HBASE-26481 Consider rolling upgrading from old region replication framework (#3880)
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / client / TestAdmin3.java
blobc2de0fbd35554bcb0b74f6c53af1cde93b079c05
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.client;
20 import static org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory.TRACKER_IMPL;
21 import static org.junit.Assert.assertEquals;
22 import static org.junit.Assert.assertFalse;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
26 import java.io.IOException;
27 import java.util.List;
28 import java.util.regex.Pattern;
29 import org.apache.hadoop.hbase.HBaseClassTestRule;
30 import org.apache.hadoop.hbase.HConstants;
31 import org.apache.hadoop.hbase.HRegionLocation;
32 import org.apache.hadoop.hbase.InvalidFamilyOperationException;
33 import org.apache.hadoop.hbase.MetaTableAccessor;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.TableNotDisabledException;
36 import org.apache.hadoop.hbase.TableNotEnabledException;
37 import org.apache.hadoop.hbase.TableNotFoundException;
38 import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory;
39 import org.apache.hadoop.hbase.testclassification.ClientTests;
40 import org.apache.hadoop.hbase.testclassification.LargeTests;
41 import org.apache.hadoop.hbase.util.Bytes;
42 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
43 import org.junit.ClassRule;
44 import org.junit.Test;
45 import org.junit.experimental.categories.Category;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 @Category({ LargeTests.class, ClientTests.class })
50 public class TestAdmin3 extends TestAdminBase {
52 @ClassRule
53 public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestAdmin3.class);
55 private static final Logger LOG = LoggerFactory.getLogger(TestAdmin3.class);
57 @Test
58 public void testDisableAndEnableTable() throws IOException {
59 final byte[] row = Bytes.toBytes("row");
60 final byte[] qualifier = Bytes.toBytes("qualifier");
61 final byte[] value = Bytes.toBytes("value");
62 final TableName table = TableName.valueOf(name.getMethodName());
63 Table ht = TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
64 Put put = new Put(row);
65 put.addColumn(HConstants.CATALOG_FAMILY, qualifier, value);
66 ht.put(put);
67 Get get = new Get(row);
68 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
69 ht.get(get);
71 ADMIN.disableTable(ht.getName());
72 assertTrue("Table must be disabled.", TEST_UTIL.getHBaseCluster().getMaster()
73 .getTableStateManager().isTableState(ht.getName(), TableState.State.DISABLED));
74 assertEquals(TableState.State.DISABLED, getStateFromMeta(table));
76 // Test that table is disabled
77 get = new Get(row);
78 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
79 boolean ok = false;
80 try {
81 ht.get(get);
82 } catch (TableNotEnabledException e) {
83 ok = true;
85 ok = false;
86 // verify that scan encounters correct exception
87 Scan scan = new Scan();
88 try {
89 ResultScanner scanner = ht.getScanner(scan);
90 Result res = null;
91 do {
92 res = scanner.next();
93 } while (res != null);
94 } catch (TableNotEnabledException e) {
95 ok = true;
97 assertTrue(ok);
98 ADMIN.enableTable(table);
99 assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster().getMaster()
100 .getTableStateManager().isTableState(ht.getName(), TableState.State.ENABLED));
101 assertEquals(TableState.State.ENABLED, getStateFromMeta(table));
103 // Test that table is enabled
104 try {
105 ht.get(get);
106 } catch (RetriesExhaustedException e) {
107 ok = false;
109 assertTrue(ok);
110 ht.close();
113 @Test
114 public void testDisableAndEnableTables() throws IOException {
115 final byte[] row = Bytes.toBytes("row");
116 final byte[] qualifier = Bytes.toBytes("qualifier");
117 final byte[] value = Bytes.toBytes("value");
118 final TableName table1 = TableName.valueOf(name.getMethodName() + "1");
119 final TableName table2 = TableName.valueOf(name.getMethodName() + "2");
120 Table ht1 = TEST_UTIL.createTable(table1, HConstants.CATALOG_FAMILY);
121 Table ht2 = TEST_UTIL.createTable(table2, HConstants.CATALOG_FAMILY);
122 Put put = new Put(row);
123 put.addColumn(HConstants.CATALOG_FAMILY, qualifier, value);
124 ht1.put(put);
125 ht2.put(put);
126 Get get = new Get(row);
127 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
128 ht1.get(get);
129 ht2.get(get);
131 TableName[] tableNames = ADMIN.listTableNames(Pattern.compile("testDisableAndEnableTable.*"));
132 for (TableName tableName : tableNames) {
133 ADMIN.disableTable(tableName);
136 // Test that tables are disabled
137 get = new Get(row);
138 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
139 boolean ok = false;
140 try {
141 ht1.get(get);
142 ht2.get(get);
143 } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
144 ok = true;
147 assertEquals(TableState.State.DISABLED, getStateFromMeta(table1));
148 assertEquals(TableState.State.DISABLED, getStateFromMeta(table2));
150 assertTrue(ok);
151 for (TableName tableName : tableNames) {
152 ADMIN.enableTable(tableName);
155 // Test that tables are enabled
156 try {
157 ht1.get(get);
158 } catch (IOException e) {
159 ok = false;
161 try {
162 ht2.get(get);
163 } catch (IOException e) {
164 ok = false;
166 assertTrue(ok);
168 ht1.close();
169 ht2.close();
171 assertEquals(TableState.State.ENABLED, getStateFromMeta(table1));
172 assertEquals(TableState.State.ENABLED, getStateFromMeta(table2));
176 * Test retain assignment on enableTable.
178 @Test
179 public void testEnableTableRetainAssignment() throws IOException {
180 final TableName tableName = TableName.valueOf(name.getMethodName());
181 byte[][] splitKeys = { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }, new byte[] { 3, 3, 3 },
182 new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 }, new byte[] { 6, 6, 6 },
183 new byte[] { 7, 7, 7 }, new byte[] { 8, 8, 8 }, new byte[] { 9, 9, 9 } };
184 int expectedRegions = splitKeys.length + 1;
185 TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
186 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
187 ADMIN.createTable(desc, splitKeys);
189 try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
190 List<HRegionLocation> regions = l.getAllRegionLocations();
192 assertEquals(
193 "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size(),
194 expectedRegions, regions.size());
195 // Disable table.
196 ADMIN.disableTable(tableName);
197 // Enable table, use retain assignment to assign regions.
198 ADMIN.enableTable(tableName);
199 List<HRegionLocation> regions2 = l.getAllRegionLocations();
201 // Check the assignment.
202 assertEquals(regions.size(), regions2.size());
203 assertTrue(regions2.containsAll(regions));
207 @Test
208 public void testEnableDisableAddColumnDeleteColumn() throws Exception {
209 final TableName tableName = TableName.valueOf(name.getMethodName());
210 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
211 while (!ADMIN.isTableEnabled(TableName.valueOf(name.getMethodName()))) {
212 Thread.sleep(10);
214 ADMIN.disableTable(tableName);
215 try {
216 TEST_UTIL.getConnection().getTable(tableName);
217 } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
218 // expected
221 ADMIN.addColumnFamily(tableName, ColumnFamilyDescriptorBuilder.of("col2"));
222 ADMIN.enableTable(tableName);
223 try {
224 ADMIN.deleteColumnFamily(tableName, Bytes.toBytes("col2"));
225 } catch (TableNotDisabledException e) {
226 LOG.info(e.toString(), e);
228 ADMIN.disableTable(tableName);
229 ADMIN.deleteTable(tableName);
232 @Test
233 public void testGetTableDescriptor() throws IOException {
234 TableDescriptor htd = TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))
235 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1"))
236 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam2"))
237 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam3")).build();
238 ADMIN.createTable(htd);
239 Table table = TEST_UTIL.getConnection().getTable(htd.getTableName());
240 TableDescriptor confirmedHtd = table.getDescriptor();
241 //HBASE-26246 introduced persist of store file tracker into table descriptor
242 htd = TableDescriptorBuilder.newBuilder(htd).setValue(TRACKER_IMPL,
243 StoreFileTrackerFactory.getStoreFileTrackerName(TEST_UTIL.getConfiguration())).
244 build();
245 assertEquals(0, TableDescriptor.COMPARATOR.compare(htd, confirmedHtd));
246 MetaTableAccessor.fullScanMetaAndPrint(TEST_UTIL.getConnection());
247 table.close();
251 * Verify schema change for read only table
253 @Test
254 public void testReadOnlyTableModify() throws IOException, InterruptedException {
255 final TableName tableName = TableName.valueOf(name.getMethodName());
256 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
258 // Make table read only
259 TableDescriptor htd =
260 TableDescriptorBuilder.newBuilder(ADMIN.getDescriptor(tableName)).setReadOnly(true).build();
261 ADMIN.modifyTable(htd);
263 // try to modify the read only table now
264 htd = TableDescriptorBuilder.newBuilder(ADMIN.getDescriptor(tableName))
265 .setCompactionEnabled(false).build();
266 ADMIN.modifyTable(htd);
267 // Delete the table
268 ADMIN.disableTable(tableName);
269 ADMIN.deleteTable(tableName);
270 assertFalse(ADMIN.tableExists(tableName));
273 @Test
274 public void testDeleteLastColumnFamily() throws Exception {
275 final TableName tableName = TableName.valueOf(name.getMethodName());
276 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
277 while (!ADMIN.isTableEnabled(TableName.valueOf(name.getMethodName()))) {
278 Thread.sleep(10);
281 // test for enabled table
282 try {
283 ADMIN.deleteColumnFamily(tableName, HConstants.CATALOG_FAMILY);
284 fail("Should have failed to delete the only column family of a table");
285 } catch (InvalidFamilyOperationException ex) {
286 // expected
289 // test for disabled table
290 ADMIN.disableTable(tableName);
292 try {
293 ADMIN.deleteColumnFamily(tableName, HConstants.CATALOG_FAMILY);
294 fail("Should have failed to delete the only column family of a table");
295 } catch (InvalidFamilyOperationException ex) {
296 // expected
299 ADMIN.deleteTable(tableName);
302 @Test
303 public void testDeleteEditUnknownColumnFamilyAndOrTable() throws IOException {
304 // Test we get exception if we try to
305 final TableName nonexistentTable = TableName.valueOf("nonexistent");
306 final byte[] nonexistentColumn = Bytes.toBytes("nonexistent");
307 ColumnFamilyDescriptor nonexistentHcd = ColumnFamilyDescriptorBuilder.of(nonexistentColumn);
308 Exception exception = null;
309 try {
310 ADMIN.addColumnFamily(nonexistentTable, nonexistentHcd);
311 } catch (IOException e) {
312 exception = e;
314 assertTrue(exception instanceof TableNotFoundException);
316 exception = null;
317 try {
318 ADMIN.deleteTable(nonexistentTable);
319 } catch (IOException e) {
320 exception = e;
322 assertTrue(exception instanceof TableNotFoundException);
324 exception = null;
325 try {
326 ADMIN.deleteColumnFamily(nonexistentTable, nonexistentColumn);
327 } catch (IOException e) {
328 exception = e;
330 assertTrue(exception instanceof TableNotFoundException);
332 exception = null;
333 try {
334 ADMIN.disableTable(nonexistentTable);
335 } catch (IOException e) {
336 exception = e;
338 assertTrue(exception instanceof TableNotFoundException);
340 exception = null;
341 try {
342 ADMIN.enableTable(nonexistentTable);
343 } catch (IOException e) {
344 exception = e;
346 assertTrue(exception instanceof TableNotFoundException);
348 exception = null;
349 try {
350 ADMIN.modifyColumnFamily(nonexistentTable, nonexistentHcd);
351 } catch (IOException e) {
352 exception = e;
354 assertTrue(exception instanceof TableNotFoundException);
356 exception = null;
357 try {
358 TableDescriptor htd = TableDescriptorBuilder.newBuilder(nonexistentTable)
359 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
360 ADMIN.modifyTable(htd);
361 } catch (IOException e) {
362 exception = e;
364 assertTrue(exception instanceof TableNotFoundException);
366 // Now make it so at least the table exists and then do tests against a
367 // nonexistent column family -- see if we get right exceptions.
368 final TableName tableName =
369 TableName.valueOf(name.getMethodName() + EnvironmentEdgeManager.currentTime());
370 TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
371 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build();
372 ADMIN.createTable(htd);
373 try {
374 exception = null;
375 try {
376 ADMIN.deleteColumnFamily(htd.getTableName(), nonexistentHcd.getName());
377 } catch (IOException e) {
378 exception = e;
380 assertTrue("found=" + exception.getClass().getName(),
381 exception instanceof InvalidFamilyOperationException);
383 exception = null;
384 try {
385 ADMIN.modifyColumnFamily(htd.getTableName(), nonexistentHcd);
386 } catch (IOException e) {
387 exception = e;
389 assertTrue("found=" + exception.getClass().getName(),
390 exception instanceof InvalidFamilyOperationException);
391 } finally {
392 ADMIN.disableTable(tableName);
393 ADMIN.deleteTable(tableName);