HBASE-24033 Add ut for loading the corrupt recovered hfiles (#1322)
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / client / TestAdmin3.java
blobc648db94aa39185767525d4fe1a8306c1a91b4f7
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.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
25 import java.io.IOException;
26 import java.util.List;
27 import java.util.regex.Pattern;
28 import org.apache.hadoop.hbase.HBaseClassTestRule;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.HRegionLocation;
31 import org.apache.hadoop.hbase.InvalidFamilyOperationException;
32 import org.apache.hadoop.hbase.MetaTableAccessor;
33 import org.apache.hadoop.hbase.TableName;
34 import org.apache.hadoop.hbase.TableNotDisabledException;
35 import org.apache.hadoop.hbase.TableNotEnabledException;
36 import org.apache.hadoop.hbase.TableNotFoundException;
37 import org.apache.hadoop.hbase.testclassification.ClientTests;
38 import org.apache.hadoop.hbase.testclassification.LargeTests;
39 import org.apache.hadoop.hbase.util.Bytes;
40 import org.junit.ClassRule;
41 import org.junit.Test;
42 import org.junit.experimental.categories.Category;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 @Category({ LargeTests.class, ClientTests.class })
47 public class TestAdmin3 extends TestAdminBase {
49 @ClassRule
50 public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestAdmin3.class);
52 private static final Logger LOG = LoggerFactory.getLogger(TestAdmin3.class);
54 @Test
55 public void testDisableAndEnableTable() throws IOException {
56 final byte[] row = Bytes.toBytes("row");
57 final byte[] qualifier = Bytes.toBytes("qualifier");
58 final byte[] value = Bytes.toBytes("value");
59 final TableName table = TableName.valueOf(name.getMethodName());
60 Table ht = TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
61 Put put = new Put(row);
62 put.addColumn(HConstants.CATALOG_FAMILY, qualifier, value);
63 ht.put(put);
64 Get get = new Get(row);
65 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
66 ht.get(get);
68 ADMIN.disableTable(ht.getName());
69 assertTrue("Table must be disabled.", TEST_UTIL.getHBaseCluster().getMaster()
70 .getTableStateManager().isTableState(ht.getName(), TableState.State.DISABLED));
71 assertEquals(TableState.State.DISABLED, getStateFromMeta(table));
73 // Test that table is disabled
74 get = new Get(row);
75 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
76 boolean ok = false;
77 try {
78 ht.get(get);
79 } catch (TableNotEnabledException e) {
80 ok = true;
82 ok = false;
83 // verify that scan encounters correct exception
84 Scan scan = new Scan();
85 try {
86 ResultScanner scanner = ht.getScanner(scan);
87 Result res = null;
88 do {
89 res = scanner.next();
90 } while (res != null);
91 } catch (TableNotEnabledException e) {
92 ok = true;
94 assertTrue(ok);
95 ADMIN.enableTable(table);
96 assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster().getMaster()
97 .getTableStateManager().isTableState(ht.getName(), TableState.State.ENABLED));
98 assertEquals(TableState.State.ENABLED, getStateFromMeta(table));
100 // Test that table is enabled
101 try {
102 ht.get(get);
103 } catch (RetriesExhaustedException e) {
104 ok = false;
106 assertTrue(ok);
107 ht.close();
110 @Test
111 public void testDisableAndEnableTables() throws IOException {
112 final byte[] row = Bytes.toBytes("row");
113 final byte[] qualifier = Bytes.toBytes("qualifier");
114 final byte[] value = Bytes.toBytes("value");
115 final TableName table1 = TableName.valueOf(name.getMethodName() + "1");
116 final TableName table2 = TableName.valueOf(name.getMethodName() + "2");
117 Table ht1 = TEST_UTIL.createTable(table1, HConstants.CATALOG_FAMILY);
118 Table ht2 = TEST_UTIL.createTable(table2, HConstants.CATALOG_FAMILY);
119 Put put = new Put(row);
120 put.addColumn(HConstants.CATALOG_FAMILY, qualifier, value);
121 ht1.put(put);
122 ht2.put(put);
123 Get get = new Get(row);
124 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
125 ht1.get(get);
126 ht2.get(get);
128 TableName[] tableNames = ADMIN.listTableNames(Pattern.compile("testDisableAndEnableTable.*"));
129 for (TableName tableName : tableNames) {
130 ADMIN.disableTable(tableName);
133 // Test that tables are disabled
134 get = new Get(row);
135 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
136 boolean ok = false;
137 try {
138 ht1.get(get);
139 ht2.get(get);
140 } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
141 ok = true;
144 assertEquals(TableState.State.DISABLED, getStateFromMeta(table1));
145 assertEquals(TableState.State.DISABLED, getStateFromMeta(table2));
147 assertTrue(ok);
148 for (TableName tableName : tableNames) {
149 ADMIN.enableTable(tableName);
152 // Test that tables are enabled
153 try {
154 ht1.get(get);
155 } catch (IOException e) {
156 ok = false;
158 try {
159 ht2.get(get);
160 } catch (IOException e) {
161 ok = false;
163 assertTrue(ok);
165 ht1.close();
166 ht2.close();
168 assertEquals(TableState.State.ENABLED, getStateFromMeta(table1));
169 assertEquals(TableState.State.ENABLED, getStateFromMeta(table2));
173 * Test retain assignment on enableTable.
175 @Test
176 public void testEnableTableRetainAssignment() throws IOException {
177 final TableName tableName = TableName.valueOf(name.getMethodName());
178 byte[][] splitKeys = { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }, new byte[] { 3, 3, 3 },
179 new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 }, new byte[] { 6, 6, 6 },
180 new byte[] { 7, 7, 7 }, new byte[] { 8, 8, 8 }, new byte[] { 9, 9, 9 } };
181 int expectedRegions = splitKeys.length + 1;
182 TableDescriptor desc = TableDescriptorBuilder.newBuilder(tableName)
183 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
184 ADMIN.createTable(desc, splitKeys);
186 try (RegionLocator l = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
187 List<HRegionLocation> regions = l.getAllRegionLocations();
189 assertEquals(
190 "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size(),
191 expectedRegions, regions.size());
192 // Disable table.
193 ADMIN.disableTable(tableName);
194 // Enable table, use retain assignment to assign regions.
195 ADMIN.enableTable(tableName);
196 List<HRegionLocation> regions2 = l.getAllRegionLocations();
198 // Check the assignment.
199 assertEquals(regions.size(), regions2.size());
200 assertTrue(regions2.containsAll(regions));
204 @Test
205 public void testEnableDisableAddColumnDeleteColumn() throws Exception {
206 final TableName tableName = TableName.valueOf(name.getMethodName());
207 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
208 while (!ADMIN.isTableEnabled(TableName.valueOf(name.getMethodName()))) {
209 Thread.sleep(10);
211 ADMIN.disableTable(tableName);
212 try {
213 TEST_UTIL.getConnection().getTable(tableName);
214 } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
215 // expected
218 ADMIN.addColumnFamily(tableName, ColumnFamilyDescriptorBuilder.of("col2"));
219 ADMIN.enableTable(tableName);
220 try {
221 ADMIN.deleteColumnFamily(tableName, Bytes.toBytes("col2"));
222 } catch (TableNotDisabledException e) {
223 LOG.info(e.toString(), e);
225 ADMIN.disableTable(tableName);
226 ADMIN.deleteTable(tableName);
229 @Test
230 public void testGetTableDescriptor() throws IOException {
231 TableDescriptor htd = TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName()))
232 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam1"))
233 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam2"))
234 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("fam3")).build();
235 ADMIN.createTable(htd);
236 Table table = TEST_UTIL.getConnection().getTable(htd.getTableName());
237 TableDescriptor confirmedHtd = table.getDescriptor();
238 assertEquals(0, TableDescriptor.COMPARATOR.compare(htd, confirmedHtd));
239 MetaTableAccessor.fullScanMetaAndPrint(TEST_UTIL.getConnection());
240 table.close();
244 * Verify schema change for read only table
246 @Test
247 public void testReadOnlyTableModify() throws IOException, InterruptedException {
248 final TableName tableName = TableName.valueOf(name.getMethodName());
249 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
251 // Make table read only
252 TableDescriptor htd =
253 TableDescriptorBuilder.newBuilder(ADMIN.getDescriptor(tableName)).setReadOnly(true).build();
254 ADMIN.modifyTable(htd);
256 // try to modify the read only table now
257 htd = TableDescriptorBuilder.newBuilder(ADMIN.getDescriptor(tableName))
258 .setCompactionEnabled(false).build();
259 ADMIN.modifyTable(htd);
260 // Delete the table
261 ADMIN.disableTable(tableName);
262 ADMIN.deleteTable(tableName);
263 assertFalse(ADMIN.tableExists(tableName));
266 @Test(expected = TableNotDisabledException.class)
267 public void testModifyRegionReplicasEnabledTable() throws Exception {
268 final TableName tableName = TableName.valueOf(name.getMethodName());
269 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
271 // Modify region replication count
272 TableDescriptor htd = TableDescriptorBuilder.newBuilder(ADMIN.getDescriptor(tableName))
273 .setRegionReplication(3).build();
274 try {
275 // try to modify the region replication count without disabling the table
276 ADMIN.modifyTable(htd);
277 fail("Expected an exception");
278 } finally {
279 // Delete the table
280 ADMIN.disableTable(tableName);
281 ADMIN.deleteTable(tableName);
282 assertFalse(ADMIN.tableExists(tableName));
286 @Test
287 public void testDeleteLastColumnFamily() throws Exception {
288 final TableName tableName = TableName.valueOf(name.getMethodName());
289 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
290 while (!ADMIN.isTableEnabled(TableName.valueOf(name.getMethodName()))) {
291 Thread.sleep(10);
294 // test for enabled table
295 try {
296 ADMIN.deleteColumnFamily(tableName, HConstants.CATALOG_FAMILY);
297 fail("Should have failed to delete the only column family of a table");
298 } catch (InvalidFamilyOperationException ex) {
299 // expected
302 // test for disabled table
303 ADMIN.disableTable(tableName);
305 try {
306 ADMIN.deleteColumnFamily(tableName, HConstants.CATALOG_FAMILY);
307 fail("Should have failed to delete the only column family of a table");
308 } catch (InvalidFamilyOperationException ex) {
309 // expected
312 ADMIN.deleteTable(tableName);
315 @Test
316 public void testDeleteEditUnknownColumnFamilyAndOrTable() throws IOException {
317 // Test we get exception if we try to
318 final TableName nonexistentTable = TableName.valueOf("nonexistent");
319 final byte[] nonexistentColumn = Bytes.toBytes("nonexistent");
320 ColumnFamilyDescriptor nonexistentHcd = ColumnFamilyDescriptorBuilder.of(nonexistentColumn);
321 Exception exception = null;
322 try {
323 ADMIN.addColumnFamily(nonexistentTable, nonexistentHcd);
324 } catch (IOException e) {
325 exception = e;
327 assertTrue(exception instanceof TableNotFoundException);
329 exception = null;
330 try {
331 ADMIN.deleteTable(nonexistentTable);
332 } catch (IOException e) {
333 exception = e;
335 assertTrue(exception instanceof TableNotFoundException);
337 exception = null;
338 try {
339 ADMIN.deleteColumnFamily(nonexistentTable, nonexistentColumn);
340 } catch (IOException e) {
341 exception = e;
343 assertTrue(exception instanceof TableNotFoundException);
345 exception = null;
346 try {
347 ADMIN.disableTable(nonexistentTable);
348 } catch (IOException e) {
349 exception = e;
351 assertTrue(exception instanceof TableNotFoundException);
353 exception = null;
354 try {
355 ADMIN.enableTable(nonexistentTable);
356 } catch (IOException e) {
357 exception = e;
359 assertTrue(exception instanceof TableNotFoundException);
361 exception = null;
362 try {
363 ADMIN.modifyColumnFamily(nonexistentTable, nonexistentHcd);
364 } catch (IOException e) {
365 exception = e;
367 assertTrue(exception instanceof TableNotFoundException);
369 exception = null;
370 try {
371 TableDescriptor htd = TableDescriptorBuilder.newBuilder(nonexistentTable)
372 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(HConstants.CATALOG_FAMILY)).build();
373 ADMIN.modifyTable(htd);
374 } catch (IOException e) {
375 exception = e;
377 assertTrue(exception instanceof TableNotFoundException);
379 // Now make it so at least the table exists and then do tests against a
380 // nonexistent column family -- see if we get right exceptions.
381 final TableName tableName =
382 TableName.valueOf(name.getMethodName() + System.currentTimeMillis());
383 TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
384 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build();
385 ADMIN.createTable(htd);
386 try {
387 exception = null;
388 try {
389 ADMIN.deleteColumnFamily(htd.getTableName(), nonexistentHcd.getName());
390 } catch (IOException e) {
391 exception = e;
393 assertTrue("found=" + exception.getClass().getName(),
394 exception instanceof InvalidFamilyOperationException);
396 exception = null;
397 try {
398 ADMIN.modifyColumnFamily(htd.getTableName(), nonexistentHcd);
399 } catch (IOException e) {
400 exception = e;
402 assertTrue("found=" + exception.getClass().getName(),
403 exception instanceof InvalidFamilyOperationException);
404 } finally {
405 ADMIN.disableTable(tableName);
406 ADMIN.deleteTable(tableName);