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