1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.client;
20
21
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26
27 import java.io.IOException;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.Comparator;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.concurrent.atomic.AtomicBoolean;
37 import java.util.concurrent.atomic.AtomicInteger;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.hadoop.conf.Configuration;
42 import org.apache.hadoop.hbase.HBaseTestingUtility;
43 import org.apache.hadoop.hbase.HColumnDescriptor;
44 import org.apache.hadoop.hbase.HConstants;
45 import org.apache.hadoop.hbase.HRegionInfo;
46 import org.apache.hadoop.hbase.HRegionLocation;
47 import org.apache.hadoop.hbase.HTableDescriptor;
48 import org.apache.hadoop.hbase.InvalidFamilyOperationException;
49 import org.apache.hadoop.hbase.LargeTests;
50 import org.apache.hadoop.hbase.MasterNotRunningException;
51 import org.apache.hadoop.hbase.MiniHBaseCluster;
52 import org.apache.hadoop.hbase.NotServingRegionException;
53 import org.apache.hadoop.hbase.ServerName;
54 import org.apache.hadoop.hbase.TableExistsException;
55 import org.apache.hadoop.hbase.TableName;
56 import org.apache.hadoop.hbase.TableNotDisabledException;
57 import org.apache.hadoop.hbase.TableNotEnabledException;
58 import org.apache.hadoop.hbase.TableNotFoundException;
59 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
60 import org.apache.hadoop.hbase.catalog.CatalogTracker;
61 import org.apache.hadoop.hbase.constraint.ConstraintException;
62 import org.apache.hadoop.hbase.executor.EventHandler;
63 import org.apache.hadoop.hbase.master.AssignmentManager;
64 import org.apache.hadoop.hbase.master.HMaster;
65 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
66 import org.apache.hadoop.hbase.regionserver.HRegion;
67 import org.apache.hadoop.hbase.regionserver.HRegionServer;
68 import org.apache.hadoop.hbase.regionserver.wal.HLogUtilsForTests;
69 import org.apache.hadoop.hbase.util.Bytes;
70 import org.apache.hadoop.hbase.util.Pair;
71 import org.apache.hadoop.hbase.zookeeper.ZKTableReadOnly;
72 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
73 import org.junit.*;
74 import org.junit.experimental.categories.Category;
75
76 import com.google.protobuf.ServiceException;
77
78
79
80
81
82
83
84 @Category(LargeTests.class)
85 public class TestAdmin {
86 final Log LOG = LogFactory.getLog(getClass());
87 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
88 private HBaseAdmin admin;
89
90 @BeforeClass
91 public static void setUpBeforeClass() throws Exception {
92 TEST_UTIL.getConfiguration().setBoolean("hbase.online.schema.update.enable", true);
93 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
94 TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
95 TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 6);
96 TEST_UTIL.getConfiguration().setBoolean(
97 "hbase.master.enabletable.roundrobin", true);
98 TEST_UTIL.startMiniCluster(3);
99 }
100
101 @AfterClass
102 public static void tearDownAfterClass() throws Exception {
103 TEST_UTIL.shutdownMiniCluster();
104 }
105
106 @Before
107 public void setUp() throws Exception {
108 this.admin = TEST_UTIL.getHBaseAdmin();
109 }
110
111 @After
112 public void tearDown() throws Exception {
113 }
114
115 @Test (timeout=300000)
116 public void testSplitFlushCompactUnknownTable() throws InterruptedException {
117 final String unknowntable = "fubar";
118 Exception exception = null;
119 try {
120 this.admin.compact(unknowntable);
121 } catch (IOException e) {
122 exception = e;
123 }
124 assertTrue(exception instanceof TableNotFoundException);
125
126 exception = null;
127 try {
128 this.admin.flush(unknowntable);
129 } catch (IOException e) {
130 exception = e;
131 }
132 assertTrue(exception instanceof TableNotFoundException);
133
134 exception = null;
135 try {
136 this.admin.split(unknowntable);
137 } catch (IOException e) {
138 exception = e;
139 }
140 assertTrue(exception instanceof TableNotFoundException);
141 }
142
143 @Test (timeout=300000)
144 public void testDeleteEditUnknownColumnFamilyAndOrTable() throws IOException {
145
146 final String nonexistent = "nonexistent";
147 HColumnDescriptor nonexistentHcd = new HColumnDescriptor(nonexistent);
148 Exception exception = null;
149 try {
150 this.admin.addColumn(nonexistent, nonexistentHcd);
151 } catch (IOException e) {
152 exception = e;
153 }
154 assertTrue(exception instanceof TableNotFoundException);
155
156 exception = null;
157 try {
158 this.admin.deleteTable(nonexistent);
159 } catch (IOException e) {
160 exception = e;
161 }
162 assertTrue(exception instanceof TableNotFoundException);
163
164 exception = null;
165 try {
166 this.admin.deleteColumn(nonexistent, nonexistent);
167 } catch (IOException e) {
168 exception = e;
169 }
170 assertTrue(exception instanceof TableNotFoundException);
171
172 exception = null;
173 try {
174 this.admin.disableTable(nonexistent);
175 } catch (IOException e) {
176 exception = e;
177 }
178 assertTrue(exception instanceof TableNotFoundException);
179
180 exception = null;
181 try {
182 this.admin.enableTable(nonexistent);
183 } catch (IOException e) {
184 exception = e;
185 }
186 assertTrue(exception instanceof TableNotFoundException);
187
188 exception = null;
189 try {
190 this.admin.modifyColumn(nonexistent, nonexistentHcd);
191 } catch (IOException e) {
192 exception = e;
193 }
194 assertTrue(exception instanceof TableNotFoundException);
195
196 exception = null;
197 try {
198 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(nonexistent));
199 this.admin.modifyTable(htd.getTableName(), htd);
200 } catch (IOException e) {
201 exception = e;
202 }
203 assertTrue(exception instanceof TableNotFoundException);
204
205
206
207 final String tableName =
208 "testDeleteEditUnknownColumnFamilyAndOrTable" + System.currentTimeMillis();
209 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName));
210 htd.addFamily(new HColumnDescriptor("cf"));
211 this.admin.createTable(htd);
212 try {
213 exception = null;
214 try {
215 this.admin.deleteColumn(htd.getTableName(), nonexistentHcd.getName());
216 } catch (IOException e) {
217 exception = e;
218 }
219 assertTrue("found=" + exception.getClass().getName(),
220 exception instanceof InvalidFamilyOperationException);
221
222 exception = null;
223 try {
224 this.admin.modifyColumn(htd.getTableName(), nonexistentHcd);
225 } catch (IOException e) {
226 exception = e;
227 }
228 assertTrue("found=" + exception.getClass().getName(),
229 exception instanceof InvalidFamilyOperationException);
230 } finally {
231 this.admin.disableTable(tableName);
232 this.admin.deleteTable(tableName);
233 }
234 }
235
236 @Test (timeout=300000)
237 public void testDisableAndEnableTable() throws IOException {
238 final byte [] row = Bytes.toBytes("row");
239 final byte [] qualifier = Bytes.toBytes("qualifier");
240 final byte [] value = Bytes.toBytes("value");
241 final byte [] table = Bytes.toBytes("testDisableAndEnableTable");
242 HTable ht = TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
243 Put put = new Put(row);
244 put.add(HConstants.CATALOG_FAMILY, qualifier, value);
245 ht.put(put);
246 Get get = new Get(row);
247 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
248 ht.get(get);
249
250 this.admin.disableTable(ht.getName());
251 assertTrue("Table must be disabled.", TEST_UTIL.getHBaseCluster()
252 .getMaster().getAssignmentManager().getZKTable().isDisabledTable(
253 ht.getName()));
254
255
256 get = new Get(row);
257 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
258 boolean ok = false;
259 try {
260 ht.get(get);
261 } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
262 ok = true;
263 }
264 assertTrue(ok);
265 this.admin.enableTable(table);
266 assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster()
267 .getMaster().getAssignmentManager().getZKTable().isEnabledTable(
268 ht.getName()));
269
270
271 try {
272 ht.get(get);
273 } catch (RetriesExhaustedException e) {
274 ok = false;
275 }
276 assertTrue(ok);
277 ht.close();
278 }
279
280 @Test (timeout=300000)
281 public void testDisableAndEnableTables() throws IOException {
282 final byte [] row = Bytes.toBytes("row");
283 final byte [] qualifier = Bytes.toBytes("qualifier");
284 final byte [] value = Bytes.toBytes("value");
285 final byte [] table1 = Bytes.toBytes("testDisableAndEnableTable1");
286 final byte [] table2 = Bytes.toBytes("testDisableAndEnableTable2");
287 HTable ht1 = TEST_UTIL.createTable(table1, HConstants.CATALOG_FAMILY);
288 HTable ht2 = TEST_UTIL.createTable(table2, HConstants.CATALOG_FAMILY);
289 Put put = new Put(row);
290 put.add(HConstants.CATALOG_FAMILY, qualifier, value);
291 ht1.put(put);
292 ht2.put(put);
293 Get get = new Get(row);
294 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
295 ht1.get(get);
296 ht2.get(get);
297
298 this.admin.disableTables("testDisableAndEnableTable.*");
299
300
301 get = new Get(row);
302 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
303 boolean ok = false;
304 try {
305 ht1.get(get);
306 ht2.get(get);
307 } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
308 ok = true;
309 }
310
311 assertTrue(ok);
312 this.admin.enableTables("testDisableAndEnableTable.*");
313
314
315 try {
316 ht1.get(get);
317 } catch (IOException e) {
318 ok = false;
319 }
320 try {
321 ht2.get(get);
322 } catch (IOException e) {
323 ok = false;
324 }
325 assertTrue(ok);
326
327 ht1.close();
328 ht2.close();
329 }
330
331 @Test (timeout=300000)
332 public void testCreateTable() throws IOException {
333 HTableDescriptor [] tables = admin.listTables();
334 int numTables = tables.length;
335 TEST_UTIL.createTable(Bytes.toBytes("testCreateTable"),
336 HConstants.CATALOG_FAMILY).close();
337 tables = this.admin.listTables();
338 assertEquals(numTables + 1, tables.length);
339 assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster()
340 .getMaster().getAssignmentManager().getZKTable().isEnabledTable(
341 TableName.valueOf("testCreateTable")));
342 }
343
344 @Test (timeout=300000)
345 public void testGetTableDescriptor() throws IOException {
346 HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
347 HColumnDescriptor fam2 = new HColumnDescriptor("fam2");
348 HColumnDescriptor fam3 = new HColumnDescriptor("fam3");
349 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("myTestTable"));
350 htd.addFamily(fam1);
351 htd.addFamily(fam2);
352 htd.addFamily(fam3);
353 this.admin.createTable(htd);
354 HTable table = new HTable(TEST_UTIL.getConfiguration(), "myTestTable");
355 HTableDescriptor confirmedHtd = table.getTableDescriptor();
356 assertEquals(htd.compareTo(confirmedHtd), 0);
357 table.close();
358 }
359
360 @Test (timeout=300000)
361 public void testHColumnValidName() {
362 boolean exceptionThrown;
363 try {
364 new HColumnDescriptor("\\test\\abc");
365 } catch(IllegalArgumentException iae) {
366 exceptionThrown = true;
367 assertTrue(exceptionThrown);
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 testEnableTableRoundRobinAssignment() 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
875
876 HTable metaTable = new HTable(TEST_UTIL.getConfiguration(),
877 TableName.META_TABLE_NAME);
878 List<HRegionInfo> regionInfos = admin.getTableRegions(tableName);
879 Map<String, Integer> serverMap = new HashMap<String, Integer>();
880 for (HRegionInfo hri : regionInfos) {
881 Get get = new Get(hri.getRegionName());
882 Result result = metaTable.get(get);
883 String server = Bytes.toString(result.getValue(HConstants.CATALOG_FAMILY,
884 HConstants.SERVER_QUALIFIER));
885 Integer regioncount = serverMap.get(server);
886 if (regioncount == null) {
887 regioncount = 0;
888 }
889 regioncount++;
890 serverMap.put(server, regioncount);
891 }
892 metaTable.close();
893 List<Map.Entry<String, Integer>> entryList = new ArrayList<Map.Entry<String, Integer>>(
894 serverMap.entrySet());
895 Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
896 public int compare(Map.Entry<String, Integer> oa,
897 Map.Entry<String, Integer> ob) {
898 return (oa.getValue() - ob.getValue());
899 }
900 });
901 assertTrue(entryList.size() == 3);
902 assertTrue((entryList.get(2).getValue() - entryList.get(0).getValue()) < 2);
903 }
904
905
906
907
908
909
910
911 @Test (timeout=300000)
912 public void testForceSplitMultiFamily() throws Exception {
913 int numVersions = HColumnDescriptor.DEFAULT_VERSIONS;
914
915
916
917
918 int blockSize = 256;
919 byte[][] familyNames = new byte[][] { Bytes.toBytes("cf1"),
920 Bytes.toBytes("cf2") };
921
922
923 int[] rowCounts = new int[] { 6000, 1 };
924 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
925
926 rowCounts = new int[] { 1, 6000 };
927 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
928
929
930
931 rowCounts = new int[] { 6000, 300 };
932 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
933
934 rowCounts = new int[] { 300, 6000 };
935 splitTest(null, familyNames, rowCounts, numVersions, blockSize);
936
937 }
938
939 void splitTest(byte[] splitPoint, byte[][] familyNames, int[] rowCounts,
940 int numVersions, int blockSize) throws Exception {
941 TableName tableName = TableName.valueOf("testForceSplit");
942 StringBuilder sb = new StringBuilder();
943
944 for (int i = 0; i < rowCounts.length; i++) {
945 sb.append("_").append(Integer.toString(rowCounts[i]));
946 }
947 assertFalse(admin.tableExists(tableName));
948 final HTable table = TEST_UTIL.createTable(tableName, familyNames,
949 numVersions, blockSize);
950
951 int rowCount = 0;
952 byte[] q = new byte[0];
953
954
955
956 for (int index = 0; index < familyNames.length; index++) {
957 ArrayList<Put> puts = new ArrayList<Put>(rowCounts[index]);
958 for (int i = 0; i < rowCounts[index]; i++) {
959 byte[] k = Bytes.toBytes(i);
960 Put put = new Put(k);
961 put.add(familyNames[index], q, k);
962 puts.add(put);
963 }
964 table.put(puts);
965
966 if ( rowCount < rowCounts[index] ) {
967 rowCount = rowCounts[index];
968 }
969 }
970
971
972 Map<HRegionInfo, ServerName> m = table.getRegionLocations();
973 LOG.info("Initial regions (" + m.size() + "): " + m);
974 assertTrue(m.size() == 1);
975
976
977 Scan scan = new Scan();
978 ResultScanner scanner = table.getScanner(scan);
979 int rows = 0;
980 for(@SuppressWarnings("unused") Result result : scanner) {
981 rows++;
982 }
983 scanner.close();
984 assertEquals(rowCount, rows);
985
986
987 scan = new Scan();
988 scanner = table.getScanner(scan);
989
990 scanner.next();
991
992
993 this.admin.split(tableName.getName(), splitPoint);
994
995 final AtomicInteger count = new AtomicInteger(0);
996 Thread t = new Thread("CheckForSplit") {
997 public void run() {
998 for (int i = 0; i < 20; i++) {
999 try {
1000 sleep(1000);
1001 } catch (InterruptedException e) {
1002 continue;
1003 }
1004
1005 Map<HRegionInfo, ServerName> regions = null;
1006 try {
1007 regions = table.getRegionLocations();
1008 } catch (IOException e) {
1009 e.printStackTrace();
1010 }
1011 if (regions == null) continue;
1012 count.set(regions.size());
1013 if (count.get() >= 2) {
1014 LOG.info("Found: " + regions);
1015 break;
1016 }
1017 LOG.debug("Cycle waiting on split");
1018 }
1019 LOG.debug("CheckForSplit thread exited, current region count: " + count.get());
1020 }
1021 };
1022 t.setPriority(Thread.NORM_PRIORITY - 2);
1023 t.start();
1024 t.join();
1025
1026
1027 rows = 1;
1028 for (@SuppressWarnings("unused") Result result : scanner) {
1029 rows++;
1030 if (rows > rowCount) {
1031 scanner.close();
1032 assertTrue("Scanned more than expected (" + rowCount + ")", false);
1033 }
1034 }
1035 scanner.close();
1036 assertEquals(rowCount, rows);
1037
1038 Map<HRegionInfo, ServerName> regions = null;
1039 try {
1040 regions = table.getRegionLocations();
1041 } catch (IOException e) {
1042 e.printStackTrace();
1043 }
1044 assertEquals(2, regions.size());
1045 Set<HRegionInfo> hRegionInfos = regions.keySet();
1046 HRegionInfo[] r = hRegionInfos.toArray(new HRegionInfo[hRegionInfos.size()]);
1047 if (splitPoint != null) {
1048
1049 assertEquals(Bytes.toString(splitPoint),
1050 Bytes.toString(r[0].getEndKey()));
1051 assertEquals(Bytes.toString(splitPoint),
1052 Bytes.toString(r[1].getStartKey()));
1053 LOG.debug("Properly split on " + Bytes.toString(splitPoint));
1054 } else {
1055 if (familyNames.length > 1) {
1056 int splitKey = Bytes.toInt(r[0].getEndKey());
1057
1058
1059 int deltaForLargestFamily = Math.abs(rowCount/2 - splitKey);
1060 LOG.debug("SplitKey=" + splitKey + "&deltaForLargestFamily=" + deltaForLargestFamily +
1061 ", r=" + r[0]);
1062 for (int index = 0; index < familyNames.length; index++) {
1063 int delta = Math.abs(rowCounts[index]/2 - splitKey);
1064 if (delta < deltaForLargestFamily) {
1065 assertTrue("Delta " + delta + " for family " + index
1066 + " should be at least deltaForLargestFamily " + deltaForLargestFamily,
1067 false);
1068 }
1069 }
1070 }
1071 }
1072 TEST_UTIL.deleteTable(tableName);
1073 table.close();
1074 }
1075
1076
1077
1078
1079
1080 @SuppressWarnings("deprecation")
1081 @Test (expected=IllegalArgumentException.class, timeout=300000)
1082 public void testEmptyHTableDescriptor() throws IOException {
1083 this.admin.createTable(new HTableDescriptor());
1084 }
1085
1086 @Test (expected=IllegalArgumentException.class, timeout=300000)
1087 public void testInvalidHColumnDescriptor() throws IOException {
1088 new HColumnDescriptor("/cfamily/name");
1089 }
1090
1091 @Test (timeout=300000)
1092 public void testEnableDisableAddColumnDeleteColumn() throws Exception {
1093 ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(TEST_UTIL);
1094 TableName tableName = TableName.valueOf("testMasterAdmin");
1095 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
1096 while (!ZKTableReadOnly.isEnabledTable(zkw,
1097 TableName.valueOf("testMasterAdmin"))) {
1098 Thread.sleep(10);
1099 }
1100 this.admin.disableTable(tableName);
1101 try {
1102 new HTable(TEST_UTIL.getConfiguration(), tableName);
1103 } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
1104
1105 }
1106
1107 this.admin.addColumn(tableName, new HColumnDescriptor("col2"));
1108 this.admin.enableTable(tableName);
1109 try {
1110 this.admin.deleteColumn(tableName, Bytes.toBytes("col2"));
1111 } catch (TableNotDisabledException e) {
1112 LOG.info(e);
1113 }
1114 this.admin.disableTable(tableName);
1115 this.admin.deleteTable(tableName);
1116 }
1117
1118 @Test (timeout=300000)
1119 public void testCreateBadTables() throws IOException {
1120 String msg = null;
1121 try {
1122 this.admin.createTable(HTableDescriptor.META_TABLEDESC);
1123 } catch(TableExistsException e) {
1124 msg = e.toString();
1125 }
1126 assertTrue("Unexcepted exception message " + msg, msg != null &&
1127 msg.startsWith(TableExistsException.class.getName()) &&
1128 msg.contains(HTableDescriptor.META_TABLEDESC.getTableName().getNameAsString()));
1129
1130
1131 final HTableDescriptor threadDesc =
1132 new HTableDescriptor(TableName.valueOf("threaded_testCreateBadTables"));
1133 threadDesc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
1134 int count = 10;
1135 Thread [] threads = new Thread [count];
1136 final AtomicInteger successes = new AtomicInteger(0);
1137 final AtomicInteger failures = new AtomicInteger(0);
1138 final HBaseAdmin localAdmin = this.admin;
1139 for (int i = 0; i < count; i++) {
1140 threads[i] = new Thread(Integer.toString(i)) {
1141 @Override
1142 public void run() {
1143 try {
1144 localAdmin.createTable(threadDesc);
1145 successes.incrementAndGet();
1146 } catch (TableExistsException e) {
1147 failures.incrementAndGet();
1148 } catch (IOException e) {
1149 throw new RuntimeException("Failed threaded create" + getName(), e);
1150 }
1151 }
1152 };
1153 }
1154 for (int i = 0; i < count; i++) {
1155 threads[i].start();
1156 }
1157 for (int i = 0; i < count; i++) {
1158 while(threads[i].isAlive()) {
1159 try {
1160 Thread.sleep(100);
1161 } catch (InterruptedException e) {
1162
1163 }
1164 }
1165 }
1166
1167
1168 assertEquals(1, successes.get());
1169 assertEquals(count - 1, failures.get());
1170 }
1171
1172
1173
1174
1175
1176 @Test (timeout=300000)
1177 public void testTableNameClash() throws Exception {
1178 String name = "testTableNameClash";
1179 admin.createTable(new HTableDescriptor(TableName.valueOf(name + "SOMEUPPERCASE")));
1180 admin.createTable(new HTableDescriptor(TableName.valueOf(name)));
1181
1182 new HTable(TEST_UTIL.getConfiguration(), name).close();
1183 }
1184
1185
1186
1187
1188
1189
1190
1191
1192 @Test (timeout=300000)
1193 public void testCreateTableRPCTimeOut() throws Exception {
1194 String name = "testCreateTableRPCTimeOut";
1195 int oldTimeout = TEST_UTIL.getConfiguration().
1196 getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
1197 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500);
1198 try {
1199 int expectedRegions = 100;
1200
1201 byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
1202 byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
1203 HBaseAdmin hbaseadmin = new HBaseAdmin(TEST_UTIL.getConfiguration());
1204 hbaseadmin.createTable(new HTableDescriptor(TableName.valueOf(name)), startKey, endKey,
1205 expectedRegions);
1206 hbaseadmin.close();
1207 } finally {
1208 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, oldTimeout);
1209 }
1210 }
1211
1212
1213
1214
1215
1216 @Test (timeout=300000)
1217 public void testReadOnlyTable() throws Exception {
1218 byte [] name = Bytes.toBytes("testReadOnlyTable");
1219 HTable table = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1220 byte[] value = Bytes.toBytes("somedata");
1221
1222 Put put = new Put(value);
1223 put.add(HConstants.CATALOG_FAMILY, HConstants.CATALOG_FAMILY, value);
1224 table.put(put);
1225 table.close();
1226 }
1227
1228
1229
1230
1231
1232
1233 @Test (timeout=300000)
1234 public void testTableNames() throws IOException {
1235 byte[][] illegalNames = new byte[][] {
1236 Bytes.toBytes("-bad"),
1237 Bytes.toBytes(".bad")
1238 };
1239 for (byte[] illegalName : illegalNames) {
1240 try {
1241 new HTableDescriptor(TableName.valueOf(illegalName));
1242 throw new IOException("Did not detect '" +
1243 Bytes.toString(illegalName) + "' as an illegal user table name");
1244 } catch (IllegalArgumentException e) {
1245
1246 }
1247 }
1248 byte[] legalName = Bytes.toBytes("g-oo.d");
1249 try {
1250 new HTableDescriptor(TableName.valueOf(legalName));
1251 } catch (IllegalArgumentException e) {
1252 throw new IOException("Legal user table name: '" +
1253 Bytes.toString(legalName) + "' caused IllegalArgumentException: " +
1254 e.getMessage());
1255 }
1256 }
1257
1258
1259
1260
1261
1262 @Test (expected=TableExistsException.class, timeout=300000)
1263 public void testTableExistsExceptionWithATable() throws IOException {
1264 final byte [] name = Bytes.toBytes("testTableExistsExceptionWithATable");
1265 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
1266 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1267 }
1268
1269
1270
1271
1272
1273 @Test (expected=TableNotEnabledException.class, timeout=300000)
1274 public void testTableNotEnabledExceptionWithATable() throws IOException {
1275 final byte [] name = Bytes.toBytes(
1276 "testTableNotEnabledExceptionWithATable");
1277 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
1278 this.admin.disableTable(name);
1279 this.admin.disableTable(name);
1280 }
1281
1282
1283
1284
1285
1286 @Test (expected=TableNotDisabledException.class, timeout=300000)
1287 public void testTableNotDisabledExceptionWithATable() throws IOException {
1288 final byte [] name = Bytes.toBytes(
1289 "testTableNotDisabledExceptionWithATable");
1290 HTable t = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1291 try {
1292 this.admin.enableTable(name);
1293 }finally {
1294 t.close();
1295 }
1296 }
1297
1298
1299
1300
1301
1302 @Test (expected=TableNotFoundException.class, timeout=300000)
1303 public void testTableNotFoundExceptionWithoutAnyTables() throws IOException {
1304 new HTable(TEST_UTIL.getConfiguration(),"testTableNotFoundExceptionWithoutAnyTables");
1305 }
1306
1307
1308 @Test (timeout=300000)
1309 public void testShouldCloseTheRegionBasedOnTheEncodedRegionName()
1310 throws Exception {
1311 TableName TABLENAME =
1312 TableName.valueOf("TestHBACloseRegion");
1313 createTableWithDefaultConf(TABLENAME);
1314
1315 HRegionInfo info = null;
1316 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1317 List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1318 for (HRegionInfo regionInfo : onlineRegions) {
1319 if (!HTableDescriptor.isSystemTable(regionInfo.getTableName())) {
1320 info = regionInfo;
1321 admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), rs
1322 .getServerName().getServerName());
1323 }
1324 }
1325 boolean isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
1326 long timeout = System.currentTimeMillis() + 10000;
1327 while ((System.currentTimeMillis() < timeout) && (isInList)) {
1328 Thread.sleep(100);
1329 isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
1330 }
1331
1332 assertFalse("The region should not be present in online regions list.",
1333 isInList);
1334 }
1335
1336 @Test (timeout=300000)
1337 public void testCloseRegionIfInvalidRegionNameIsPassed() throws Exception {
1338 byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion1");
1339 createTableWithDefaultConf(TABLENAME);
1340
1341 HRegionInfo info = null;
1342 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1343 List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1344 for (HRegionInfo regionInfo : onlineRegions) {
1345 if (!regionInfo.isMetaTable()) {
1346 if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion1")) {
1347 info = regionInfo;
1348 try {
1349 admin.closeRegionWithEncodedRegionName("sample", rs.getServerName()
1350 .getServerName());
1351 } catch (NotServingRegionException nsre) {
1352
1353 }
1354 }
1355 }
1356 }
1357 onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1358 assertTrue("The region should be present in online regions list.",
1359 onlineRegions.contains(info));
1360 }
1361
1362 @Test (timeout=300000)
1363 public void testCloseRegionThatFetchesTheHRIFromMeta() throws Exception {
1364 TableName TABLENAME =
1365 TableName.valueOf("TestHBACloseRegion2");
1366 createTableWithDefaultConf(TABLENAME);
1367
1368 HRegionInfo info = null;
1369 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1370 List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1371 for (HRegionInfo regionInfo : onlineRegions) {
1372 if (!regionInfo.isMetaTable()) {
1373
1374 if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion2")) {
1375 info = regionInfo;
1376 admin.closeRegion(regionInfo.getRegionNameAsString(), rs
1377 .getServerName().getServerName());
1378 }
1379 }
1380 }
1381
1382 boolean isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
1383 long timeout = System.currentTimeMillis() + 10000;
1384 while ((System.currentTimeMillis() < timeout) && (isInList)) {
1385 Thread.sleep(100);
1386 isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
1387 }
1388
1389 assertFalse("The region should not be present in online regions list.",
1390 isInList);
1391 }
1392
1393 @Test (timeout=300000)
1394 public void testCloseRegionWhenServerNameIsNull() throws Exception {
1395 byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion3");
1396 createTableWithDefaultConf(TABLENAME);
1397
1398 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1399
1400 try {
1401 List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1402 for (HRegionInfo regionInfo : onlineRegions) {
1403 if (!regionInfo.isMetaTable()) {
1404 if (regionInfo.getRegionNameAsString()
1405 .contains("TestHBACloseRegion3")) {
1406 admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(),
1407 null);
1408 }
1409 }
1410 }
1411 fail("The test should throw exception if the servername passed is null.");
1412 } catch (IllegalArgumentException e) {
1413 }
1414 }
1415
1416
1417 @Test (timeout=300000)
1418 public void testCloseRegionWhenServerNameIsEmpty() throws Exception {
1419 byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegionWhenServerNameIsEmpty");
1420 createTableWithDefaultConf(TABLENAME);
1421
1422 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1423
1424 try {
1425 List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1426 for (HRegionInfo regionInfo : onlineRegions) {
1427 if (!regionInfo.isMetaTable()) {
1428 if (regionInfo.getRegionNameAsString()
1429 .contains("TestHBACloseRegionWhenServerNameIsEmpty")) {
1430 admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(),
1431 " ");
1432 }
1433 }
1434 }
1435 fail("The test should throw exception if the servername passed is empty.");
1436 } catch (IllegalArgumentException e) {
1437 }
1438 }
1439
1440 @Test (timeout=300000)
1441 public void testCloseRegionWhenEncodedRegionNameIsNotGiven() throws Exception {
1442 byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion4");
1443 createTableWithDefaultConf(TABLENAME);
1444
1445 HRegionInfo info = null;
1446 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1447
1448 List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1449 for (HRegionInfo regionInfo : onlineRegions) {
1450 if (!regionInfo.isMetaTable()) {
1451 if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion4")) {
1452 info = regionInfo;
1453 try {
1454 admin.closeRegionWithEncodedRegionName(regionInfo
1455 .getRegionNameAsString(), rs.getServerName().getServerName());
1456 } catch (NotServingRegionException nsre) {
1457
1458 }
1459 }
1460 }
1461 }
1462 onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1463 assertTrue("The region should be present in online regions list.",
1464 onlineRegions.contains(info));
1465 }
1466
1467 private HBaseAdmin createTable(byte[] TABLENAME) throws IOException {
1468
1469 Configuration config = TEST_UTIL.getConfiguration();
1470 HBaseAdmin admin = new HBaseAdmin(config);
1471
1472 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TABLENAME));
1473 HColumnDescriptor hcd = new HColumnDescriptor("value");
1474
1475 htd.addFamily(hcd);
1476 admin.createTable(htd, null);
1477 return admin;
1478 }
1479
1480 private void createTableWithDefaultConf(byte[] TABLENAME) throws IOException {
1481 createTableWithDefaultConf(TableName.valueOf(TABLENAME));
1482 }
1483
1484 private void createTableWithDefaultConf(TableName TABLENAME) throws IOException {
1485 HTableDescriptor htd = new HTableDescriptor(TABLENAME);
1486 HColumnDescriptor hcd = new HColumnDescriptor("value");
1487 htd.addFamily(hcd);
1488
1489 admin.createTable(htd, null);
1490 }
1491
1492
1493
1494
1495
1496 @Test (timeout=300000)
1497 public void testGetTableRegions() throws IOException {
1498
1499 byte[] tableName = Bytes.toBytes("testGetTableRegions");
1500
1501 int expectedRegions = 10;
1502
1503
1504 byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
1505 byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
1506
1507
1508 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
1509 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
1510 admin.createTable(desc, startKey, endKey, expectedRegions);
1511
1512 List<HRegionInfo> RegionInfos = admin.getTableRegions(tableName);
1513
1514 assertEquals("Tried to create " + expectedRegions + " regions " +
1515 "but only found " + RegionInfos.size(),
1516 expectedRegions, RegionInfos.size());
1517
1518 }
1519
1520 @Test (timeout=300000)
1521 public void testHLogRollWriting() throws Exception {
1522 setUpforLogRolling();
1523 String className = this.getClass().getName();
1524 StringBuilder v = new StringBuilder(className);
1525 while (v.length() < 1000) {
1526 v.append(className);
1527 }
1528 byte[] value = Bytes.toBytes(v.toString());
1529 HRegionServer regionServer = startAndWriteData("TestLogRolling", value);
1530 LOG.info("after writing there are "
1531 + HLogUtilsForTests.getNumLogFiles(regionServer.getWAL()) + " log files");
1532
1533
1534
1535 List<HRegion> regions = new ArrayList<HRegion>(regionServer
1536 .getOnlineRegionsLocalContext());
1537 for (HRegion r : regions) {
1538 r.flushcache();
1539 }
1540 admin.rollHLogWriter(regionServer.getServerName().getServerName());
1541 int count = HLogUtilsForTests.getNumLogFiles(regionServer.getWAL());
1542 LOG.info("after flushing all regions and rolling logs there are " +
1543 count + " log files");
1544 assertTrue(("actual count: " + count), count <= 2);
1545 }
1546
1547 @Test (timeout=300000)
1548 public void testMoveToPreviouslyAssignedRS() throws IOException, InterruptedException {
1549 byte[] tableName = Bytes.toBytes("testMoveToPreviouslyAssignedRS");
1550 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
1551 HMaster master = cluster.getMaster();
1552 HBaseAdmin localAdmin = createTable(tableName);
1553 List<HRegionInfo> tableRegions = localAdmin.getTableRegions(tableName);
1554 HRegionInfo hri = tableRegions.get(0);
1555 AssignmentManager am = master.getAssignmentManager();
1556 assertTrue("Region " + hri.getRegionNameAsString()
1557 + " should be assigned properly", am.waitForAssignment(hri));
1558 ServerName server = am.getRegionStates().getRegionServerOfRegion(hri);
1559 localAdmin.move(hri.getEncodedNameAsBytes(), Bytes.toBytes(server.getServerName()));
1560 assertEquals("Current region server and region server before move should be same.", server,
1561 am.getRegionStates().getRegionServerOfRegion(hri));
1562 }
1563
1564
1565 private void setUpforLogRolling() {
1566
1567 TEST_UTIL.getConfiguration().setLong(HConstants.HREGION_MAX_FILESIZE,
1568 768L * 1024L);
1569
1570
1571 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.maxlogentries", 32);
1572
1573 TEST_UTIL.getConfiguration().setInt(
1574 "hbase.regionserver.logroll.errors.tolerated", 2);
1575 TEST_UTIL.getConfiguration().setInt("ipc.ping.interval", 10 * 1000);
1576 TEST_UTIL.getConfiguration().setInt("ipc.socket.timeout", 10 * 1000);
1577 TEST_UTIL.getConfiguration().setInt("hbase.rpc.timeout", 10 * 1000);
1578
1579
1580 TEST_UTIL.getConfiguration().setInt(
1581 "hbase.hregion.memstore.optionalflushcount", 2);
1582
1583
1584 TEST_UTIL.getConfiguration().setInt(HConstants.HREGION_MEMSTORE_FLUSH_SIZE,
1585 8192);
1586
1587
1588 TEST_UTIL.getConfiguration().setLong("hbase.client.pause", 10 * 1000);
1589
1590
1591
1592 TEST_UTIL.getConfiguration().setInt(HConstants.THREAD_WAKE_FREQUENCY,
1593 2 * 1000);
1594
1595
1596
1597 TEST_UTIL.getConfiguration().setBoolean("dfs.support.append", true);
1598
1599
1600 TEST_UTIL.getConfiguration().setInt("heartbeat.recheck.interval", 5000);
1601 TEST_UTIL.getConfiguration().setInt("dfs.heartbeat.interval", 1);
1602
1603
1604 TEST_UTIL.getConfiguration().setInt("dfs.client.block.write.retries", 30);
1605 TEST_UTIL.getConfiguration().setInt(
1606 "hbase.regionserver.hlog.tolerable.lowreplication", 2);
1607 TEST_UTIL.getConfiguration().setInt(
1608 "hbase.regionserver.hlog.lowreplication.rolllimit", 3);
1609 }
1610
1611 private HRegionServer startAndWriteData(String tableName, byte[] value)
1612 throws IOException, InterruptedException {
1613
1614 new HTable(
1615 TEST_UTIL.getConfiguration(), TableName.META_TABLE_NAME).close();
1616
1617
1618 HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
1619 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
1620 admin.createTable(desc);
1621 HTable table = new HTable(TEST_UTIL.getConfiguration(), tableName);
1622
1623 HRegionServer regionServer = TEST_UTIL.getRSForFirstRegionInTable(Bytes.toBytes(tableName));
1624 for (int i = 1; i <= 256; i++) {
1625 Put put = new Put(Bytes.toBytes("row" + String.format("%1$04d", i)));
1626 put.add(HConstants.CATALOG_FAMILY, null, value);
1627 table.put(put);
1628 if (i % 32 == 0) {
1629
1630 try {
1631 Thread.sleep(2000);
1632 } catch (InterruptedException e) {
1633
1634 }
1635 }
1636 }
1637
1638 table.close();
1639 return regionServer;
1640 }
1641
1642
1643
1644
1645 @Test (timeout=300000)
1646 public void testCheckHBaseAvailableClosesConnection() throws Exception {
1647 Configuration conf = TEST_UTIL.getConfiguration();
1648
1649 int initialCount = HConnectionTestingUtility.getConnectionCount();
1650 HBaseAdmin.checkHBaseAvailable(conf);
1651 int finalCount = HConnectionTestingUtility.getConnectionCount();
1652
1653 Assert.assertEquals(initialCount, finalCount) ;
1654 }
1655
1656
1657
1658
1659 @Test (timeout=300000)
1660 public void testCheckHBaseAvailableWithoutCluster() {
1661 Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
1662
1663
1664 conf.setInt(HConstants.ZOOKEEPER_CLIENT_PORT,
1665 conf.getInt(HConstants.ZOOKEEPER_CLIENT_PORT, 9999)+10);
1666
1667 int initialCount = HConnectionTestingUtility.getConnectionCount();
1668
1669 long start = System.currentTimeMillis();
1670 try {
1671 HBaseAdmin.checkHBaseAvailable(conf);
1672 assertTrue(false);
1673 } catch (MasterNotRunningException ignored) {
1674 } catch (ZooKeeperConnectionException ignored) {
1675 } catch (ServiceException ignored) {
1676 } catch (IOException ignored) {
1677 }
1678 long end = System.currentTimeMillis();
1679
1680 int finalCount = HConnectionTestingUtility.getConnectionCount();
1681
1682 Assert.assertEquals(initialCount, finalCount) ;
1683
1684 LOG.info("It took "+(end-start)+" ms to find out that" +
1685 " HBase was not available");
1686 }
1687
1688 @Test (timeout=300000)
1689 public void testDisableCatalogTable() throws Exception {
1690 try {
1691 this.admin.disableTable(TableName.META_TABLE_NAME);
1692 fail("Expected to throw ConstraintException");
1693 } catch (ConstraintException e) {
1694 }
1695
1696
1697 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("testDisableCatalogTable".getBytes()));
1698 HColumnDescriptor hcd = new HColumnDescriptor("cf1".getBytes());
1699 htd.addFamily(hcd);
1700 TEST_UTIL.getHBaseAdmin().createTable(htd);
1701 }
1702
1703 @Test (timeout=300000)
1704 public void testGetRegion() throws Exception {
1705 final String name = "testGetRegion";
1706 LOG.info("Started " + name);
1707 final byte [] nameBytes = Bytes.toBytes(name);
1708 HTable t = TEST_UTIL.createTable(nameBytes, HConstants.CATALOG_FAMILY);
1709 TEST_UTIL.createMultiRegions(t, HConstants.CATALOG_FAMILY);
1710 CatalogTracker ct = new CatalogTracker(TEST_UTIL.getConfiguration());
1711 ct.start();
1712 try {
1713 HRegionLocation regionLocation = t.getRegionLocation("mmm");
1714 HRegionInfo region = regionLocation.getRegionInfo();
1715 byte[] regionName = region.getRegionName();
1716 Pair<HRegionInfo, ServerName> pair = admin.getRegion(regionName, ct);
1717 assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
1718 pair = admin.getRegion(region.getEncodedNameAsBytes(), ct);
1719 assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
1720 } finally {
1721 ct.stop();
1722 }
1723 }
1724 }