1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.client;
21
22
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27
28 import java.io.IOException;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.Comparator;
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.concurrent.atomic.AtomicBoolean;
37 import java.util.concurrent.atomic.AtomicInteger;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.hadoop.conf.Configuration;
42 import org.apache.hadoop.hbase.*;
43 import org.apache.hadoop.hbase.catalog.CatalogTracker;
44 import org.apache.hadoop.hbase.executor.EventHandler;
45 import org.apache.hadoop.hbase.executor.EventHandler.EventType;
46 import org.apache.hadoop.hbase.executor.ExecutorService;
47 import org.apache.hadoop.hbase.master.MasterServices;
48 import org.apache.hadoop.hbase.regionserver.HRegion;
49 import org.apache.hadoop.hbase.regionserver.HRegionServer;
50 import org.apache.hadoop.hbase.regionserver.wal.HLogUtilsForTests;
51 import org.apache.hadoop.hbase.InvalidFamilyOperationException;
52 import org.apache.hadoop.hbase.util.Bytes;
53 import org.apache.hadoop.hbase.util.Pair;
54 import org.apache.hadoop.hbase.zookeeper.ZKTableReadOnly;
55 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
56 import org.junit.*;
57 import org.junit.experimental.categories.Category;
58
59
60
61
62
63
64
65 @Category(LargeTests.class)
66 public class TestAdmin {
67 final Log LOG = LogFactory.getLog(getClass());
68 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
69 private HBaseAdmin admin;
70
71 @BeforeClass
72 public static void setUpBeforeClass() throws Exception {
73 TEST_UTIL.getConfiguration().setBoolean("hbase.online.schema.update.enable", true);
74 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
75 TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
76 TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 6);
77 TEST_UTIL.getConfiguration().setBoolean(
78 "hbase.master.enabletable.roundrobin", true);
79 TEST_UTIL.startMiniCluster(3);
80 }
81
82 @AfterClass
83 public static void tearDownAfterClass() throws Exception {
84 TEST_UTIL.shutdownMiniCluster();
85 }
86
87 @Before
88 public void setUp() throws Exception {
89 this.admin = TEST_UTIL.getHBaseAdmin();
90 }
91
92 @After
93 public void tearDown() throws Exception {
94 }
95
96 @Test
97 public void testSplitFlushCompactUnknownTable() throws InterruptedException {
98 final String unknowntable = "fubar";
99 Exception exception = null;
100 try {
101 this.admin.compact(unknowntable);
102 } catch (IOException e) {
103 exception = e;
104 }
105 assertTrue(exception instanceof TableNotFoundException);
106
107 exception = null;
108 try {
109 this.admin.flush(unknowntable);
110 } catch (IOException e) {
111 exception = e;
112 }
113 assertTrue(exception instanceof TableNotFoundException);
114
115 exception = null;
116 try {
117 this.admin.split(unknowntable);
118 } catch (IOException e) {
119 exception = e;
120 }
121 assertTrue(exception instanceof TableNotFoundException);
122 }
123
124 @Test
125 public void testDeleteEditUnknownColumnFamilyAndOrTable() throws IOException {
126
127 final String nonexistent = "nonexistent";
128 HColumnDescriptor nonexistentHcd = new HColumnDescriptor(nonexistent);
129 Exception exception = null;
130 try {
131 this.admin.addColumn(nonexistent, nonexistentHcd);
132 } catch (IOException e) {
133 exception = e;
134 }
135 assertTrue(exception instanceof TableNotFoundException);
136
137 exception = null;
138 try {
139 this.admin.deleteTable(nonexistent);
140 } catch (IOException e) {
141 exception = e;
142 }
143 assertTrue(exception instanceof TableNotFoundException);
144
145 exception = null;
146 try {
147 this.admin.deleteColumn(nonexistent, nonexistent);
148 } catch (IOException e) {
149 exception = e;
150 }
151 assertTrue(exception instanceof TableNotFoundException);
152
153 exception = null;
154 try {
155 this.admin.disableTable(nonexistent);
156 } catch (IOException e) {
157 exception = e;
158 }
159 assertTrue(exception instanceof TableNotFoundException);
160
161 exception = null;
162 try {
163 this.admin.enableTable(nonexistent);
164 } catch (IOException e) {
165 exception = e;
166 }
167 assertTrue(exception instanceof TableNotFoundException);
168
169 exception = null;
170 try {
171 this.admin.modifyColumn(nonexistent, nonexistentHcd);
172 } catch (IOException e) {
173 exception = e;
174 }
175 assertTrue(exception instanceof TableNotFoundException);
176
177 exception = null;
178 try {
179 HTableDescriptor htd = new HTableDescriptor(nonexistent);
180 this.admin.modifyTable(htd.getName(), htd);
181 } catch (IOException e) {
182 exception = e;
183 }
184 assertTrue(exception instanceof TableNotFoundException);
185
186
187
188 final String tableName = "t";
189 HTableDescriptor htd = new HTableDescriptor(tableName);
190 htd.addFamily(new HColumnDescriptor("cf"));
191 this.admin.createTable(htd);
192 try {
193 exception = null;
194 try {
195 this.admin.deleteColumn(htd.getName(), nonexistentHcd.getName());
196 } catch (IOException e) {
197 exception = e;
198 }
199 assertTrue(exception instanceof InvalidFamilyOperationException);
200
201 exception = null;
202 try {
203 this.admin.modifyColumn(htd.getName(), nonexistentHcd);
204 } catch (IOException e) {
205 exception = e;
206 }
207 assertTrue(exception instanceof InvalidFamilyOperationException);
208 } finally {
209 this.admin.disableTable(tableName);
210 this.admin.deleteTable(tableName);
211 }
212 }
213
214 @Test
215 public void testDisableAndEnableTable() throws IOException {
216 final byte [] row = Bytes.toBytes("row");
217 final byte [] qualifier = Bytes.toBytes("qualifier");
218 final byte [] value = Bytes.toBytes("value");
219 final byte [] table = Bytes.toBytes("testDisableAndEnableTable");
220 HTable ht = TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
221 Put put = new Put(row);
222 put.add(HConstants.CATALOG_FAMILY, qualifier, value);
223 ht.put(put);
224 Get get = new Get(row);
225 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
226 ht.get(get);
227
228 this.admin.disableTable(table);
229 assertTrue("Table must be disabled.", TEST_UTIL.getHBaseCluster()
230 .getMaster().getAssignmentManager().getZKTable().isDisabledTable(
231 Bytes.toString(table)));
232
233
234 get = new Get(row);
235 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
236 boolean ok = false;
237 try {
238 ht.get(get);
239 } catch (DoNotRetryIOException e) {
240 ok = true;
241 }
242 assertTrue(ok);
243 this.admin.enableTable(table);
244 assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster()
245 .getMaster().getAssignmentManager().getZKTable().isEnabledTable(
246 Bytes.toString(table)));
247
248
249 try {
250 ht.get(get);
251 } catch (RetriesExhaustedException e) {
252 ok = false;
253 }
254 assertTrue(ok);
255 ht.close();
256 }
257
258 @Test
259 public void testIsEnabledOnUnknownTable() throws Exception {
260 try {
261 admin.isTableEnabled(Bytes.toBytes("unkownTable"));
262 fail("Test should fail if isTableEnabled called on unknown table.");
263 } catch (IOException e) {
264 }
265 }
266
267 @Test
268 public void testDisableAndEnableTables() throws IOException {
269 final byte [] row = Bytes.toBytes("row");
270 final byte [] qualifier = Bytes.toBytes("qualifier");
271 final byte [] value = Bytes.toBytes("value");
272 final byte [] table1 = Bytes.toBytes("testDisableAndEnableTable1");
273 final byte [] table2 = Bytes.toBytes("testDisableAndEnableTable2");
274 HTable ht1 = TEST_UTIL.createTable(table1, HConstants.CATALOG_FAMILY);
275 HTable ht2 = TEST_UTIL.createTable(table2, HConstants.CATALOG_FAMILY);
276 Put put = new Put(row);
277 put.add(HConstants.CATALOG_FAMILY, qualifier, value);
278 ht1.put(put);
279 ht2.put(put);
280 Get get = new Get(row);
281 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
282 ht1.get(get);
283 ht2.get(get);
284
285 this.admin.disableTables("testDisableAndEnableTable.*");
286
287
288 get = new Get(row);
289 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
290 boolean ok = false;
291 try {
292 ht1.get(get);
293 ht2.get(get);
294 } catch (DoNotRetryIOException e) {
295 ok = true;
296 }
297
298 assertTrue(ok);
299 this.admin.enableTables("testDisableAndEnableTable.*");
300
301
302 try {
303 ht1.get(get);
304 } catch (IOException e) {
305 ok = false;
306 }
307 try {
308 ht2.get(get);
309 } catch (IOException e) {
310 ok = false;
311 }
312 assertTrue(ok);
313
314 ht1.close();
315 ht2.close();
316 }
317
318 @Test
319 public void testCreateTable() throws IOException {
320 HTableDescriptor [] tables = admin.listTables();
321 int numTables = tables.length;
322 TEST_UTIL.createTable(Bytes.toBytes("testCreateTable"),
323 HConstants.CATALOG_FAMILY).close();
324 tables = this.admin.listTables();
325 assertEquals(numTables + 1, tables.length);
326 assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster()
327 .getMaster().getAssignmentManager().getZKTable().isEnabledTable(
328 "testCreateTable"));
329 }
330
331 @Test
332 public void testGetTableDescriptor() throws IOException {
333 HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
334 HColumnDescriptor fam2 = new HColumnDescriptor("fam2");
335 HColumnDescriptor fam3 = new HColumnDescriptor("fam3");
336 HTableDescriptor htd = new HTableDescriptor("myTestTable");
337 htd.addFamily(fam1);
338 htd.addFamily(fam2);
339 htd.addFamily(fam3);
340 this.admin.createTable(htd);
341 HTable table = new HTable(TEST_UTIL.getConfiguration(), "myTestTable");
342 HTableDescriptor confirmedHtd = table.getTableDescriptor();
343 assertEquals(htd.compareTo(confirmedHtd), 0);
344 table.close();
345 }
346
347 @Test
348 public void testHColumnValidName() {
349 boolean exceptionThrown = false;
350 try {
351 HColumnDescriptor fam1 = new HColumnDescriptor("\\test\\abc");
352 } catch(IllegalArgumentException iae) {
353 exceptionThrown = true;
354 assertTrue(exceptionThrown);
355 }
356 }
357
358
359
360
361
362 @Test
363 public void testOnlineChangeTableSchema() throws IOException, InterruptedException {
364 final byte [] tableName = Bytes.toBytes("changeTableSchemaOnline");
365 TEST_UTIL.getMiniHBaseCluster().getMaster().getConfiguration().setBoolean(
366 "hbase.online.schema.update.enable", true);
367 HTableDescriptor [] tables = admin.listTables();
368 int numTables = tables.length;
369 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
370 tables = this.admin.listTables();
371 assertEquals(numTables + 1, tables.length);
372
373
374 HTableDescriptor htd = this.admin.getTableDescriptor(tableName);
375
376 HTableDescriptor copy = new HTableDescriptor(htd);
377 assertTrue(htd.equals(copy));
378
379 long newFlushSize = htd.getMemStoreFlushSize() / 2;
380 if (newFlushSize <=0) {
381 newFlushSize = HTableDescriptor.DEFAULT_MEMSTORE_FLUSH_SIZE / 2;
382 }
383 copy.setMemStoreFlushSize(newFlushSize);
384 final String key = "anyoldkey";
385 assertTrue(htd.getValue(key) == null);
386 copy.setValue(key, key);
387 boolean expectedException = false;
388 try {
389 modifyTable(tableName, copy);
390 } catch (TableNotDisabledException re) {
391 expectedException = true;
392 }
393 assertFalse(expectedException);
394 HTableDescriptor modifiedHtd = this.admin.getTableDescriptor(tableName);
395 assertFalse(htd.equals(modifiedHtd));
396 assertTrue(copy.equals(modifiedHtd));
397 assertEquals(newFlushSize, modifiedHtd.getMemStoreFlushSize());
398 assertEquals(key, modifiedHtd.getValue(key));
399
400
401 htd = this.admin.getTableDescriptor(tableName);
402 int countOfFamilies = modifiedHtd.getFamilies().size();
403 assertTrue(countOfFamilies > 0);
404 HColumnDescriptor hcd = modifiedHtd.getFamilies().iterator().next();
405 int maxversions = hcd.getMaxVersions();
406 final int newMaxVersions = maxversions + 1;
407 hcd.setMaxVersions(newMaxVersions);
408 final byte [] hcdName = hcd.getName();
409 expectedException = false;
410 try {
411 this.admin.modifyColumn(tableName, hcd);
412 } catch (TableNotDisabledException re) {
413 expectedException = true;
414 }
415 assertFalse(expectedException);
416 modifiedHtd = this.admin.getTableDescriptor(tableName);
417 HColumnDescriptor modifiedHcd = modifiedHtd.getFamily(hcdName);
418 assertEquals(newMaxVersions, modifiedHcd.getMaxVersions());
419
420
421 assertFalse(this.admin.isTableDisabled(tableName));
422 final String xtracolName = "xtracol";
423 htd = this.admin.getTableDescriptor(tableName);
424 HColumnDescriptor xtracol = new HColumnDescriptor(xtracolName);
425 xtracol.setValue(xtracolName, xtracolName);
426 expectedException = false;
427 try {
428 this.admin.addColumn(tableName, xtracol);
429 } catch (TableNotDisabledException re) {
430 expectedException = true;
431 }
432
433 assertFalse(expectedException);
434 modifiedHtd = this.admin.getTableDescriptor(tableName);
435 hcd = modifiedHtd.getFamily(xtracol.getName());
436 assertTrue(hcd != null);
437 assertTrue(hcd.getValue(xtracolName).equals(xtracolName));
438
439
440 this.admin.deleteColumn(tableName, xtracol.getName());
441 modifiedHtd = this.admin.getTableDescriptor(tableName);
442 hcd = modifiedHtd.getFamily(xtracol.getName());
443 assertTrue(hcd == null);
444
445
446 this.admin.disableTable(tableName);
447 this.admin.deleteTable(tableName);
448 this.admin.listTables();
449 assertFalse(this.admin.tableExists(tableName));
450 }
451
452 @Test
453 public void testShouldFailOnlineSchemaUpdateIfOnlineSchemaIsNotEnabled()
454 throws Exception {
455 final byte[] tableName = Bytes.toBytes("changeTableSchemaOnlineFailure");
456 TEST_UTIL.getMiniHBaseCluster().getMaster().getConfiguration().setBoolean(
457 "hbase.online.schema.update.enable", false);
458 HTableDescriptor[] tables = admin.listTables();
459 int numTables = tables.length;
460 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
461 tables = this.admin.listTables();
462 assertEquals(numTables + 1, tables.length);
463
464
465 HTableDescriptor htd = this.admin.getTableDescriptor(tableName);
466
467 HTableDescriptor copy = new HTableDescriptor(htd);
468 assertTrue(htd.equals(copy));
469
470 long newFlushSize = htd.getMemStoreFlushSize() / 2;
471 if (newFlushSize <=0) {
472 newFlushSize = HTableDescriptor.DEFAULT_MEMSTORE_FLUSH_SIZE / 2;
473 }
474 copy.setMemStoreFlushSize(newFlushSize);
475 final String key = "anyoldkey";
476 assertTrue(htd.getValue(key) == null);
477 copy.setValue(key, key);
478 boolean expectedException = false;
479 try {
480 modifyTable(tableName, copy);
481 } catch (TableNotDisabledException re) {
482 expectedException = true;
483 }
484 assertTrue("Online schema update should not happen.", expectedException);
485 }
486
487
488
489
490
491
492
493 private void modifyTable(final byte [] tableName, final HTableDescriptor htd)
494 throws IOException {
495 MasterServices services = TEST_UTIL.getMiniHBaseCluster().getMaster();
496 ExecutorService executor = services.getExecutorService();
497 AtomicBoolean done = new AtomicBoolean(false);
498 executor.registerListener(EventType.C_M_MODIFY_TABLE, new DoneListener(done));
499 this.admin.modifyTable(tableName, htd);
500 while (!done.get()) {
501 synchronized (done) {
502 try {
503 done.wait(100);
504 } catch (InterruptedException e) {
505 e.printStackTrace();
506 }
507 }
508 }
509 executor.unregisterListener(EventType.C_M_MODIFY_TABLE);
510 }
511
512
513
514
515 static class DoneListener implements EventHandler.EventHandlerListener {
516 private final AtomicBoolean done;
517
518 DoneListener(final AtomicBoolean done) {
519 super();
520 this.done = done;
521 }
522
523 @Override
524 public void afterProcess(EventHandler event) {
525 this.done.set(true);
526 synchronized (this.done) {
527
528 this.done.notifyAll();
529 }
530 }
531
532 @Override
533 public void beforeProcess(EventHandler event) {
534
535 }
536 }
537
538 protected void verifyRoundRobinDistribution(HTable ht, int expectedRegions) throws IOException {
539 int numRS = ht.getConnection().getCurrentNrHRS();
540 Map<HRegionInfo,HServerAddress> regions = ht.getRegionsInfo();
541 Map<HServerAddress, List<HRegionInfo>> server2Regions = new HashMap<HServerAddress, List<HRegionInfo>>();
542 for (Map.Entry<HRegionInfo,HServerAddress> entry : regions.entrySet()) {
543 HServerAddress server = entry.getValue();
544 List<HRegionInfo> regs = server2Regions.get(server);
545 if (regs == null) {
546 regs = new ArrayList<HRegionInfo>();
547 server2Regions.put(server, regs);
548 }
549 regs.add(entry.getKey());
550 }
551 float average = (float) expectedRegions/numRS;
552 int min = (int)Math.floor(average);
553 int max = (int)Math.ceil(average);
554 for (List<HRegionInfo> regionList : server2Regions.values()) {
555 assertTrue(regionList.size() == min || regionList.size() == max);
556 }
557 }
558
559 @Test
560 public void testCreateTableNumberOfRegions() throws IOException, InterruptedException {
561 byte[] tableName = Bytes.toBytes("testCreateTableNumberOfRegions");
562 HTableDescriptor desc = new HTableDescriptor(tableName);
563 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
564 admin.createTable(desc);
565 HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
566 Map<HRegionInfo, ServerName> regions = ht.getRegionLocations();
567 assertEquals("Table should have only 1 region", 1, regions.size());
568 ht.close();
569
570 byte[] TABLE_2 = Bytes.add(tableName, Bytes.toBytes("_2"));
571 desc = new HTableDescriptor(TABLE_2);
572 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
573 admin.createTable(desc, new byte[][] { new byte[] { 42 } });
574 HTable ht2 = new HTable(TEST_UTIL.getConfiguration(), TABLE_2);
575 regions = ht2.getRegionLocations();
576 assertEquals("Table should have only 2 region", 2, regions.size());
577 ht2.close();
578
579 byte[] TABLE_3 = Bytes.add(tableName, Bytes.toBytes("_3"));
580 desc = new HTableDescriptor(TABLE_3);
581 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
582 admin.createTable(desc, "a".getBytes(), "z".getBytes(), 3);
583 HTable ht3 = new HTable(TEST_UTIL.getConfiguration(), TABLE_3);
584 regions = ht3.getRegionLocations();
585 assertEquals("Table should have only 3 region", 3, regions.size());
586 ht3.close();
587
588 byte[] TABLE_4 = Bytes.add(tableName, Bytes.toBytes("_4"));
589 desc = new HTableDescriptor(TABLE_4);
590 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
591 try {
592 admin.createTable(desc, "a".getBytes(), "z".getBytes(), 2);
593 fail("Should not be able to create a table with only 2 regions using this API.");
594 } catch (IllegalArgumentException eae) {
595
596 }
597
598 byte[] TABLE_5 = Bytes.add(tableName, Bytes.toBytes("_5"));
599 desc = new HTableDescriptor(TABLE_5);
600 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
601 admin.createTable(desc, new byte[] { 1 }, new byte[] { 127 }, 16);
602 HTable ht5 = new HTable(TEST_UTIL.getConfiguration(), TABLE_5);
603 regions = ht5.getRegionLocations();
604 assertEquals("Table should have 16 region", 16, regions.size());
605 ht5.close();
606 }
607
608 @Test
609 public void testCreateTableWithRegions() throws IOException, InterruptedException {
610
611 byte[] tableName = Bytes.toBytes("testCreateTableWithRegions");
612
613 byte [][] splitKeys = {
614 new byte [] { 1, 1, 1 },
615 new byte [] { 2, 2, 2 },
616 new byte [] { 3, 3, 3 },
617 new byte [] { 4, 4, 4 },
618 new byte [] { 5, 5, 5 },
619 new byte [] { 6, 6, 6 },
620 new byte [] { 7, 7, 7 },
621 new byte [] { 8, 8, 8 },
622 new byte [] { 9, 9, 9 },
623 };
624 int expectedRegions = splitKeys.length + 1;
625
626 HTableDescriptor desc = new HTableDescriptor(tableName);
627 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
628 admin.createTable(desc, splitKeys);
629
630 HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
631 Map<HRegionInfo,HServerAddress> regions = ht.getRegionsInfo();
632 assertEquals("Tried to create " + expectedRegions + " regions " +
633 "but only found " + regions.size(),
634 expectedRegions, regions.size());
635 System.err.println("Found " + regions.size() + " regions");
636
637 Iterator<HRegionInfo> hris = regions.keySet().iterator();
638 HRegionInfo hri = hris.next();
639 assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0);
640 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[0]));
641 hri = hris.next();
642 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[0]));
643 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[1]));
644 hri = hris.next();
645 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[1]));
646 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[2]));
647 hri = hris.next();
648 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[2]));
649 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[3]));
650 hri = hris.next();
651 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[3]));
652 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[4]));
653 hri = hris.next();
654 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[4]));
655 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[5]));
656 hri = hris.next();
657 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[5]));
658 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[6]));
659 hri = hris.next();
660 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[6]));
661 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[7]));
662 hri = hris.next();
663 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[7]));
664 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[8]));
665 hri = hris.next();
666 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[8]));
667 assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0);
668
669 verifyRoundRobinDistribution(ht, expectedRegions);
670 ht.close();
671
672
673
674
675 byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
676 byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
677
678
679
680
681 expectedRegions = 10;
682
683 byte [] TABLE_2 = Bytes.add(tableName, Bytes.toBytes("_2"));
684
685 desc = new HTableDescriptor(TABLE_2);
686 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
687 admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
688 admin.createTable(desc, startKey, endKey, expectedRegions);
689
690 HTable ht2 = new HTable(TEST_UTIL.getConfiguration(), TABLE_2);
691 regions = ht2.getRegionsInfo();
692 assertEquals("Tried to create " + expectedRegions + " regions " +
693 "but only found " + regions.size(),
694 expectedRegions, regions.size());
695 System.err.println("Found " + regions.size() + " regions");
696
697 hris = regions.keySet().iterator();
698 hri = hris.next();
699 assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0);
700 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {1,1,1,1,1,1,1,1,1,1}));
701 hri = hris.next();
702 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {1,1,1,1,1,1,1,1,1,1}));
703 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {2,2,2,2,2,2,2,2,2,2}));
704 hri = hris.next();
705 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {2,2,2,2,2,2,2,2,2,2}));
706 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {3,3,3,3,3,3,3,3,3,3}));
707 hri = hris.next();
708 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {3,3,3,3,3,3,3,3,3,3}));
709 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {4,4,4,4,4,4,4,4,4,4}));
710 hri = hris.next();
711 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {4,4,4,4,4,4,4,4,4,4}));
712 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {5,5,5,5,5,5,5,5,5,5}));
713 hri = hris.next();
714 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {5,5,5,5,5,5,5,5,5,5}));
715 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {6,6,6,6,6,6,6,6,6,6}));
716 hri = hris.next();
717 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {6,6,6,6,6,6,6,6,6,6}));
718 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {7,7,7,7,7,7,7,7,7,7}));
719 hri = hris.next();
720 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {7,7,7,7,7,7,7,7,7,7}));
721 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {8,8,8,8,8,8,8,8,8,8}));
722 hri = hris.next();
723 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {8,8,8,8,8,8,8,8,8,8}));
724 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {9,9,9,9,9,9,9,9,9,9}));
725 hri = hris.next();
726 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {9,9,9,9,9,9,9,9,9,9}));
727 assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0);
728
729 verifyRoundRobinDistribution(ht2, expectedRegions);
730 ht2.close();
731
732
733
734 startKey = new byte [] { 0, 0, 0, 0, 0, 0 };
735 endKey = new byte [] { 1, 0, 0, 0, 0, 0 };
736
737 expectedRegions = 5;
738
739 byte [] TABLE_3 = Bytes.add(tableName, Bytes.toBytes("_3"));
740
741 desc = new HTableDescriptor(TABLE_3);
742 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
743 admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
744 admin.createTable(desc, startKey, endKey, expectedRegions);
745
746
747 HTable ht3 = new HTable(TEST_UTIL.getConfiguration(), TABLE_3);
748 regions = ht3.getRegionsInfo();
749 assertEquals("Tried to create " + expectedRegions + " regions " +
750 "but only found " + regions.size(),
751 expectedRegions, regions.size());
752 System.err.println("Found " + regions.size() + " regions");
753
754 verifyRoundRobinDistribution(ht3, expectedRegions);
755 ht3.close();
756
757
758
759 splitKeys = new byte [][] {
760 new byte [] { 1, 1, 1 },
761 new byte [] { 2, 2, 2 },
762 new byte [] { 3, 3, 3 },
763 new byte [] { 2, 2, 2 }
764 };
765
766 byte [] TABLE_4 = Bytes.add(tableName, Bytes.toBytes("_4"));
767 desc = new HTableDescriptor(TABLE_4);
768 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
769 HBaseAdmin ladmin = new HBaseAdmin(TEST_UTIL.getConfiguration());
770 try {
771 ladmin.createTable(desc, splitKeys);
772 assertTrue("Should not be able to create this table because of " +
773 "duplicate split keys", false);
774 } catch(IllegalArgumentException iae) {
775
776 }
777 ladmin.close();
778 }
779
780
781 @Test
782 public void testCreateTableWithOnlyEmptyStartRow() throws IOException {
783 byte[] tableName = Bytes.toBytes("testCreateTableWithOnlyEmptyStartRow");
784 byte[][] splitKeys = new byte[1][];
785 splitKeys[0] = HConstants.EMPTY_BYTE_ARRAY;
786 HTableDescriptor desc = new HTableDescriptor(tableName);
787 desc.addFamily(new HColumnDescriptor("col"));
788 try {
789 admin.createTable(desc, splitKeys);
790 fail("Test case should fail as empty split key is passed.");
791 } catch (IllegalArgumentException e) {
792 }
793 }
794
795 @Test
796 public void testCreateTableWithEmptyRowInTheSplitKeys() throws IOException {
797 byte[] tableName = Bytes
798 .toBytes("testCreateTableWithEmptyRowInTheSplitKeys");
799 byte[][] splitKeys = new byte[3][];
800 splitKeys[0] = "region1".getBytes();
801 splitKeys[1] = HConstants.EMPTY_BYTE_ARRAY;
802 splitKeys[2] = "region2".getBytes();
803 HTableDescriptor desc = new HTableDescriptor(tableName);
804 desc.addFamily(new HColumnDescriptor("col"));
805 try {
806 admin.createTable(desc, splitKeys);
807 fail("Test case should fail as empty split key is passed.");
808 } catch (IllegalArgumentException e) {
809 }
810 }
811
812 @Test
813 public void testTableExist() throws IOException {
814 final byte [] table = Bytes.toBytes("testTableExist");
815 boolean exist = false;
816 exist = this.admin.tableExists(table);
817 assertEquals(false, exist);
818 TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
819 exist = this.admin.tableExists(table);
820 assertEquals(true, exist);
821 }
822
823
824
825
826
827
828 @Test
829 public void testForceSplit() throws Exception {
830 byte[][] familyNames = new byte[][] { Bytes.toBytes("cf") };
831 int[] rowCounts = new int[] { 6000 };
832 int numVersions = HColumnDescriptor.DEFAULT_VERSIONS;
833 int blockSize = 256;
834 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
835
836 byte[] splitKey = Bytes.toBytes(3500);
837 splitTest(splitKey, familyNames, rowCounts, numVersions, blockSize);
838 }
839
840
841
842
843
844
845 @Test
846 public void testEnableTableRoundRobinAssignment() throws IOException {
847 byte[] tableName = Bytes.toBytes("testEnableTableAssignment");
848 byte[][] splitKeys = { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 },
849 new byte[] { 3, 3, 3 }, new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 },
850 new byte[] { 6, 6, 6 }, new byte[] { 7, 7, 7 }, new byte[] { 8, 8, 8 },
851 new byte[] { 9, 9, 9 } };
852 int expectedRegions = splitKeys.length + 1;
853 HTableDescriptor desc = new HTableDescriptor(tableName);
854 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
855 admin.createTable(desc, splitKeys);
856 HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
857 Map<HRegionInfo, HServerAddress> regions = ht.getRegionsInfo();
858 assertEquals("Tried to create " + expectedRegions + " regions "
859 + "but only found " + regions.size(), expectedRegions, regions.size());
860
861 admin.disableTable(tableName);
862
863 admin.enableTable(tableName);
864
865
866 HTable metaTable = new HTable(TEST_UTIL.getConfiguration(),
867 HConstants.META_TABLE_NAME);
868 List<HRegionInfo> regionInfos = admin.getTableRegions(tableName);
869 Map<String, Integer> serverMap = new HashMap<String, Integer>();
870 for (int i = 0, j = regionInfos.size(); i < j; i++) {
871 HRegionInfo hri = regionInfos.get(i);
872 Get get = new Get(hri.getRegionName());
873 Result result = metaTable.get(get);
874 String server = Bytes.toString(result.getValue(HConstants.CATALOG_FAMILY,
875 HConstants.SERVER_QUALIFIER));
876 Integer regioncount = serverMap.get(server);
877 if (regioncount == null) {
878 regioncount = 0;
879 }
880 regioncount++;
881 serverMap.put(server, regioncount);
882 }
883 List<Map.Entry<String, Integer>> entryList = new ArrayList<Map.Entry<String, Integer>>(
884 serverMap.entrySet());
885 Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
886 public int compare(Map.Entry<String, Integer> oa,
887 Map.Entry<String, Integer> ob) {
888 return (oa.getValue() - ob.getValue());
889 }
890 });
891 assertTrue(entryList.size() == 3);
892 assertTrue((entryList.get(2).getValue() - entryList.get(0).getValue()) < 2);
893 }
894
895
896
897
898
899
900
901 @Test
902 public void testForceSplitMultiFamily() throws Exception {
903 int numVersions = HColumnDescriptor.DEFAULT_VERSIONS;
904
905
906
907
908 int blockSize = 256;
909 byte[][] familyNames = new byte[][] { Bytes.toBytes("cf1"),
910 Bytes.toBytes("cf2") };
911
912
913 int[] rowCounts = new int[] { 6000, 1 };
914 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
915
916 rowCounts = new int[] { 1, 6000 };
917 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
918
919
920
921 rowCounts = new int[] { 6000, 300 };
922 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
923
924 rowCounts = new int[] { 300, 6000 };
925 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
926
927 }
928
929 void splitTest(byte[] splitPoint, byte[][] familyNames, int[] rowCounts,
930 int numVersions, int blockSize) throws Exception {
931 byte [] tableName = Bytes.toBytes("testForceSplit");
932 assertFalse(admin.tableExists(tableName));
933 final HTable table = TEST_UTIL.createTable(tableName, familyNames,
934 numVersions, blockSize);
935 int rowCount = 0;
936 byte[] q = new byte[0];
937
938
939
940 for (int index = 0; index < familyNames.length; index++) {
941 ArrayList<Put> puts = new ArrayList<Put>(rowCounts[index]);
942 for (int i = 0; i < rowCounts[index]; i++) {
943 byte[] k = Bytes.toBytes(i);
944 Put put = new Put(k);
945 put.add(familyNames[index], q, k);
946 puts.add(put);
947 }
948 table.put(puts);
949
950 if ( rowCount < rowCounts[index] ) {
951 rowCount = rowCounts[index];
952 }
953 }
954
955
956 Map<HRegionInfo,HServerAddress> m = table.getRegionsInfo();
957 System.out.println("Initial regions (" + m.size() + "): " + m);
958 assertTrue(m.size() == 1);
959
960
961 Scan scan = new Scan();
962 ResultScanner scanner = table.getScanner(scan);
963 int rows = 0;
964 for(@SuppressWarnings("unused") Result result : scanner) {
965 rows++;
966 }
967 scanner.close();
968 assertEquals(rowCount, rows);
969
970
971 scan = new Scan();
972 scanner = table.getScanner(scan);
973
974 scanner.next();
975
976 final AtomicInteger count = new AtomicInteger(0);
977 Thread t = new Thread("CheckForSplit") {
978 public void run() {
979 for (int i = 0; i < 20; i++) {
980 try {
981 sleep(1000);
982 } catch (InterruptedException e) {
983 continue;
984 }
985
986 Map<HRegionInfo, HServerAddress> regions = null;
987 try {
988 regions = table.getRegionsInfo();
989 } catch (IOException e) {
990 e.printStackTrace();
991 }
992 if (regions == null) continue;
993 count.set(regions.size());
994 if (count.get() >= 2) break;
995 LOG.debug("Cycle waiting on split");
996 }
997 }
998 };
999 t.start();
1000
1001 this.admin.split(tableName, splitPoint);
1002 t.join();
1003
1004
1005 rows = 1;
1006 for (@SuppressWarnings("unused") Result result : scanner) {
1007 rows++;
1008 if (rows > rowCount) {
1009 scanner.close();
1010 assertTrue("Scanned more than expected (" + rowCount + ")", false);
1011 }
1012 }
1013 scanner.close();
1014 assertEquals(rowCount, rows);
1015
1016 Map<HRegionInfo, HServerAddress> regions = null;
1017 try {
1018 regions = table.getRegionsInfo();
1019 } catch (IOException e) {
1020 e.printStackTrace();
1021 }
1022 assertEquals(2, regions.size());
1023 HRegionInfo[] r = regions.keySet().toArray(new HRegionInfo[0]);
1024 if (splitPoint != null) {
1025
1026 assertEquals(Bytes.toString(splitPoint),
1027 Bytes.toString(r[0].getEndKey()));
1028 assertEquals(Bytes.toString(splitPoint),
1029 Bytes.toString(r[1].getStartKey()));
1030 LOG.debug("Properly split on " + Bytes.toString(splitPoint));
1031 } else {
1032 if (familyNames.length > 1) {
1033 int splitKey = Bytes.toInt(r[0].getEndKey());
1034
1035
1036 int deltaForLargestFamily = Math.abs(rowCount/2 - splitKey);
1037 for (int index = 0; index < familyNames.length; index++) {
1038 int delta = Math.abs(rowCounts[index]/2 - splitKey);
1039 assertTrue(delta >= deltaForLargestFamily);
1040 }
1041 }
1042 }
1043 TEST_UTIL.deleteTable(tableName);
1044 table.close();
1045 }
1046
1047
1048
1049
1050
1051 @Test (expected=IllegalArgumentException.class)
1052 public void testEmptyHHTableDescriptor() throws IOException {
1053 this.admin.createTable(new HTableDescriptor());
1054 }
1055
1056 @Test (expected=IllegalArgumentException.class)
1057 public void testInvalidHColumnDescriptor() throws IOException {
1058 new HColumnDescriptor("/cfamily/name");
1059 }
1060
1061 @Test(timeout=36000)
1062 public void testEnableDisableAddColumnDeleteColumn() throws Exception {
1063 ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(TEST_UTIL);
1064 byte [] tableName = Bytes.toBytes("testMasterAdmin");
1065 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
1066 while (!ZKTableReadOnly.isEnabledTable(zkw, "testMasterAdmin")) {
1067 Thread.sleep(10);
1068 }
1069 this.admin.disableTable(tableName);
1070 try {
1071 new HTable(TEST_UTIL.getConfiguration(), tableName);
1072 } catch (DoNotRetryIOException e) {
1073
1074 }
1075
1076 this.admin.addColumn(tableName, new HColumnDescriptor("col2"));
1077 this.admin.enableTable(tableName);
1078 try {
1079 this.admin.deleteColumn(tableName, Bytes.toBytes("col2"));
1080 } catch (TableNotDisabledException e) {
1081 LOG.info(e);
1082 }
1083 this.admin.disableTable(tableName);
1084 this.admin.deleteTable(tableName);
1085 }
1086
1087 @Test
1088 public void testCreateBadTables() throws IOException {
1089 String msg = null;
1090 try {
1091 this.admin.createTable(HTableDescriptor.ROOT_TABLEDESC);
1092 } catch (IllegalArgumentException e) {
1093 msg = e.toString();
1094 }
1095 assertTrue("Unexcepted exception message " + msg, msg != null &&
1096 msg.startsWith(IllegalArgumentException.class.getName()) &&
1097 msg.contains(HTableDescriptor.ROOT_TABLEDESC.getNameAsString()));
1098 msg = null;
1099 try {
1100 this.admin.createTable(HTableDescriptor.META_TABLEDESC);
1101 } catch(IllegalArgumentException e) {
1102 msg = e.toString();
1103 }
1104 assertTrue("Unexcepted exception message " + msg, msg != null &&
1105 msg.startsWith(IllegalArgumentException.class.getName()) &&
1106 msg.contains(HTableDescriptor.META_TABLEDESC.getNameAsString()));
1107
1108
1109 final HTableDescriptor threadDesc =
1110 new HTableDescriptor("threaded_testCreateBadTables");
1111 threadDesc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
1112 int count = 10;
1113 Thread [] threads = new Thread [count];
1114 final AtomicInteger successes = new AtomicInteger(0);
1115 final AtomicInteger failures = new AtomicInteger(0);
1116 final HBaseAdmin localAdmin = this.admin;
1117 for (int i = 0; i < count; i++) {
1118 threads[i] = new Thread(Integer.toString(i)) {
1119 @Override
1120 public void run() {
1121 try {
1122 localAdmin.createTable(threadDesc);
1123 successes.incrementAndGet();
1124 } catch (TableExistsException e) {
1125 failures.incrementAndGet();
1126 } catch (IOException e) {
1127 throw new RuntimeException("Failed threaded create" + getName(), e);
1128 }
1129 }
1130 };
1131 }
1132 for (int i = 0; i < count; i++) {
1133 threads[i].start();
1134 }
1135 for (int i = 0; i < count; i++) {
1136 while(threads[i].isAlive()) {
1137 try {
1138 Thread.sleep(100);
1139 } catch (InterruptedException e) {
1140
1141 }
1142 }
1143 }
1144
1145
1146 assertEquals(1, successes.get());
1147 assertEquals(count - 1, failures.get());
1148 }
1149
1150
1151
1152
1153
1154 @Test
1155 public void testTableNameClash() throws Exception {
1156 String name = "testTableNameClash";
1157 admin.createTable(new HTableDescriptor(name + "SOMEUPPERCASE"));
1158 admin.createTable(new HTableDescriptor(name));
1159
1160 new HTable(TEST_UTIL.getConfiguration(), name).close();
1161 }
1162
1163
1164
1165
1166
1167
1168
1169
1170 @Test
1171 public void testCreateTableRPCTimeOut() throws Exception {
1172 String name = "testCreateTableRPCTimeOut";
1173 int oldTimeout = TEST_UTIL.getConfiguration().
1174 getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
1175 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500);
1176 try {
1177 int expectedRegions = 100;
1178
1179 byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
1180 byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
1181 HBaseAdmin hbaseadmin = new HBaseAdmin(TEST_UTIL.getConfiguration());
1182 hbaseadmin.createTable(new HTableDescriptor(name), startKey, endKey,
1183 expectedRegions);
1184 hbaseadmin.close();
1185 } finally {
1186 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, oldTimeout);
1187 }
1188 }
1189
1190
1191
1192
1193
1194 @Test
1195 public void testReadOnlyTable() throws Exception {
1196 byte [] name = Bytes.toBytes("testReadOnlyTable");
1197 HTable table = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1198 byte[] value = Bytes.toBytes("somedata");
1199
1200 Put put = new Put(value);
1201 put.add(HConstants.CATALOG_FAMILY, HConstants.CATALOG_FAMILY, value);
1202 table.put(put);
1203 table.close();
1204 }
1205
1206
1207
1208
1209
1210
1211 @Test
1212 public void testTableNames() throws IOException {
1213 byte[][] illegalNames = new byte[][] {
1214 Bytes.toBytes("-bad"),
1215 Bytes.toBytes(".bad"),
1216 HConstants.ROOT_TABLE_NAME,
1217 HConstants.META_TABLE_NAME
1218 };
1219 for (int i = 0; i < illegalNames.length; i++) {
1220 try {
1221 new HTableDescriptor(illegalNames[i]);
1222 throw new IOException("Did not detect '" +
1223 Bytes.toString(illegalNames[i]) + "' as an illegal user table name");
1224 } catch (IllegalArgumentException e) {
1225
1226 }
1227 }
1228 byte[] legalName = Bytes.toBytes("g-oo.d");
1229 try {
1230 new HTableDescriptor(legalName);
1231 } catch (IllegalArgumentException e) {
1232 throw new IOException("Legal user table name: '" +
1233 Bytes.toString(legalName) + "' caused IllegalArgumentException: " +
1234 e.getMessage());
1235 }
1236 }
1237
1238
1239
1240
1241
1242 @Test (expected=TableExistsException.class)
1243 public void testTableExistsExceptionWithATable() throws IOException {
1244 final byte [] name = Bytes.toBytes("testTableExistsExceptionWithATable");
1245 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
1246 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1247 }
1248
1249
1250
1251
1252
1253 @Test (expected=TableNotEnabledException.class)
1254 public void testTableNotEnabledExceptionWithATable() throws IOException {
1255 final byte [] name = Bytes.toBytes(
1256 "testTableNotEnabledExceptionWithATable");
1257 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
1258 this.admin.disableTable(name);
1259 this.admin.disableTable(name);
1260 }
1261
1262
1263
1264
1265
1266 @Test (expected=TableNotDisabledException.class)
1267 public void testTableNotDisabledExceptionWithATable() throws IOException {
1268 final byte [] name = Bytes.toBytes(
1269 "testTableNotDisabledExceptionWithATable");
1270 HTable t = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1271 try {
1272 this.admin.enableTable(name);
1273 }finally {
1274 t.close();
1275 }
1276 }
1277
1278
1279
1280
1281
1282 @Test (expected=TableNotFoundException.class)
1283 public void testTableNotFoundExceptionWithoutAnyTables() throws IOException {
1284 new HTable(TEST_UTIL.getConfiguration(),
1285 "testTableNotFoundExceptionWithoutAnyTables");
1286 }
1287 @Test
1288 public void testShouldCloseTheRegionBasedOnTheEncodedRegionName()
1289 throws Exception {
1290 byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion");
1291 createTableWithDefaultConf(TABLENAME);
1292
1293 HRegionInfo info = null;
1294 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1295 List<HRegionInfo> onlineRegions = rs.getOnlineRegions();
1296 for (HRegionInfo regionInfo : onlineRegions) {
1297 if (!regionInfo.isMetaTable()) {
1298 info = regionInfo;
1299 admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), rs
1300 .getServerName().getServerName());
1301 }
1302 }
1303 Thread.sleep(1000);
1304 onlineRegions = rs.getOnlineRegions();
1305 assertFalse("The region should not be present in online regions list.",
1306 onlineRegions.contains(info));
1307 }
1308
1309 @Test
1310 public void testCloseRegionIfInvalidRegionNameIsPassed() throws Exception {
1311 byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion1");
1312 createTableWithDefaultConf(TABLENAME);
1313
1314 HRegionInfo info = null;
1315 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1316 List<HRegionInfo> onlineRegions = rs.getOnlineRegions();
1317 for (HRegionInfo regionInfo : onlineRegions) {
1318 if (!regionInfo.isMetaTable()) {
1319 if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion1")) {
1320 info = regionInfo;
1321 admin.closeRegionWithEncodedRegionName("sample", rs.getServerName()
1322 .getServerName());
1323 }
1324 }
1325 }
1326 onlineRegions = rs.getOnlineRegions();
1327 assertTrue("The region should be present in online regions list.",
1328 onlineRegions.contains(info));
1329 }
1330
1331 @Test
1332 public void testCloseRegionThatFetchesTheHRIFromMeta() throws Exception {
1333 byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion2");
1334 createTableWithDefaultConf(TABLENAME);
1335
1336 HRegionInfo info = null;
1337 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1338 List<HRegionInfo> onlineRegions = rs.getOnlineRegions();
1339 for (HRegionInfo regionInfo : onlineRegions) {
1340 if (!regionInfo.isMetaTable()) {
1341
1342 if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion2")) {
1343 info = regionInfo;
1344 admin.closeRegion(regionInfo.getRegionNameAsString(), rs
1345 .getServerName().getServerName());
1346 }
1347 }
1348 }
1349
1350 boolean isInList = rs.getOnlineRegions().contains(info);
1351 long timeout = System.currentTimeMillis() + 2000;
1352 while ((System.currentTimeMillis() < timeout) && (isInList)) {
1353 Thread.sleep(100);
1354 isInList = rs.getOnlineRegions().contains(info);
1355 }
1356
1357 assertFalse("The region should not be present in online regions list.",
1358 isInList);
1359 }
1360
1361 @Test
1362 public void testCloseRegionWhenServerNameIsNull() throws Exception {
1363 byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion3");
1364 createTableWithDefaultConf(TABLENAME);
1365
1366 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1367
1368 try {
1369 List<HRegionInfo> onlineRegions = rs.getOnlineRegions();
1370 for (HRegionInfo regionInfo : onlineRegions) {
1371 if (!regionInfo.isMetaTable()) {
1372 if (regionInfo.getRegionNameAsString()
1373 .contains("TestHBACloseRegion3")) {
1374 admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(),
1375 null);
1376 }
1377 }
1378 }
1379 fail("The test should throw exception if the servername passed is null.");
1380 } catch (IllegalArgumentException e) {
1381 }
1382 }
1383
1384
1385 @Test
1386 public void testCloseRegionWhenServerNameIsEmpty() throws Exception {
1387 byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegionWhenServerNameIsEmpty");
1388 createTableWithDefaultConf(TABLENAME);
1389
1390 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1391
1392 try {
1393 List<HRegionInfo> onlineRegions = rs.getOnlineRegions();
1394 for (HRegionInfo regionInfo : onlineRegions) {
1395 if (!regionInfo.isMetaTable()) {
1396 if (regionInfo.getRegionNameAsString()
1397 .contains("TestHBACloseRegionWhenServerNameIsEmpty")) {
1398 admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(),
1399 " ");
1400 }
1401 }
1402 }
1403 fail("The test should throw exception if the servername passed is empty.");
1404 } catch (IllegalArgumentException e) {
1405 }
1406 }
1407
1408 @Test
1409 public void testCloseRegionWhenEncodedRegionNameIsNotGiven() throws Exception {
1410 byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion4");
1411 createTableWithDefaultConf(TABLENAME);
1412
1413 HRegionInfo info = null;
1414 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1415
1416 List<HRegionInfo> onlineRegions = rs.getOnlineRegions();
1417 for (HRegionInfo regionInfo : onlineRegions) {
1418 if (!regionInfo.isMetaTable()) {
1419 if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion4")) {
1420 info = regionInfo;
1421 admin.closeRegionWithEncodedRegionName(regionInfo
1422 .getRegionNameAsString(), rs.getServerName().getServerName());
1423 }
1424 }
1425 }
1426 onlineRegions = rs.getOnlineRegions();
1427 assertTrue("The region should be present in online regions list.",
1428 onlineRegions.contains(info));
1429 }
1430
1431 private HBaseAdmin createTable(byte[] TABLENAME) throws IOException {
1432
1433 Configuration config = TEST_UTIL.getConfiguration();
1434 HBaseAdmin admin = new HBaseAdmin(config);
1435
1436 HTableDescriptor htd = new HTableDescriptor(TABLENAME);
1437 HColumnDescriptor hcd = new HColumnDescriptor("value");
1438
1439 htd.addFamily(hcd);
1440 admin.createTable(htd, null);
1441 return admin;
1442 }
1443
1444 private void createTableWithDefaultConf(byte[] TABLENAME) throws IOException {
1445 HTableDescriptor htd = new HTableDescriptor(TABLENAME);
1446 HColumnDescriptor hcd = new HColumnDescriptor("value");
1447 htd.addFamily(hcd);
1448
1449 admin.createTable(htd, null);
1450 }
1451
1452
1453
1454
1455
1456 @Test
1457 public void testGetTableRegions() throws IOException {
1458
1459 byte[] tableName = Bytes.toBytes("testGetTableRegions");
1460
1461 int expectedRegions = 10;
1462
1463
1464 byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
1465 byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
1466
1467
1468 HTableDescriptor desc = new HTableDescriptor(tableName);
1469 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
1470 admin.createTable(desc, startKey, endKey, expectedRegions);
1471
1472 List<HRegionInfo> RegionInfos = admin.getTableRegions(tableName);
1473
1474 assertEquals("Tried to create " + expectedRegions + " regions " +
1475 "but only found " + RegionInfos.size(),
1476 expectedRegions, RegionInfos.size());
1477
1478 }
1479
1480 @Test
1481 public void testHLogRollWriting() throws Exception {
1482 setUpforLogRolling();
1483 String className = this.getClass().getName();
1484 StringBuilder v = new StringBuilder(className);
1485 while (v.length() < 1000) {
1486 v.append(className);
1487 }
1488 byte[] value = Bytes.toBytes(v.toString());
1489 HRegionServer regionServer = startAndWriteData("TestLogRolling", value);
1490 LOG.info("after writing there are "
1491 + HLogUtilsForTests.getNumLogFiles(regionServer.getWAL()) + " log files");
1492
1493
1494
1495 List<HRegion> regions = new ArrayList<HRegion>(regionServer
1496 .getOnlineRegionsLocalContext());
1497 for (HRegion r : regions) {
1498 r.flushcache();
1499 }
1500 admin.rollHLogWriter(regionServer.getServerName().getServerName());
1501 int count = HLogUtilsForTests.getNumLogFiles(regionServer.getWAL());
1502 LOG.info("after flushing all regions and rolling logs there are " +
1503 count + " log files");
1504 assertTrue(("actual count: " + count), count <= 2);
1505 }
1506
1507 private void setUpforLogRolling() {
1508
1509 TEST_UTIL.getConfiguration().setLong(HConstants.HREGION_MAX_FILESIZE,
1510 768L * 1024L);
1511
1512
1513 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.maxlogentries", 32);
1514
1515 TEST_UTIL.getConfiguration().setInt(
1516 "hbase.regionserver.logroll.errors.tolerated", 2);
1517 TEST_UTIL.getConfiguration().setInt("ipc.ping.interval", 10 * 1000);
1518 TEST_UTIL.getConfiguration().setInt("ipc.socket.timeout", 10 * 1000);
1519 TEST_UTIL.getConfiguration().setInt("hbase.rpc.timeout", 10 * 1000);
1520
1521
1522 TEST_UTIL.getConfiguration().setInt(
1523 "hbase.hregion.memstore.optionalflushcount", 2);
1524
1525
1526 TEST_UTIL.getConfiguration().setInt(HConstants.HREGION_MEMSTORE_FLUSH_SIZE,
1527 8192);
1528
1529
1530 TEST_UTIL.getConfiguration().setLong("hbase.client.pause", 10 * 1000);
1531
1532
1533
1534 TEST_UTIL.getConfiguration().setInt(HConstants.THREAD_WAKE_FREQUENCY,
1535 2 * 1000);
1536
1537
1538
1539 TEST_UTIL.getConfiguration().setBoolean("dfs.support.append", true);
1540
1541
1542 TEST_UTIL.getConfiguration().setInt("heartbeat.recheck.interval", 5000);
1543 TEST_UTIL.getConfiguration().setInt("dfs.heartbeat.interval", 1);
1544
1545
1546 TEST_UTIL.getConfiguration().setInt("dfs.client.block.write.retries", 30);
1547 TEST_UTIL.getConfiguration().setInt(
1548 "hbase.regionserver.hlog.tolerable.lowreplication", 2);
1549 TEST_UTIL.getConfiguration().setInt(
1550 "hbase.regionserver.hlog.lowreplication.rolllimit", 3);
1551 }
1552
1553 private HRegionServer startAndWriteData(String tableName, byte[] value)
1554 throws IOException {
1555
1556 new HTable(
1557 TEST_UTIL.getConfiguration(), HConstants.META_TABLE_NAME).close();
1558 HRegionServer regionServer = TEST_UTIL.getHBaseCluster()
1559 .getRegionServerThreads().get(0).getRegionServer();
1560
1561
1562 HTableDescriptor desc = new HTableDescriptor(tableName);
1563 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
1564 admin.createTable(desc);
1565 HTable table = new HTable(TEST_UTIL.getConfiguration(), tableName);
1566
1567 regionServer = TEST_UTIL.getRSForFirstRegionInTable(Bytes
1568 .toBytes(tableName));
1569 for (int i = 1; i <= 256; i++) {
1570 Put put = new Put(Bytes.toBytes("row" + String.format("%1$04d", i)));
1571 put.add(HConstants.CATALOG_FAMILY, null, value);
1572 table.put(put);
1573 if (i % 32 == 0) {
1574
1575 try {
1576 Thread.sleep(2000);
1577 } catch (InterruptedException e) {
1578
1579 }
1580 }
1581 }
1582
1583 table.close();
1584 return regionServer;
1585 }
1586
1587
1588
1589
1590 @Test
1591 public void testCheckHBaseAvailableClosesConnection() throws Exception {
1592 Configuration conf = TEST_UTIL.getConfiguration();
1593
1594 int initialCount = HConnectionTestingUtility.getConnectionCount();
1595 HBaseAdmin.checkHBaseAvailable(conf);
1596 int finalCount = HConnectionTestingUtility.getConnectionCount();
1597
1598 Assert.assertEquals(initialCount, finalCount) ;
1599 }
1600
1601 @Test
1602 public void testDisableCatalogTable() throws Exception {
1603 try {
1604 this.admin.disableTable(".META.");
1605 fail("Expected to throw IllegalArgumentException");
1606 } catch (IllegalArgumentException e) {
1607 }
1608
1609
1610 HTableDescriptor htd = new HTableDescriptor("testDisableCatalogTable".getBytes());
1611 HColumnDescriptor hcd = new HColumnDescriptor("cf1".getBytes());
1612 htd.addFamily(hcd);
1613 TEST_UTIL.getHBaseAdmin().createTable(htd);
1614 }
1615
1616 @Test
1617 public void testGetRegion() throws Exception {
1618 final String name = "testGetRegion";
1619 LOG.info("Started " + name);
1620 final byte [] nameBytes = Bytes.toBytes(name);
1621 HTable t = TEST_UTIL.createTable(nameBytes, HConstants.CATALOG_FAMILY);
1622 TEST_UTIL.createMultiRegions(t, HConstants.CATALOG_FAMILY);
1623 CatalogTracker ct = new CatalogTracker(TEST_UTIL.getConfiguration());
1624 ct.start();
1625 try {
1626 HRegionLocation regionLocation = t.getRegionLocation("mmm");
1627 HRegionInfo region = regionLocation.getRegionInfo();
1628 byte[] regionName = region.getRegionName();
1629 Pair<HRegionInfo, ServerName> pair = admin.getRegion(regionName, ct);
1630 assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
1631 pair = admin.getRegion(region.getEncodedNameAsBytes(), ct);
1632 assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
1633 } finally {
1634 ct.stop();
1635 }
1636 }
1637
1638 @Test
1639 public void testRootTableSplit() throws Exception {
1640 Scan s = new Scan();
1641 HTable rootTable = new HTable(TEST_UTIL.getConfiguration(), HConstants.ROOT_TABLE_NAME);
1642 ResultScanner scanner = rootTable.getScanner(s);
1643 Result metaEntry = scanner.next();
1644 this.admin.split(HConstants.ROOT_TABLE_NAME, metaEntry.getRow());
1645 Thread.sleep(1000);
1646 List<HRegion> regions = TEST_UTIL.getMiniHBaseCluster().getRegions(HConstants.ROOT_TABLE_NAME);
1647 assertEquals("ROOT region should not be splitted.",1, regions.size());
1648 }
1649
1650 @org.junit.Rule
1651 public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
1652 new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
1653 }