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