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