HBASE-24033 Add ut for loading the corrupt recovered hfiles (#1322)
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / rsgroup / TestMigrateRSGroupInfo.java
blob4a492f88cb283d02a559588b2f410665641630e6
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.rsgroup;
20 import static org.apache.hadoop.hbase.rsgroup.RSGroupInfoManagerImpl.META_FAMILY_BYTES;
21 import static org.apache.hadoop.hbase.rsgroup.RSGroupInfoManagerImpl.META_QUALIFIER_BYTES;
22 import static org.apache.hadoop.hbase.rsgroup.RSGroupInfoManagerImpl.RSGROUP_TABLE_NAME;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertTrue;
26 import java.io.IOException;
27 import java.util.concurrent.CountDownLatch;
28 import org.apache.hadoop.conf.Configuration;
29 import org.apache.hadoop.hbase.HBaseClassTestRule;
30 import org.apache.hadoop.hbase.HConstants;
31 import org.apache.hadoop.hbase.TableDescriptors;
32 import org.apache.hadoop.hbase.TableName;
33 import org.apache.hadoop.hbase.client.Get;
34 import org.apache.hadoop.hbase.client.Put;
35 import org.apache.hadoop.hbase.client.Result;
36 import org.apache.hadoop.hbase.client.Table;
37 import org.apache.hadoop.hbase.client.TableDescriptor;
38 import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
39 import org.apache.hadoop.hbase.master.HMaster;
40 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
41 import org.apache.hadoop.hbase.protobuf.generated.RSGroupProtos;
42 import org.apache.hadoop.hbase.testclassification.MediumTests;
43 import org.apache.hadoop.hbase.testclassification.RSGroupTests;
44 import org.apache.hadoop.hbase.util.Bytes;
45 import org.apache.zookeeper.KeeperException;
46 import org.junit.AfterClass;
47 import org.junit.BeforeClass;
48 import org.junit.ClassRule;
49 import org.junit.Test;
50 import org.junit.experimental.categories.Category;
52 /**
53 * Testcase for HBASE-22819
55 @Category({ RSGroupTests.class, MediumTests.class })
56 public class TestMigrateRSGroupInfo extends TestRSGroupsBase {
58 @ClassRule
59 public static final HBaseClassTestRule CLASS_RULE =
60 HBaseClassTestRule.forClass(TestMigrateRSGroupInfo.class);
62 private static String TABLE_NAME_PREFIX = "Table_";
64 private static int NUM_TABLES = 10;
66 private static byte[] FAMILY = Bytes.toBytes("family");
68 private static RSGroupAdminClient RS_GROUP_ADMIN_CLIENT;
70 @BeforeClass
71 public static void setUp() throws Exception {
72 TEST_UTIL.getConfiguration().setClass(HConstants.MASTER_IMPL, HMasterForTest.class,
73 HMaster.class);
74 // confirm that we could enable rs group by setting the old CP.
75 TEST_UTIL.getConfiguration().setBoolean(RSGroupUtil.RS_GROUP_ENABLED, false);
76 TEST_UTIL.getConfiguration().set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY,
77 RSGroupAdminEndpoint.class.getName());
78 setUpTestBeforeClass();
79 RS_GROUP_ADMIN_CLIENT = new RSGroupAdminClient(TEST_UTIL.getConnection());
80 for (int i = 0; i < NUM_TABLES; i++) {
81 TEST_UTIL.createTable(TableName.valueOf(TABLE_NAME_PREFIX + i), FAMILY);
85 @AfterClass
86 public static void tearDown() throws Exception {
87 tearDownAfterClass();
90 private static CountDownLatch RESUME = new CountDownLatch(1);
92 public static final class HMasterForTest extends HMaster {
94 public HMasterForTest(Configuration conf) throws IOException, KeeperException {
95 super(conf);
98 @Override
99 public TableDescriptors getTableDescriptors() {
100 if (RESUME != null) {
101 for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
102 if (element.getMethodName().equals("migrate")) {
103 try {
104 RESUME.await();
105 } catch (InterruptedException e) {
107 RESUME = null;
108 break;
112 return super.getTableDescriptors();
116 @Test
117 public void testMigrate() throws IOException, InterruptedException {
118 String groupName = getNameWithoutIndex(name.getMethodName());
119 addGroup(groupName, TEST_UTIL.getMiniHBaseCluster().getRegionServerThreads().size() - 1);
120 RSGroupInfo rsGroupInfo = ADMIN.getRSGroup(groupName);
121 assertTrue(rsGroupInfo.getTables().isEmpty());
122 for (int i = 0; i < NUM_TABLES; i++) {
123 rsGroupInfo.addTable(TableName.valueOf(TABLE_NAME_PREFIX + i));
125 try (Table table = TEST_UTIL.getConnection().getTable(RSGROUP_TABLE_NAME)) {
126 RSGroupProtos.RSGroupInfo proto = ProtobufUtil.toProtoGroupInfo(rsGroupInfo);
127 Put p = new Put(Bytes.toBytes(rsGroupInfo.getName()));
128 p.addColumn(META_FAMILY_BYTES, META_QUALIFIER_BYTES, proto.toByteArray());
129 table.put(p);
131 TEST_UTIL.getMiniHBaseCluster().stopMaster(0).join();
132 RESUME = new CountDownLatch(1);
133 TEST_UTIL.getMiniHBaseCluster().startMaster();
134 TEST_UTIL.invalidateConnection();
135 RS_GROUP_ADMIN_CLIENT = new RSGroupAdminClient(TEST_UTIL.getConnection());
137 // wait until we can get the rs group info for a table
138 TEST_UTIL.waitFor(30000, () -> {
139 try {
140 RS_GROUP_ADMIN_CLIENT.getRSGroupInfoOfTable(TableName.valueOf(TABLE_NAME_PREFIX + 0));
141 return true;
142 } catch (IOException e) {
143 return false;
146 // confirm that before migrating, we could still get the correct rs group for a table.
147 for (int i = 0; i < NUM_TABLES; i++) {
148 RSGroupInfo info =
149 RS_GROUP_ADMIN_CLIENT.getRSGroupInfoOfTable(TableName.valueOf(TABLE_NAME_PREFIX + i));
150 assertEquals(rsGroupInfo.getName(), info.getName());
151 assertEquals(NUM_TABLES, info.getTables().size());
153 RESUME.countDown();
154 TEST_UTIL.waitFor(60000, () -> {
155 for (int i = 0; i < NUM_TABLES; i++) {
156 TableDescriptor td;
157 try {
158 td = TEST_UTIL.getAdmin().getDescriptor(TableName.valueOf(TABLE_NAME_PREFIX + i));
159 } catch (IOException e) {
160 return false;
162 if (!rsGroupInfo.getName().equals(td.getRegionServerGroup().orElse(null))) {
163 return false;
166 return true;
168 // make sure that we persist the result to hbase, where we delete all the tables in the rs
169 // group.
170 TEST_UTIL.waitFor(30000, () -> {
171 try (Table table = TEST_UTIL.getConnection().getTable(RSGROUP_TABLE_NAME)) {
172 Result result = table.get(new Get(Bytes.toBytes(rsGroupInfo.getName())));
173 RSGroupProtos.RSGroupInfo proto = RSGroupProtos.RSGroupInfo
174 .parseFrom(result.getValue(META_FAMILY_BYTES, META_QUALIFIER_BYTES));
175 RSGroupInfo gi = ProtobufUtil.toGroupInfo(proto);
176 return gi.getTables().isEmpty();
179 // make sure that the migrate thread has quit.
180 TEST_UTIL.waitFor(30000, () -> Thread.getAllStackTraces().keySet().stream()
181 .noneMatch(t -> t.getName().equals(RSGroupInfoManagerImpl.MIGRATE_THREAD_NAME)));
182 // make sure we could still get the correct rs group info after migration
183 for (int i = 0; i < NUM_TABLES; i++) {
184 RSGroupInfo info =
185 RS_GROUP_ADMIN_CLIENT.getRSGroupInfoOfTable(TableName.valueOf(TABLE_NAME_PREFIX + i));
186 assertEquals(rsGroupInfo.getName(), info.getName());
187 assertEquals(NUM_TABLES, info.getTables().size());