1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.client;
20
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;
25
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.concurrent.atomic.AtomicBoolean;
34 import java.util.concurrent.atomic.AtomicInteger;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.apache.hadoop.hbase.HBaseTestingUtility;
39 import org.apache.hadoop.hbase.HColumnDescriptor;
40 import org.apache.hadoop.hbase.HConstants;
41 import org.apache.hadoop.hbase.HRegionInfo;
42 import org.apache.hadoop.hbase.HTableDescriptor;
43 import org.apache.hadoop.hbase.InvalidFamilyOperationException;
44 import org.apache.hadoop.hbase.testclassification.LargeTests;
45 import org.apache.hadoop.hbase.MasterNotRunningException;
46 import org.apache.hadoop.hbase.MetaTableAccessor;
47 import org.apache.hadoop.hbase.ServerName;
48 import org.apache.hadoop.hbase.TableName;
49 import org.apache.hadoop.hbase.TableNotDisabledException;
50 import org.apache.hadoop.hbase.TableNotEnabledException;
51 import org.apache.hadoop.hbase.TableNotFoundException;
52 import org.apache.hadoop.hbase.executor.EventHandler;
53 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
54 import org.apache.hadoop.hbase.util.Bytes;
55 import org.apache.hadoop.hbase.zookeeper.ZKTableStateClientSideReader;
56 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
57 import org.apache.hadoop.hbase.exceptions.MergeRegionException;
58 import org.apache.hadoop.hbase.master.HMaster;
59 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
60 import org.apache.hadoop.hbase.protobuf.RequestConverter;
61 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.AdminService;
62 import org.apache.hadoop.hbase.protobuf.generated.MasterProtos.DispatchMergingRegionsRequest;
63 import org.apache.hadoop.hbase.regionserver.HRegion;
64 import org.apache.hadoop.hbase.util.Pair;
65 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
66 import org.junit.After;
67 import org.junit.AfterClass;
68 import org.junit.Before;
69 import org.junit.BeforeClass;
70 import org.junit.Test;
71 import org.junit.experimental.categories.Category;
72
73 import com.google.protobuf.ServiceException;
74
75
76
77
78
79
80 @Category(LargeTests.class)
81 public class TestAdmin1 {
82 final Log LOG = LogFactory.getLog(getClass());
83 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
84 private Admin admin;
85
86 @BeforeClass
87 public static void setUpBeforeClass() throws Exception {
88 TEST_UTIL.getConfiguration().setBoolean("hbase.online.schema.update.enable", true);
89 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
90 TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
91 TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 6);
92 TEST_UTIL.getConfiguration().setBoolean(
93 "hbase.master.enabletable.roundrobin", true);
94 TEST_UTIL.startMiniCluster(3);
95 }
96
97 @AfterClass
98 public static void tearDownAfterClass() throws Exception {
99 TEST_UTIL.shutdownMiniCluster();
100 }
101
102 @Before
103 public void setUp() throws Exception {
104 this.admin = TEST_UTIL.getHBaseAdmin();
105 }
106
107 @After
108 public void tearDown() throws Exception {
109 for (HTableDescriptor htd : this.admin.listTables()) {
110 TEST_UTIL.deleteTable(htd.getName());
111 }
112 }
113
114 @Test (timeout=300000)
115 public void testSplitFlushCompactUnknownTable() throws InterruptedException {
116 final TableName unknowntable = TableName.valueOf("fubar");
117 Exception exception = null;
118 try {
119 this.admin.compact(unknowntable);
120 } catch (IOException e) {
121 exception = e;
122 }
123 assertTrue(exception instanceof TableNotFoundException);
124
125 exception = null;
126 try {
127 this.admin.flush(unknowntable);
128 } catch (IOException e) {
129 exception = e;
130 }
131 assertTrue(exception instanceof TableNotFoundException);
132
133 exception = null;
134 try {
135 this.admin.split(unknowntable);
136 } catch (IOException e) {
137 exception = e;
138 }
139 assertTrue(exception instanceof TableNotFoundException);
140 }
141
142 @Test (timeout=300000)
143 public void testDeleteEditUnknownColumnFamilyAndOrTable() throws IOException {
144
145 final TableName nonexistentTable = TableName.valueOf("nonexistent");
146 final byte[] nonexistentColumn = Bytes.toBytes("nonexistent");
147 HColumnDescriptor nonexistentHcd = new HColumnDescriptor(nonexistentColumn);
148 Exception exception = null;
149 try {
150 this.admin.addColumn(nonexistentTable, nonexistentHcd);
151 } catch (IOException e) {
152 exception = e;
153 }
154 assertTrue(exception instanceof TableNotFoundException);
155
156 exception = null;
157 try {
158 this.admin.deleteTable(nonexistentTable);
159 } catch (IOException e) {
160 exception = e;
161 }
162 assertTrue(exception instanceof TableNotFoundException);
163
164 exception = null;
165 try {
166 this.admin.deleteColumn(nonexistentTable, nonexistentColumn);
167 } catch (IOException e) {
168 exception = e;
169 }
170 assertTrue(exception instanceof TableNotFoundException);
171
172 exception = null;
173 try {
174 this.admin.disableTable(nonexistentTable);
175 } catch (IOException e) {
176 exception = e;
177 }
178 assertTrue(exception instanceof TableNotFoundException);
179
180 exception = null;
181 try {
182 this.admin.enableTable(nonexistentTable);
183 } catch (IOException e) {
184 exception = e;
185 }
186 assertTrue(exception instanceof TableNotFoundException);
187
188 exception = null;
189 try {
190 this.admin.modifyColumn(nonexistentTable, nonexistentHcd);
191 } catch (IOException e) {
192 exception = e;
193 }
194 assertTrue(exception instanceof TableNotFoundException);
195
196 exception = null;
197 try {
198 HTableDescriptor htd = new HTableDescriptor(nonexistentTable);
199 htd.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
200 this.admin.modifyTable(htd.getTableName(), htd);
201 } catch (IOException e) {
202 exception = e;
203 }
204 assertTrue(exception instanceof TableNotFoundException);
205
206
207
208 final TableName tableName =
209 TableName.valueOf("testDeleteEditUnknownColumnFamilyAndOrTable" + System.currentTimeMillis());
210 HTableDescriptor htd = new HTableDescriptor(tableName);
211 htd.addFamily(new HColumnDescriptor("cf"));
212 this.admin.createTable(htd);
213 try {
214 exception = null;
215 try {
216 this.admin.deleteColumn(htd.getTableName(), nonexistentHcd.getName());
217 } catch (IOException e) {
218 exception = e;
219 }
220 assertTrue("found=" + exception.getClass().getName(),
221 exception instanceof InvalidFamilyOperationException);
222
223 exception = null;
224 try {
225 this.admin.modifyColumn(htd.getTableName(), nonexistentHcd);
226 } catch (IOException e) {
227 exception = e;
228 }
229 assertTrue("found=" + exception.getClass().getName(),
230 exception instanceof InvalidFamilyOperationException);
231 } finally {
232 this.admin.disableTable(tableName);
233 this.admin.deleteTable(tableName);
234 }
235 }
236
237 @Test (timeout=300000)
238 public void testDisableAndEnableTable() throws IOException {
239 final byte [] row = Bytes.toBytes("row");
240 final byte [] qualifier = Bytes.toBytes("qualifier");
241 final byte [] value = Bytes.toBytes("value");
242 final TableName table = TableName.valueOf("testDisableAndEnableTable");
243 Table ht = TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
244 Put put = new Put(row);
245 put.add(HConstants.CATALOG_FAMILY, qualifier, value);
246 ht.put(put);
247 Get get = new Get(row);
248 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
249 ht.get(get);
250
251 this.admin.disableTable(ht.getName());
252 assertTrue("Table must be disabled.", TEST_UTIL.getHBaseCluster()
253 .getMaster().getAssignmentManager().getTableStateManager().isTableState(
254 ht.getName(), ZooKeeperProtos.Table.State.DISABLED));
255
256
257 get = new Get(row);
258 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
259 boolean ok = false;
260 try {
261 ht.get(get);
262 } catch (TableNotEnabledException e) {
263 ok = true;
264 }
265 ok = false;
266
267 Scan scan = new Scan();
268 try {
269 ResultScanner scanner = ht.getScanner(scan);
270 Result res = null;
271 do {
272 res = scanner.next();
273 } while (res != null);
274 } catch (TableNotEnabledException e) {
275 ok = true;
276 }
277 assertTrue(ok);
278 this.admin.enableTable(table);
279 assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster()
280 .getMaster().getAssignmentManager().getTableStateManager().isTableState(
281 ht.getName(), ZooKeeperProtos.Table.State.ENABLED));
282
283
284 try {
285 ht.get(get);
286 } catch (RetriesExhaustedException e) {
287 ok = false;
288 }
289 assertTrue(ok);
290 ht.close();
291 }
292
293 @Test (timeout=300000)
294 public void testDisableAndEnableTables() throws IOException {
295 final byte [] row = Bytes.toBytes("row");
296 final byte [] qualifier = Bytes.toBytes("qualifier");
297 final byte [] value = Bytes.toBytes("value");
298 final TableName table1 = TableName.valueOf("testDisableAndEnableTable1");
299 final TableName table2 = TableName.valueOf("testDisableAndEnableTable2");
300 Table ht1 = TEST_UTIL.createTable(table1, HConstants.CATALOG_FAMILY);
301 Table ht2 = TEST_UTIL.createTable(table2, HConstants.CATALOG_FAMILY);
302 Put put = new Put(row);
303 put.add(HConstants.CATALOG_FAMILY, qualifier, value);
304 ht1.put(put);
305 ht2.put(put);
306 Get get = new Get(row);
307 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
308 ht1.get(get);
309 ht2.get(get);
310
311 this.admin.disableTables("testDisableAndEnableTable.*");
312
313
314 get = new Get(row);
315 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
316 boolean ok = false;
317 try {
318 ht1.get(get);
319 ht2.get(get);
320 } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
321 ok = true;
322 }
323
324 assertTrue(ok);
325 this.admin.enableTables("testDisableAndEnableTable.*");
326
327
328 try {
329 ht1.get(get);
330 } catch (IOException e) {
331 ok = false;
332 }
333 try {
334 ht2.get(get);
335 } catch (IOException e) {
336 ok = false;
337 }
338 assertTrue(ok);
339
340 ht1.close();
341 ht2.close();
342 }
343
344 @Test (timeout=300000)
345 public void testCreateTable() throws IOException {
346 HTableDescriptor [] tables = admin.listTables();
347 int numTables = tables.length;
348 TEST_UTIL.createTable(TableName.valueOf("testCreateTable"), HConstants.CATALOG_FAMILY).close();
349 tables = this.admin.listTables();
350 assertEquals(numTables + 1, tables.length);
351 assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster()
352 .getMaster().getAssignmentManager().getTableStateManager().isTableState(
353 TableName.valueOf("testCreateTable"), ZooKeeperProtos.Table.State.ENABLED));
354 }
355
356 @Test (timeout=300000)
357 public void testTruncateTable() throws IOException {
358 testTruncateTable(TableName.valueOf("testTruncateTable"), false);
359 }
360
361 @Test (timeout=300000)
362 public void testTruncateTablePreservingSplits() throws IOException {
363 testTruncateTable(TableName.valueOf("testTruncateTablePreservingSplits"), true);
364 }
365
366 private void testTruncateTable(final TableName tableName, boolean preserveSplits)
367 throws IOException {
368 byte[][] splitKeys = new byte[2][];
369 splitKeys[0] = Bytes.toBytes(4);
370 splitKeys[1] = Bytes.toBytes(8);
371
372
373 HTable table = TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY, splitKeys);
374 try {
375 TEST_UTIL.loadNumericRows(table, HConstants.CATALOG_FAMILY, 0, 10);
376 assertEquals(10, TEST_UTIL.countRows(table));
377 } finally {
378 table.close();
379 }
380 assertEquals(3, TEST_UTIL.getHBaseCluster().getRegions(tableName).size());
381
382
383 this.admin.disableTable(tableName);
384 this.admin.truncateTable(tableName, preserveSplits);
385 table = new HTable(TEST_UTIL.getConfiguration(), tableName);
386 try {
387 assertEquals(0, TEST_UTIL.countRows(table));
388 } finally {
389 table.close();
390 }
391 if (preserveSplits) {
392 assertEquals(3, TEST_UTIL.getHBaseCluster().getRegions(tableName).size());
393 } else {
394 assertEquals(1, TEST_UTIL.getHBaseCluster().getRegions(tableName).size());
395 }
396 }
397
398 @Test (timeout=300000)
399 public void testGetTableDescriptor() throws IOException {
400 HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
401 HColumnDescriptor fam2 = new HColumnDescriptor("fam2");
402 HColumnDescriptor fam3 = new HColumnDescriptor("fam3");
403 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("myTestTable"));
404 htd.addFamily(fam1);
405 htd.addFamily(fam2);
406 htd.addFamily(fam3);
407 this.admin.createTable(htd);
408 Table table = new HTable(TEST_UTIL.getConfiguration(), htd.getTableName());
409 HTableDescriptor confirmedHtd = table.getTableDescriptor();
410 assertEquals(htd.compareTo(confirmedHtd), 0);
411 table.close();
412 }
413
414 @Test (timeout=300000)
415 public void testCompactionTimestamps() throws Exception {
416 HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
417 TableName tableName = TableName.valueOf("testCompactionTimestampsTable");
418 HTableDescriptor htd = new HTableDescriptor(tableName);
419 htd.addFamily(fam1);
420 this.admin.createTable(htd);
421 HTable table = (HTable)TEST_UTIL.getConnection().getTable(htd.getTableName());
422 long ts = this.admin.getLastMajorCompactionTimestamp(tableName);
423 assertEquals(0, ts);
424 Put p = new Put(Bytes.toBytes("row1"));
425 p.add(Bytes.toBytes("fam1"), Bytes.toBytes("fam1"), Bytes.toBytes("fam1"));
426 table.put(p);
427 ts = this.admin.getLastMajorCompactionTimestamp(tableName);
428
429 assertEquals(0, ts);
430
431 this.admin.flush(tableName);
432 ts = this.admin.getLastMajorCompactionTimestamp(tableName);
433
434 assertEquals(0, ts);
435
436 byte[] regionName =
437 table.getRegionLocator().getAllRegionLocations().get(0).getRegionInfo().getRegionName();
438 long ts1 = this.admin.getLastMajorCompactionTimestampForRegion(regionName);
439 assertEquals(ts, ts1);
440 p = new Put(Bytes.toBytes("row2"));
441 p.add(Bytes.toBytes("fam1"), Bytes.toBytes("fam1"), Bytes.toBytes("fam1"));
442 table.put(p);
443 this.admin.flush(tableName);
444 ts = this.admin.getLastMajorCompactionTimestamp(tableName);
445
446 assertEquals(ts1, ts);
447
448 TEST_UTIL.compact(tableName, true);
449 table.put(p);
450
451 this.admin.flush(tableName);
452 ts = this.admin.getLastMajorCompactionTimestamp(tableName);
453
454 assertTrue(ts > ts1);
455
456
457 ts1 = this.admin.getLastMajorCompactionTimestampForRegion(regionName);
458 assertEquals(ts, ts1);
459 table.put(p);
460 this.admin.flush(tableName);
461 ts = this.admin.getLastMajorCompactionTimestamp(tableName);
462 assertEquals(ts, ts1);
463 table.close();
464 }
465
466 @Test (timeout=300000)
467 public void testHColumnValidName() {
468 boolean exceptionThrown;
469 try {
470 new HColumnDescriptor("\\test\\abc");
471 } catch(IllegalArgumentException iae) {
472 exceptionThrown = true;
473 assertTrue(exceptionThrown);
474 }
475 }
476
477
478
479
480
481
482 @Test (timeout=300000)
483 public void testOnlineChangeTableSchema() throws IOException, InterruptedException {
484 final TableName tableName =
485 TableName.valueOf("changeTableSchemaOnline");
486 TEST_UTIL.getMiniHBaseCluster().getMaster().getConfiguration().setBoolean(
487 "hbase.online.schema.update.enable", true);
488 HTableDescriptor [] tables = admin.listTables();
489 int numTables = tables.length;
490 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
491 tables = this.admin.listTables();
492 assertEquals(numTables + 1, tables.length);
493
494
495 HTableDescriptor htd = this.admin.getTableDescriptor(tableName);
496
497 HTableDescriptor copy = new HTableDescriptor(htd);
498 assertTrue(htd.equals(copy));
499
500 long newFlushSize = htd.getMemStoreFlushSize() / 2;
501 if (newFlushSize <=0) {
502 newFlushSize = HTableDescriptor.DEFAULT_MEMSTORE_FLUSH_SIZE / 2;
503 }
504 copy.setMemStoreFlushSize(newFlushSize);
505 final String key = "anyoldkey";
506 assertTrue(htd.getValue(key) == null);
507 copy.setValue(key, key);
508 boolean expectedException = false;
509 try {
510 admin.modifyTable(tableName, copy);
511 } catch (TableNotDisabledException re) {
512 expectedException = true;
513 }
514 assertFalse(expectedException);
515 HTableDescriptor modifiedHtd = this.admin.getTableDescriptor(tableName);
516 assertFalse(htd.equals(modifiedHtd));
517 assertTrue(copy.equals(modifiedHtd));
518 assertEquals(newFlushSize, modifiedHtd.getMemStoreFlushSize());
519 assertEquals(key, modifiedHtd.getValue(key));
520
521
522 int countOfFamilies = modifiedHtd.getFamilies().size();
523 assertTrue(countOfFamilies > 0);
524 HColumnDescriptor hcd = modifiedHtd.getFamilies().iterator().next();
525 int maxversions = hcd.getMaxVersions();
526 final int newMaxVersions = maxversions + 1;
527 hcd.setMaxVersions(newMaxVersions);
528 final byte [] hcdName = hcd.getName();
529 expectedException = false;
530 try {
531 this.admin.modifyColumn(tableName, hcd);
532 } catch (TableNotDisabledException re) {
533 expectedException = true;
534 }
535 assertFalse(expectedException);
536 modifiedHtd = this.admin.getTableDescriptor(tableName);
537 HColumnDescriptor modifiedHcd = modifiedHtd.getFamily(hcdName);
538 assertEquals(newMaxVersions, modifiedHcd.getMaxVersions());
539
540
541 assertFalse(this.admin.isTableDisabled(tableName));
542 final String xtracolName = "xtracol";
543 HColumnDescriptor xtracol = new HColumnDescriptor(xtracolName);
544 xtracol.setValue(xtracolName, xtracolName);
545 expectedException = false;
546 try {
547 this.admin.addColumn(tableName, xtracol);
548 } catch (TableNotDisabledException re) {
549 expectedException = true;
550 }
551
552 assertFalse(expectedException);
553 modifiedHtd = this.admin.getTableDescriptor(tableName);
554 hcd = modifiedHtd.getFamily(xtracol.getName());
555 assertTrue(hcd != null);
556 assertTrue(hcd.getValue(xtracolName).equals(xtracolName));
557
558
559 this.admin.deleteColumn(tableName, xtracol.getName());
560 modifiedHtd = this.admin.getTableDescriptor(tableName);
561 hcd = modifiedHtd.getFamily(xtracol.getName());
562 assertTrue(hcd == null);
563
564
565 this.admin.disableTable(tableName);
566 this.admin.deleteTable(tableName);
567 this.admin.listTables();
568 assertFalse(this.admin.tableExists(tableName));
569 }
570
571 @Test (timeout=300000)
572 public void testShouldFailOnlineSchemaUpdateIfOnlineSchemaIsNotEnabled()
573 throws Exception {
574 final TableName tableName = TableName.valueOf("changeTableSchemaOnlineFailure");
575 TEST_UTIL.getMiniHBaseCluster().getMaster().getConfiguration().setBoolean(
576 "hbase.online.schema.update.enable", false);
577 HTableDescriptor[] tables = admin.listTables();
578 int numTables = tables.length;
579 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
580 tables = this.admin.listTables();
581 assertEquals(numTables + 1, tables.length);
582
583
584 HTableDescriptor htd = this.admin.getTableDescriptor(tableName);
585
586 HTableDescriptor copy = new HTableDescriptor(htd);
587 assertTrue(htd.equals(copy));
588
589 long newFlushSize = htd.getMemStoreFlushSize() / 2;
590 if (newFlushSize <=0) {
591 newFlushSize = HTableDescriptor.DEFAULT_MEMSTORE_FLUSH_SIZE / 2;
592 }
593 copy.setMemStoreFlushSize(newFlushSize);
594 final String key = "anyoldkey";
595 assertTrue(htd.getValue(key) == null);
596 copy.setValue(key, key);
597 boolean expectedException = false;
598 try {
599 admin.modifyTable(tableName, copy);
600 } catch (TableNotDisabledException re) {
601 expectedException = true;
602 }
603 assertTrue("Online schema update should not happen.", expectedException);
604
605
606 TEST_UTIL.getMiniHBaseCluster().getMaster().getConfiguration().setBoolean(
607 "hbase.online.schema.update.enable", true);
608 }
609
610
611
612
613 static class DoneListener implements EventHandler.EventHandlerListener {
614 private final AtomicBoolean done;
615
616 DoneListener(final AtomicBoolean done) {
617 super();
618 this.done = done;
619 }
620
621 @Override
622 public void afterProcess(EventHandler event) {
623 this.done.set(true);
624 synchronized (this.done) {
625
626 this.done.notifyAll();
627 }
628 }
629
630 @Override
631 public void beforeProcess(EventHandler event) {
632
633 }
634 }
635
636 @SuppressWarnings("deprecation")
637 protected void verifyRoundRobinDistribution(HTable ht, int expectedRegions) throws IOException {
638 int numRS = ht.getConnection().getCurrentNrHRS();
639 Map<HRegionInfo, ServerName> regions = ht.getRegionLocations();
640 Map<ServerName, List<HRegionInfo>> server2Regions = new HashMap<ServerName, List<HRegionInfo>>();
641 for (Map.Entry<HRegionInfo, ServerName> entry : regions.entrySet()) {
642 ServerName server = entry.getValue();
643 List<HRegionInfo> regs = server2Regions.get(server);
644 if (regs == null) {
645 regs = new ArrayList<HRegionInfo>();
646 server2Regions.put(server, regs);
647 }
648 regs.add(entry.getKey());
649 }
650 float average = (float) expectedRegions/numRS;
651 int min = (int)Math.floor(average);
652 int max = (int)Math.ceil(average);
653 for (List<HRegionInfo> regionList : server2Regions.values()) {
654 assertTrue(regionList.size() == min || regionList.size() == max);
655 }
656 }
657
658 @Test (timeout=300000)
659 public void testCreateTableNumberOfRegions() throws IOException, InterruptedException {
660 TableName tableName = TableName.valueOf("testCreateTableNumberOfRegions");
661 HTableDescriptor desc = new HTableDescriptor(tableName);
662 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
663 admin.createTable(desc);
664 HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
665 Map<HRegionInfo, ServerName> regions = ht.getRegionLocations();
666 assertEquals("Table should have only 1 region", 1, regions.size());
667 ht.close();
668
669 TableName TABLE_2 = TableName.valueOf(tableName.getNameAsString() + "_2");
670 desc = new HTableDescriptor(TABLE_2);
671 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
672 admin.createTable(desc, new byte[][]{new byte[]{42}});
673 HTable ht2 = new HTable(TEST_UTIL.getConfiguration(), TABLE_2);
674 regions = ht2.getRegionLocations();
675 assertEquals("Table should have only 2 region", 2, regions.size());
676 ht2.close();
677
678 TableName TABLE_3 = TableName.valueOf(tableName.getNameAsString() + "_3");
679 desc = new HTableDescriptor(TABLE_3);
680 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
681 admin.createTable(desc, "a".getBytes(), "z".getBytes(), 3);
682 HTable ht3 = new HTable(TEST_UTIL.getConfiguration(), TABLE_3);
683 regions = ht3.getRegionLocations();
684 assertEquals("Table should have only 3 region", 3, regions.size());
685 ht3.close();
686
687 TableName TABLE_4 = TableName.valueOf(tableName.getNameAsString() + "_4");
688 desc = new HTableDescriptor(TABLE_4);
689 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
690 try {
691 admin.createTable(desc, "a".getBytes(), "z".getBytes(), 2);
692 fail("Should not be able to create a table with only 2 regions using this API.");
693 } catch (IllegalArgumentException eae) {
694
695 }
696
697 TableName TABLE_5 = TableName.valueOf(tableName.getNameAsString() + "_5");
698 desc = new HTableDescriptor(TABLE_5);
699 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
700 admin.createTable(desc, new byte[] {1}, new byte[] {127}, 16);
701 HTable ht5 = new HTable(TEST_UTIL.getConfiguration(), TABLE_5);
702 regions = ht5.getRegionLocations();
703 assertEquals("Table should have 16 region", 16, regions.size());
704 ht5.close();
705 }
706
707 @Test (timeout=300000)
708 public void testCreateTableWithRegions() throws IOException, InterruptedException {
709
710 TableName tableName = TableName.valueOf("testCreateTableWithRegions");
711
712 byte [][] splitKeys = {
713 new byte [] { 1, 1, 1 },
714 new byte [] { 2, 2, 2 },
715 new byte [] { 3, 3, 3 },
716 new byte [] { 4, 4, 4 },
717 new byte [] { 5, 5, 5 },
718 new byte [] { 6, 6, 6 },
719 new byte [] { 7, 7, 7 },
720 new byte [] { 8, 8, 8 },
721 new byte [] { 9, 9, 9 },
722 };
723 int expectedRegions = splitKeys.length + 1;
724
725 HTableDescriptor desc = new HTableDescriptor(tableName);
726 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
727 admin.createTable(desc, splitKeys);
728
729 boolean tableAvailable = admin.isTableAvailable(tableName, splitKeys);
730 assertTrue("Table should be created with splitKyes + 1 rows in META", tableAvailable);
731
732 HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
733 Map<HRegionInfo, ServerName> regions = ht.getRegionLocations();
734 assertEquals("Tried to create " + expectedRegions + " regions " +
735 "but only found " + regions.size(),
736 expectedRegions, regions.size());
737 System.err.println("Found " + regions.size() + " regions");
738
739 Iterator<HRegionInfo> hris = regions.keySet().iterator();
740 HRegionInfo hri = hris.next();
741 assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0);
742 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[0]));
743 hri = hris.next();
744 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[0]));
745 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[1]));
746 hri = hris.next();
747 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[1]));
748 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[2]));
749 hri = hris.next();
750 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[2]));
751 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[3]));
752 hri = hris.next();
753 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[3]));
754 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[4]));
755 hri = hris.next();
756 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[4]));
757 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[5]));
758 hri = hris.next();
759 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[5]));
760 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[6]));
761 hri = hris.next();
762 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[6]));
763 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[7]));
764 hri = hris.next();
765 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[7]));
766 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[8]));
767 hri = hris.next();
768 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[8]));
769 assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0);
770
771 verifyRoundRobinDistribution(ht, expectedRegions);
772 ht.close();
773
774
775
776
777 byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
778 byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
779
780
781
782
783 expectedRegions = 10;
784
785 TableName TABLE_2 = TableName.valueOf(tableName.getNameAsString() + "_2");
786
787 desc = new HTableDescriptor(TABLE_2);
788 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
789 admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
790 admin.createTable(desc, startKey, endKey, expectedRegions);
791
792 HTable ht2 = new HTable(TEST_UTIL.getConfiguration(), TABLE_2);
793 regions = ht2.getRegionLocations();
794 assertEquals("Tried to create " + expectedRegions + " regions " +
795 "but only found " + regions.size(),
796 expectedRegions, regions.size());
797 System.err.println("Found " + regions.size() + " regions");
798
799 hris = regions.keySet().iterator();
800 hri = hris.next();
801 assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0);
802 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {1,1,1,1,1,1,1,1,1,1}));
803 hri = hris.next();
804 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {1,1,1,1,1,1,1,1,1,1}));
805 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {2,2,2,2,2,2,2,2,2,2}));
806 hri = hris.next();
807 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {2,2,2,2,2,2,2,2,2,2}));
808 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {3,3,3,3,3,3,3,3,3,3}));
809 hri = hris.next();
810 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {3,3,3,3,3,3,3,3,3,3}));
811 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {4,4,4,4,4,4,4,4,4,4}));
812 hri = hris.next();
813 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {4,4,4,4,4,4,4,4,4,4}));
814 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {5,5,5,5,5,5,5,5,5,5}));
815 hri = hris.next();
816 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {5,5,5,5,5,5,5,5,5,5}));
817 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {6,6,6,6,6,6,6,6,6,6}));
818 hri = hris.next();
819 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {6,6,6,6,6,6,6,6,6,6}));
820 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {7,7,7,7,7,7,7,7,7,7}));
821 hri = hris.next();
822 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {7,7,7,7,7,7,7,7,7,7}));
823 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {8,8,8,8,8,8,8,8,8,8}));
824 hri = hris.next();
825 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {8,8,8,8,8,8,8,8,8,8}));
826 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {9,9,9,9,9,9,9,9,9,9}));
827 hri = hris.next();
828 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {9,9,9,9,9,9,9,9,9,9}));
829 assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0);
830
831 verifyRoundRobinDistribution(ht2, expectedRegions);
832 ht2.close();
833
834
835
836 startKey = new byte [] { 0, 0, 0, 0, 0, 0 };
837 endKey = new byte [] { 1, 0, 0, 0, 0, 0 };
838
839 expectedRegions = 5;
840
841 TableName TABLE_3 = TableName.valueOf(tableName.getNameAsString() + "_3");
842
843 desc = new HTableDescriptor(TABLE_3);
844 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
845 admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
846 admin.createTable(desc, startKey, endKey, expectedRegions);
847
848
849 HTable ht3 = new HTable(TEST_UTIL.getConfiguration(), TABLE_3);
850 regions = ht3.getRegionLocations();
851 assertEquals("Tried to create " + expectedRegions + " regions " +
852 "but only found " + regions.size(),
853 expectedRegions, regions.size());
854 System.err.println("Found " + regions.size() + " regions");
855
856 verifyRoundRobinDistribution(ht3, expectedRegions);
857 ht3.close();
858
859
860
861 splitKeys = new byte [][] {
862 new byte [] { 1, 1, 1 },
863 new byte [] { 2, 2, 2 },
864 new byte [] { 3, 3, 3 },
865 new byte [] { 2, 2, 2 }
866 };
867
868 TableName TABLE_4 = TableName.valueOf(tableName.getNameAsString() + "_4");
869 desc = new HTableDescriptor(TABLE_4);
870 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
871 Admin ladmin = new HBaseAdmin(TEST_UTIL.getConfiguration());
872 try {
873 ladmin.createTable(desc, splitKeys);
874 assertTrue("Should not be able to create this table because of " +
875 "duplicate split keys", false);
876 } catch(IllegalArgumentException iae) {
877
878 }
879 ladmin.close();
880 }
881
882 @Test (timeout=300000)
883 public void testTableAvailableWithRandomSplitKeys() throws Exception {
884 TableName tableName = TableName.valueOf("testTableAvailableWithRandomSplitKeys");
885 HTableDescriptor desc = new HTableDescriptor(tableName);
886 desc.addFamily(new HColumnDescriptor("col"));
887 byte[][] splitKeys = new byte[1][];
888 splitKeys = new byte [][] {
889 new byte [] { 1, 1, 1 },
890 new byte [] { 2, 2, 2 }
891 };
892 admin.createTable(desc);
893 boolean tableAvailable = admin.isTableAvailable(tableName, splitKeys);
894 assertFalse("Table should be created with 1 row in META", tableAvailable);
895 }
896
897 @Test (timeout=300000)
898 public void testCreateTableWithOnlyEmptyStartRow() throws IOException {
899 byte[] tableName = Bytes.toBytes("testCreateTableWithOnlyEmptyStartRow");
900 byte[][] splitKeys = new byte[1][];
901 splitKeys[0] = HConstants.EMPTY_BYTE_ARRAY;
902 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
903 desc.addFamily(new HColumnDescriptor("col"));
904 try {
905 admin.createTable(desc, splitKeys);
906 fail("Test case should fail as empty split key is passed.");
907 } catch (IllegalArgumentException e) {
908 }
909 }
910
911 @Test (timeout=300000)
912 public void testCreateTableWithEmptyRowInTheSplitKeys() throws IOException{
913 byte[] tableName = Bytes.toBytes("testCreateTableWithEmptyRowInTheSplitKeys");
914 byte[][] splitKeys = new byte[3][];
915 splitKeys[0] = "region1".getBytes();
916 splitKeys[1] = HConstants.EMPTY_BYTE_ARRAY;
917 splitKeys[2] = "region2".getBytes();
918 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
919 desc.addFamily(new HColumnDescriptor("col"));
920 try {
921 admin.createTable(desc, splitKeys);
922 fail("Test case should fail as empty split key is passed.");
923 } catch (IllegalArgumentException e) {
924 LOG.info("Expected ", e);
925 }
926 }
927
928 @Test (timeout=120000)
929 public void testTableExist() throws IOException {
930 final TableName table = TableName.valueOf("testTableExist");
931 boolean exist;
932 exist = this.admin.tableExists(table);
933 assertEquals(false, exist);
934 TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
935 exist = this.admin.tableExists(table);
936 assertEquals(true, exist);
937 }
938
939
940
941
942
943
944 @Test (timeout=400000)
945 public void testForceSplit() throws Exception {
946 byte[][] familyNames = new byte[][] { Bytes.toBytes("cf") };
947 int[] rowCounts = new int[] { 6000 };
948 int numVersions = HColumnDescriptor.DEFAULT_VERSIONS;
949 int blockSize = 256;
950 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
951
952 byte[] splitKey = Bytes.toBytes(3500);
953 splitTest(splitKey, familyNames, rowCounts, numVersions, blockSize);
954 }
955
956
957
958
959
960
961 @Test (timeout=300000)
962 public void testEnableTableRetainAssignment() throws IOException {
963 final TableName tableName = TableName.valueOf("testEnableTableAssignment");
964 byte[][] splitKeys = { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 },
965 new byte[] { 3, 3, 3 }, new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 },
966 new byte[] { 6, 6, 6 }, new byte[] { 7, 7, 7 }, new byte[] { 8, 8, 8 },
967 new byte[] { 9, 9, 9 } };
968 int expectedRegions = splitKeys.length + 1;
969 HTableDescriptor desc = new HTableDescriptor(tableName);
970 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
971 admin.createTable(desc, splitKeys);
972 HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
973 Map<HRegionInfo, ServerName> regions = ht.getRegionLocations();
974 assertEquals("Tried to create " + expectedRegions + " regions "
975 + "but only found " + regions.size(), expectedRegions, regions.size());
976
977 admin.disableTable(tableName);
978
979 admin.enableTable(tableName);
980 Map<HRegionInfo, ServerName> regions2 = ht.getRegionLocations();
981
982
983 assertEquals(regions.size(), regions2.size());
984 for (Map.Entry<HRegionInfo, ServerName> entry : regions.entrySet()) {
985 assertEquals(regions2.get(entry.getKey()), entry.getValue());
986 }
987 }
988
989
990
991
992
993
994
995 @Test (timeout=800000)
996 public void testForceSplitMultiFamily() throws Exception {
997 int numVersions = HColumnDescriptor.DEFAULT_VERSIONS;
998
999
1000
1001
1002 int blockSize = 256;
1003 byte[][] familyNames = new byte[][] { Bytes.toBytes("cf1"),
1004 Bytes.toBytes("cf2") };
1005
1006
1007 int[] rowCounts = new int[] { 6000, 1 };
1008 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
1009
1010 rowCounts = new int[] { 1, 6000 };
1011 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
1012
1013
1014
1015 rowCounts = new int[] { 6000, 300 };
1016 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
1017
1018 rowCounts = new int[] { 300, 6000 };
1019 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
1020
1021 }
1022
1023 void splitTest(byte[] splitPoint, byte[][] familyNames, int[] rowCounts,
1024 int numVersions, int blockSize) throws Exception {
1025 TableName tableName = TableName.valueOf("testForceSplit");
1026 StringBuilder sb = new StringBuilder();
1027
1028 for (int i = 0; i < rowCounts.length; i++) {
1029 sb.append("_").append(Integer.toString(rowCounts[i]));
1030 }
1031 assertFalse(admin.tableExists(tableName));
1032 final HTable table = TEST_UTIL.createTable(tableName, familyNames,
1033 numVersions, blockSize);
1034
1035 int rowCount = 0;
1036 byte[] q = new byte[0];
1037
1038
1039
1040 for (int index = 0; index < familyNames.length; index++) {
1041 ArrayList<Put> puts = new ArrayList<Put>(rowCounts[index]);
1042 for (int i = 0; i < rowCounts[index]; i++) {
1043 byte[] k = Bytes.toBytes(i);
1044 Put put = new Put(k);
1045 put.add(familyNames[index], q, k);
1046 puts.add(put);
1047 }
1048 table.put(puts);
1049
1050 if ( rowCount < rowCounts[index] ) {
1051 rowCount = rowCounts[index];
1052 }
1053 }
1054
1055
1056 Map<HRegionInfo, ServerName> m = table.getRegionLocations();
1057 LOG.info("Initial regions (" + m.size() + "): " + m);
1058 assertTrue(m.size() == 1);
1059
1060
1061 Scan scan = new Scan();
1062 ResultScanner scanner = table.getScanner(scan);
1063 int rows = 0;
1064 for(@SuppressWarnings("unused") Result result : scanner) {
1065 rows++;
1066 }
1067 scanner.close();
1068 assertEquals(rowCount, rows);
1069
1070
1071 scan = new Scan();
1072 scanner = table.getScanner(scan);
1073
1074 scanner.next();
1075
1076
1077 this.admin.split(tableName, splitPoint);
1078
1079 final AtomicInteger count = new AtomicInteger(0);
1080 Thread t = new Thread("CheckForSplit") {
1081 @Override
1082 public void run() {
1083 for (int i = 0; i < 45; i++) {
1084 try {
1085 sleep(1000);
1086 } catch (InterruptedException e) {
1087 continue;
1088 }
1089
1090 Map<HRegionInfo, ServerName> regions = null;
1091 try {
1092 regions = table.getRegionLocations();
1093 } catch (IOException e) {
1094 e.printStackTrace();
1095 }
1096 if (regions == null) continue;
1097 count.set(regions.size());
1098 if (count.get() >= 2) {
1099 LOG.info("Found: " + regions);
1100 break;
1101 }
1102 LOG.debug("Cycle waiting on split");
1103 }
1104 LOG.debug("CheckForSplit thread exited, current region count: " + count.get());
1105 }
1106 };
1107 t.setPriority(Thread.NORM_PRIORITY - 2);
1108 t.start();
1109 t.join();
1110
1111
1112 rows = 1;
1113 for (@SuppressWarnings("unused") Result result : scanner) {
1114 rows++;
1115 if (rows > rowCount) {
1116 scanner.close();
1117 assertTrue("Scanned more than expected (" + rowCount + ")", false);
1118 }
1119 }
1120 scanner.close();
1121 assertEquals(rowCount, rows);
1122
1123 Map<HRegionInfo, ServerName> regions = null;
1124 try {
1125 regions = table.getRegionLocations();
1126 } catch (IOException e) {
1127 e.printStackTrace();
1128 }
1129 assertEquals(2, regions.size());
1130 Set<HRegionInfo> hRegionInfos = regions.keySet();
1131 HRegionInfo[] r = hRegionInfos.toArray(new HRegionInfo[hRegionInfos.size()]);
1132 if (splitPoint != null) {
1133
1134 assertEquals(Bytes.toString(splitPoint),
1135 Bytes.toString(r[0].getEndKey()));
1136 assertEquals(Bytes.toString(splitPoint),
1137 Bytes.toString(r[1].getStartKey()));
1138 LOG.debug("Properly split on " + Bytes.toString(splitPoint));
1139 } else {
1140 if (familyNames.length > 1) {
1141 int splitKey = Bytes.toInt(r[0].getEndKey());
1142
1143
1144 int deltaForLargestFamily = Math.abs(rowCount/2 - splitKey);
1145 LOG.debug("SplitKey=" + splitKey + "&deltaForLargestFamily=" + deltaForLargestFamily +
1146 ", r=" + r[0]);
1147 for (int index = 0; index < familyNames.length; index++) {
1148 int delta = Math.abs(rowCounts[index]/2 - splitKey);
1149 if (delta < deltaForLargestFamily) {
1150 assertTrue("Delta " + delta + " for family " + index
1151 + " should be at least deltaForLargestFamily " + deltaForLargestFamily,
1152 false);
1153 }
1154 }
1155 }
1156 }
1157 TEST_UTIL.deleteTable(tableName);
1158 table.close();
1159 }
1160
1161 @Test
1162 public void testSplitAndMergeWithReplicaTable() throws Exception {
1163
1164
1165
1166
1167 TableName tableName = TableName.valueOf("testSplitAndMergeWithReplicaTable");
1168 HTableDescriptor desc = new HTableDescriptor(tableName);
1169 desc.setRegionReplication(3);
1170 byte[] cf = "f".getBytes();
1171 HColumnDescriptor hcd = new HColumnDescriptor(cf);
1172 desc.addFamily(hcd);
1173 byte[][] splitRows = new byte[2][];
1174 splitRows[0] = new byte[]{(byte)'4'};
1175 splitRows[1] = new byte[]{(byte)'7'};
1176 TEST_UTIL.getHBaseAdmin().createTable(desc, splitRows);
1177 List<HRegion> oldRegions;
1178 do {
1179 oldRegions = TEST_UTIL.getHBaseCluster().getRegions(tableName);
1180 Thread.sleep(10);
1181 } while (oldRegions.size() != 9);
1182
1183 HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
1184 List<Put> puts = new ArrayList<Put>();
1185 byte[] qualifier = "c".getBytes();
1186 Put put = new Put(new byte[]{(byte)'1'});
1187 put.add(cf, qualifier, "100".getBytes());
1188 puts.add(put);
1189 put = new Put(new byte[]{(byte)'6'});
1190 put.add(cf, qualifier, "100".getBytes());
1191 puts.add(put);
1192 put = new Put(new byte[]{(byte)'8'});
1193 put.add(cf, qualifier, "100".getBytes());
1194 puts.add(put);
1195 ht.put(puts);
1196 ht.flushCommits();
1197 ht.close();
1198 List<Pair<HRegionInfo, ServerName>> regions =
1199 MetaTableAccessor.getTableRegionsAndLocations(TEST_UTIL.getZooKeeperWatcher(),
1200 TEST_UTIL.getConnection(), tableName);
1201 boolean gotException = false;
1202
1203
1204 try {
1205 TEST_UTIL.getHBaseAdmin().split(regions.get(1).getFirst().getRegionName());
1206 } catch (IllegalArgumentException ex) {
1207 gotException = true;
1208 }
1209 assertTrue(gotException);
1210 gotException = false;
1211
1212
1213
1214 try {
1215 TEST_UTIL.getHBaseAdmin().split(regions.get(1).getSecond(), regions.get(1).getFirst(),
1216 new byte[]{(byte)'1'});
1217 } catch (IOException ex) {
1218 gotException = true;
1219 }
1220 assertTrue(gotException);
1221 gotException = false;
1222
1223 try {
1224 TEST_UTIL.getHBaseAdmin().mergeRegions(regions.get(1).getFirst().getEncodedNameAsBytes(),
1225 regions.get(2).getFirst().getEncodedNameAsBytes(), true);
1226 } catch (IllegalArgumentException m) {
1227 gotException = true;
1228 }
1229 assertTrue(gotException);
1230
1231 try {
1232 DispatchMergingRegionsRequest request = RequestConverter
1233 .buildDispatchMergingRegionsRequest(regions.get(1).getFirst().getEncodedNameAsBytes(),
1234 regions.get(2).getFirst().getEncodedNameAsBytes(), true);
1235 TEST_UTIL.getHBaseAdmin().getConnection().getMaster().dispatchMergingRegions(null, request);
1236 } catch (ServiceException m) {
1237 Throwable t = m.getCause();
1238 do {
1239 if (t instanceof MergeRegionException) {
1240 gotException = true;
1241 break;
1242 }
1243 t = t.getCause();
1244 } while (t != null);
1245 }
1246 assertTrue(gotException);
1247 gotException = false;
1248
1249
1250 if (!regions.get(2).getSecond().equals(regions.get(1).getSecond())) {
1251 moveRegionAndWait(regions.get(2).getFirst(), regions.get(1).getSecond());
1252 }
1253 try {
1254 AdminService.BlockingInterface admin = TEST_UTIL.getHBaseAdmin().getConnection()
1255 .getAdmin(regions.get(1).getSecond());
1256 ProtobufUtil.mergeRegions(null, admin, regions.get(1).getFirst(), regions.get(2).getFirst(), true);
1257 } catch (MergeRegionException mm) {
1258 gotException = true;
1259 }
1260 assertTrue(gotException);
1261 }
1262
1263 private void moveRegionAndWait(HRegionInfo destRegion, ServerName destServer)
1264 throws InterruptedException, MasterNotRunningException,
1265 ZooKeeperConnectionException, IOException {
1266 HMaster master = TEST_UTIL.getMiniHBaseCluster().getMaster();
1267 TEST_UTIL.getHBaseAdmin().move(
1268 destRegion.getEncodedNameAsBytes(),
1269 Bytes.toBytes(destServer.getServerName()));
1270 while (true) {
1271 ServerName serverName = master.getAssignmentManager()
1272 .getRegionStates().getRegionServerOfRegion(destRegion);
1273 if (serverName != null && serverName.equals(destServer)) {
1274 TEST_UTIL.assertRegionOnServer(
1275 destRegion, serverName, 200);
1276 break;
1277 }
1278 Thread.sleep(10);
1279 }
1280 }
1281
1282
1283
1284
1285
1286 @SuppressWarnings("deprecation")
1287 @Test (expected=IllegalArgumentException.class, timeout=300000)
1288 public void testEmptyHTableDescriptor() throws IOException {
1289 this.admin.createTable(new HTableDescriptor());
1290 }
1291
1292 @Test (expected=IllegalArgumentException.class, timeout=300000)
1293 public void testInvalidHColumnDescriptor() throws IOException {
1294 new HColumnDescriptor("/cfamily/name");
1295 }
1296
1297 @Test (timeout=300000)
1298 public void testEnableDisableAddColumnDeleteColumn() throws Exception {
1299 ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(TEST_UTIL);
1300 TableName tableName = TableName.valueOf("testEnableDisableAddColumnDeleteColumn");
1301 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
1302 while (!ZKTableStateClientSideReader.isEnabledTable(zkw,
1303 TableName.valueOf("testEnableDisableAddColumnDeleteColumn"))) {
1304 Thread.sleep(10);
1305 }
1306 this.admin.disableTable(tableName);
1307 try {
1308 new HTable(TEST_UTIL.getConfiguration(), tableName);
1309 } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
1310
1311 }
1312
1313 this.admin.addColumn(tableName, new HColumnDescriptor("col2"));
1314 this.admin.enableTable(tableName);
1315 try {
1316 this.admin.deleteColumn(tableName, Bytes.toBytes("col2"));
1317 } catch (TableNotDisabledException e) {
1318 LOG.info(e);
1319 }
1320 this.admin.disableTable(tableName);
1321 this.admin.deleteTable(tableName);
1322 }
1323
1324 @Test (timeout=300000)
1325 public void testDeleteLastColumnFamily() throws Exception {
1326 TableName tableName = TableName.valueOf("testDeleteLastColumnFamily");
1327 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
1328 while (!this.admin.isTableEnabled(TableName.valueOf("testDeleteLastColumnFamily"))) {
1329 Thread.sleep(10);
1330 }
1331
1332
1333 try {
1334 this.admin.deleteColumn(tableName, HConstants.CATALOG_FAMILY);
1335 fail("Should have failed to delete the only column family of a table");
1336 } catch (InvalidFamilyOperationException ex) {
1337
1338 }
1339
1340
1341 this.admin.disableTable(tableName);
1342
1343 try {
1344 this.admin.deleteColumn(tableName, HConstants.CATALOG_FAMILY);
1345 fail("Should have failed to delete the only column family of a table");
1346 } catch (InvalidFamilyOperationException ex) {
1347
1348 }
1349
1350 this.admin.deleteTable(tableName);
1351 }
1352 }