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