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