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