1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.client;
21
22
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertTrue;
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.concurrent.atomic.AtomicBoolean;
34 import java.util.concurrent.atomic.AtomicInteger;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.apache.hadoop.hbase.HBaseTestingUtility;
39 import org.apache.hadoop.hbase.HColumnDescriptor;
40 import org.apache.hadoop.hbase.HConstants;
41 import org.apache.hadoop.hbase.HRegionInfo;
42 import org.apache.hadoop.hbase.HServerAddress;
43 import org.apache.hadoop.hbase.HTableDescriptor;
44 import org.apache.hadoop.hbase.NotServingRegionException;
45 import org.apache.hadoop.hbase.TableExistsException;
46 import org.apache.hadoop.hbase.TableNotDisabledException;
47 import org.apache.hadoop.hbase.TableNotFoundException;
48 import org.apache.hadoop.hbase.executor.EventHandler;
49 import org.apache.hadoop.hbase.executor.EventHandler.EventType;
50 import org.apache.hadoop.hbase.executor.ExecutorService;
51 import org.apache.hadoop.hbase.master.MasterServices;
52 import org.apache.hadoop.hbase.util.Bytes;
53 import org.junit.AfterClass;
54 import org.junit.Before;
55 import org.junit.BeforeClass;
56 import org.junit.Test;
57
58
59
60
61
62
63
64 public class TestAdmin {
65 final Log LOG = LogFactory.getLog(getClass());
66 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
67 private HBaseAdmin admin;
68
69 @BeforeClass
70 public static void setUpBeforeClass() throws Exception {
71 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
72 TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
73 TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 6);
74 TEST_UTIL.startMiniCluster(3);
75 }
76
77 @AfterClass
78 public static void tearDownAfterClass() throws Exception {
79 TEST_UTIL.shutdownMiniCluster();
80 }
81
82 @Before
83 public void setUp() throws Exception {
84 this.admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
85 }
86
87 @Test
88 public void testDisableAndEnableTable() throws IOException {
89 final byte [] row = Bytes.toBytes("row");
90 final byte [] qualifier = Bytes.toBytes("qualifier");
91 final byte [] value = Bytes.toBytes("value");
92 final byte [] table = Bytes.toBytes("testDisableAndEnableTable");
93 HTable ht = TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
94 Put put = new Put(row);
95 put.add(HConstants.CATALOG_FAMILY, qualifier, value);
96 ht.put(put);
97 Get get = new Get(row);
98 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
99 ht.get(get);
100
101 this.admin.disableTable(table);
102
103
104 get = new Get(row);
105 get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
106 boolean ok = false;
107 try {
108 ht.get(get);
109 } catch (NotServingRegionException e) {
110 ok = true;
111 } catch (RetriesExhaustedException e) {
112 ok = true;
113 }
114 assertTrue(ok);
115 this.admin.enableTable(table);
116
117
118 try {
119 ht.get(get);
120 } catch (RetriesExhaustedException e) {
121 ok = false;
122 }
123 assertTrue(ok);
124 }
125
126 @Test
127 public void testCreateTable() throws IOException {
128 HTableDescriptor [] tables = admin.listTables();
129 int numTables = tables.length;
130 TEST_UTIL.createTable(Bytes.toBytes("testCreateTable"),
131 HConstants.CATALOG_FAMILY);
132 tables = this.admin.listTables();
133 assertEquals(numTables + 1, tables.length);
134 }
135
136 @Test
137 public void testGetTableDescriptor() throws IOException {
138 HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
139 HColumnDescriptor fam2 = new HColumnDescriptor("fam2");
140 HColumnDescriptor fam3 = new HColumnDescriptor("fam3");
141 HTableDescriptor htd = new HTableDescriptor("myTestTable");
142 htd.addFamily(fam1);
143 htd.addFamily(fam2);
144 htd.addFamily(fam3);
145 this.admin.createTable(htd);
146 HTable table = new HTable(TEST_UTIL.getConfiguration(), "myTestTable");
147 HTableDescriptor confirmedHtd = table.getTableDescriptor();
148 assertEquals(htd.compareTo(confirmedHtd), 0);
149 }
150
151
152
153
154
155 @Test public void testChangeTableSchema() throws IOException {
156 final byte [] tableName = Bytes.toBytes("changeTableSchema");
157 HTableDescriptor [] tables = admin.listTables();
158 int numTables = tables.length;
159 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY);
160 tables = this.admin.listTables();
161 assertEquals(numTables + 1, tables.length);
162
163
164 HTableDescriptor htd = this.admin.getTableDescriptor(tableName);
165
166 HTableDescriptor copy = new HTableDescriptor(htd);
167 assertTrue(htd.equals(copy));
168
169 long newFlushSize = htd.getMemStoreFlushSize() / 2;
170 copy.setMemStoreFlushSize(newFlushSize);
171 final String key = "anyoldkey";
172 assertTrue(htd.getValue(key) == null);
173 copy.setValue(key, key);
174 boolean expectedException = false;
175 try {
176 this.admin.modifyTable(tableName, copy);
177 } catch (TableNotDisabledException re) {
178 expectedException = true;
179 }
180 assertTrue(expectedException);
181 this.admin.disableTable(tableName);
182 assertTrue(this.admin.isTableDisabled(tableName));
183 modifyTable(tableName, copy);
184 HTableDescriptor modifiedHtd = this.admin.getTableDescriptor(tableName);
185
186 assertFalse(htd.equals(modifiedHtd));
187 assertTrue(copy.equals(modifiedHtd));
188 assertEquals(newFlushSize, modifiedHtd.getMemStoreFlushSize());
189 assertEquals(key, modifiedHtd.getValue(key));
190
191
192 this.admin.enableTable(tableName);
193 assertFalse(this.admin.isTableDisabled(tableName));
194
195
196 int countOfFamilies = modifiedHtd.getFamilies().size();
197 assertTrue(countOfFamilies > 0);
198 HColumnDescriptor hcd = modifiedHtd.getFamilies().iterator().next();
199 int maxversions = hcd.getMaxVersions();
200 final int newMaxVersions = maxversions + 1;
201 hcd.setMaxVersions(newMaxVersions);
202 final byte [] hcdName = hcd.getName();
203 expectedException = false;
204 try {
205 this.admin.modifyColumn(tableName, hcd);
206 } catch (TableNotDisabledException re) {
207 expectedException = true;
208 }
209 assertTrue(expectedException);
210 this.admin.disableTable(tableName);
211 assertTrue(this.admin.isTableDisabled(tableName));
212
213 this.admin.modifyColumn(tableName, hcd);
214 modifiedHtd = this.admin.getTableDescriptor(tableName);
215 HColumnDescriptor modifiedHcd = modifiedHtd.getFamily(hcdName);
216 assertEquals(newMaxVersions, modifiedHcd.getMaxVersions());
217
218
219
220 this.admin.enableTable(tableName);
221 assertFalse(this.admin.isTableDisabled(tableName));
222 final String xtracolName = "xtracol";
223 HColumnDescriptor xtracol = new HColumnDescriptor(xtracolName);
224 xtracol.setValue(xtracolName, xtracolName);
225 try {
226 this.admin.addColumn(tableName, xtracol);
227 } catch (TableNotDisabledException re) {
228 expectedException = true;
229 }
230 assertTrue(expectedException);
231 this.admin.disableTable(tableName);
232 assertTrue(this.admin.isTableDisabled(tableName));
233 this.admin.addColumn(tableName, xtracol);
234 modifiedHtd = this.admin.getTableDescriptor(tableName);
235 hcd = modifiedHtd.getFamily(xtracol.getName());
236 assertTrue(hcd != null);
237 assertTrue(hcd.getValue(xtracolName).equals(xtracolName));
238
239
240 this.admin.deleteColumn(tableName, xtracol.getName());
241 modifiedHtd = this.admin.getTableDescriptor(tableName);
242 hcd = modifiedHtd.getFamily(xtracol.getName());
243 assertTrue(hcd == null);
244
245
246 this.admin.deleteTable(tableName);
247 this.admin.listTables();
248 assertFalse(this.admin.tableExists(tableName));
249 }
250
251
252
253
254
255
256
257 private void modifyTable(final byte [] tableName, final HTableDescriptor htd)
258 throws IOException {
259 MasterServices services = TEST_UTIL.getMiniHBaseCluster().getMaster();
260 ExecutorService executor = services.getExecutorService();
261 AtomicBoolean done = new AtomicBoolean(false);
262 executor.registerListener(EventType.C_M_MODIFY_TABLE, new DoneListener(done));
263 this.admin.modifyTable(tableName, htd);
264 while (!done.get()) {
265 synchronized (done) {
266 try {
267 done.wait(1000);
268 } catch (InterruptedException e) {
269 e.printStackTrace();
270 }
271 }
272 }
273 executor.unregisterListener(EventType.C_M_MODIFY_TABLE);
274 }
275
276
277
278
279 static class DoneListener implements EventHandler.EventHandlerListener {
280 private final AtomicBoolean done;
281
282 DoneListener(final AtomicBoolean done) {
283 super();
284 this.done = done;
285 }
286
287 @Override
288 public void afterProcess(EventHandler event) {
289 this.done.set(true);
290 synchronized (this.done) {
291
292 this.done.notifyAll();
293 }
294 }
295
296 @Override
297 public void beforeProcess(EventHandler event) {
298
299 }
300 }
301
302 protected void verifyRoundRobinDistribution(HTable ht, int expectedRegions) throws IOException {
303 int numRS = ht.getCurrentNrHRS();
304 Map<HRegionInfo,HServerAddress> regions = ht.getRegionsInfo();
305 Map<HServerAddress, List<HRegionInfo>> server2Regions = new HashMap<HServerAddress, List<HRegionInfo>>();
306 for (Map.Entry<HRegionInfo,HServerAddress> entry : regions.entrySet()) {
307 HServerAddress server = entry.getValue();
308 List<HRegionInfo> regs = server2Regions.get(server);
309 if (regs == null) {
310 regs = new ArrayList<HRegionInfo>();
311 server2Regions.put(server, regs);
312 }
313 regs.add(entry.getKey());
314 }
315 float average = (float) expectedRegions/numRS;
316 int min = (int)Math.floor(average);
317 int max = (int)Math.ceil(average);
318 for (List<HRegionInfo> regionList : server2Regions.values()) {
319 assertTrue(regionList.size() == min || regionList.size() == max);
320 }
321 }
322
323 @Test
324 public void testCreateTableWithRegions() throws IOException, InterruptedException {
325
326 byte[] tableName = Bytes.toBytes("testCreateTableWithRegions");
327
328 byte [][] splitKeys = {
329 new byte [] { 1, 1, 1 },
330 new byte [] { 2, 2, 2 },
331 new byte [] { 3, 3, 3 },
332 new byte [] { 4, 4, 4 },
333 new byte [] { 5, 5, 5 },
334 new byte [] { 6, 6, 6 },
335 new byte [] { 7, 7, 7 },
336 new byte [] { 8, 8, 8 },
337 new byte [] { 9, 9, 9 },
338 };
339 int expectedRegions = splitKeys.length + 1;
340
341 HTableDescriptor desc = new HTableDescriptor(tableName);
342 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
343 admin.createTable(desc, splitKeys);
344
345 HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
346 Map<HRegionInfo,HServerAddress> regions = ht.getRegionsInfo();
347 assertEquals("Tried to create " + expectedRegions + " regions " +
348 "but only found " + regions.size(),
349 expectedRegions, regions.size());
350 System.err.println("Found " + regions.size() + " regions");
351
352 Iterator<HRegionInfo> hris = regions.keySet().iterator();
353 HRegionInfo hri = hris.next();
354 assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0);
355 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[0]));
356 hri = hris.next();
357 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[0]));
358 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[1]));
359 hri = hris.next();
360 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[1]));
361 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[2]));
362 hri = hris.next();
363 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[2]));
364 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[3]));
365 hri = hris.next();
366 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[3]));
367 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[4]));
368 hri = hris.next();
369 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[4]));
370 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[5]));
371 hri = hris.next();
372 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[5]));
373 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[6]));
374 hri = hris.next();
375 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[6]));
376 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[7]));
377 hri = hris.next();
378 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[7]));
379 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[8]));
380 hri = hris.next();
381 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[8]));
382 assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0);
383
384 verifyRoundRobinDistribution(ht, expectedRegions);
385
386
387
388
389 byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
390 byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
391
392
393
394
395 expectedRegions = 10;
396
397 byte [] TABLE_2 = Bytes.add(tableName, Bytes.toBytes("_2"));
398
399 desc = new HTableDescriptor(TABLE_2);
400 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
401 admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
402 admin.createTable(desc, startKey, endKey, expectedRegions);
403
404 ht = new HTable(TEST_UTIL.getConfiguration(), TABLE_2);
405 regions = ht.getRegionsInfo();
406 assertEquals("Tried to create " + expectedRegions + " regions " +
407 "but only found " + regions.size(),
408 expectedRegions, regions.size());
409 System.err.println("Found " + regions.size() + " regions");
410
411 hris = regions.keySet().iterator();
412 hri = hris.next();
413 assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0);
414 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {1,1,1,1,1,1,1,1,1,1}));
415 hri = hris.next();
416 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {1,1,1,1,1,1,1,1,1,1}));
417 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {2,2,2,2,2,2,2,2,2,2}));
418 hri = hris.next();
419 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {2,2,2,2,2,2,2,2,2,2}));
420 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {3,3,3,3,3,3,3,3,3,3}));
421 hri = hris.next();
422 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {3,3,3,3,3,3,3,3,3,3}));
423 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {4,4,4,4,4,4,4,4,4,4}));
424 hri = hris.next();
425 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {4,4,4,4,4,4,4,4,4,4}));
426 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {5,5,5,5,5,5,5,5,5,5}));
427 hri = hris.next();
428 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {5,5,5,5,5,5,5,5,5,5}));
429 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {6,6,6,6,6,6,6,6,6,6}));
430 hri = hris.next();
431 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {6,6,6,6,6,6,6,6,6,6}));
432 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {7,7,7,7,7,7,7,7,7,7}));
433 hri = hris.next();
434 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {7,7,7,7,7,7,7,7,7,7}));
435 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {8,8,8,8,8,8,8,8,8,8}));
436 hri = hris.next();
437 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {8,8,8,8,8,8,8,8,8,8}));
438 assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {9,9,9,9,9,9,9,9,9,9}));
439 hri = hris.next();
440 assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {9,9,9,9,9,9,9,9,9,9}));
441 assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0);
442
443 verifyRoundRobinDistribution(ht, expectedRegions);
444
445
446
447 startKey = new byte [] { 0, 0, 0, 0, 0, 0 };
448 endKey = new byte [] { 1, 0, 0, 0, 0, 0 };
449
450 expectedRegions = 5;
451
452 byte [] TABLE_3 = Bytes.add(tableName, Bytes.toBytes("_3"));
453
454 desc = new HTableDescriptor(TABLE_3);
455 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
456 admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
457 admin.createTable(desc, startKey, endKey, expectedRegions);
458
459 ht = new HTable(TEST_UTIL.getConfiguration(), TABLE_3);
460 regions = ht.getRegionsInfo();
461 assertEquals("Tried to create " + expectedRegions + " regions " +
462 "but only found " + regions.size(),
463 expectedRegions, regions.size());
464 System.err.println("Found " + regions.size() + " regions");
465
466 verifyRoundRobinDistribution(ht, expectedRegions);
467
468
469 splitKeys = new byte [][] {
470 new byte [] { 1, 1, 1 },
471 new byte [] { 2, 2, 2 },
472 new byte [] { 3, 3, 3 },
473 new byte [] { 2, 2, 2 }
474 };
475
476 byte [] TABLE_4 = Bytes.add(tableName, Bytes.toBytes("_4"));
477 desc = new HTableDescriptor(TABLE_4);
478 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
479 admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
480 try {
481 admin.createTable(desc, splitKeys);
482 assertTrue("Should not be able to create this table because of " +
483 "duplicate split keys", false);
484 } catch(IllegalArgumentException iae) {
485
486 }
487 }
488
489 @Test
490 public void testTableExist() throws IOException {
491 final byte [] table = Bytes.toBytes("testTableExist");
492 boolean exist = false;
493 exist = this.admin.tableExists(table);
494 assertEquals(false, exist);
495 TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
496 exist = this.admin.tableExists(table);
497 assertEquals(true, exist);
498 }
499
500
501
502
503
504
505 @Test
506 public void testForceSplit() throws Exception {
507 byte [] familyName = HConstants.CATALOG_FAMILY;
508 byte [] tableName = Bytes.toBytes("testForceSplit");
509 final HTable table = TEST_UTIL.createTable(tableName, familyName);
510 byte[] k = new byte[3];
511 int rowCount = 0;
512 for (byte b1 = 'a'; b1 < 'z'; b1++) {
513 for (byte b2 = 'a'; b2 < 'z'; b2++) {
514 for (byte b3 = 'a'; b3 < 'z'; b3++) {
515 k[0] = b1;
516 k[1] = b2;
517 k[2] = b3;
518 Put put = new Put(k);
519 put.add(familyName, new byte[0], k);
520 table.put(put);
521 rowCount++;
522 }
523 }
524 }
525
526
527 Map<HRegionInfo,HServerAddress> m = table.getRegionsInfo();
528 System.out.println("Initial regions (" + m.size() + "): " + m);
529 assertTrue(m.size() == 1);
530
531
532 Scan scan = new Scan();
533 ResultScanner scanner = table.getScanner(scan);
534 int rows = 0;
535 for(@SuppressWarnings("unused") Result result : scanner) {
536 rows++;
537 }
538 scanner.close();
539 assertEquals(rowCount, rows);
540
541
542 scan = new Scan();
543 scanner = table.getScanner(scan);
544
545 scanner.next();
546
547 final AtomicInteger count = new AtomicInteger(0);
548 Thread t = new Thread("CheckForSplit") {
549 public void run() {
550 for (int i = 0; i < 20; i++) {
551 try {
552 sleep(1000);
553 } catch (InterruptedException e) {
554 continue;
555 }
556
557 Map<HRegionInfo, HServerAddress> regions = null;
558 try {
559 regions = table.getRegionsInfo();
560 } catch (IOException e) {
561 e.printStackTrace();
562 }
563 if (regions == null) continue;
564 count.set(regions.size());
565 if (count.get() >= 2) break;
566 LOG.debug("Cycle waiting on split");
567 }
568 }
569 };
570 t.start();
571
572 this.admin.split(Bytes.toString(tableName));
573 t.join();
574
575
576 rows = 1;
577 for (@SuppressWarnings("unused") Result result : scanner) {
578 rows++;
579 if (rows > rowCount) {
580 scanner.close();
581 assertTrue("Scanned more than expected (" + rowCount + ")", false);
582 }
583 }
584 scanner.close();
585 assertEquals(rowCount, rows);
586 }
587
588
589
590
591
592 @Test (expected=IllegalArgumentException.class)
593 public void testEmptyHHTableDescriptor() throws IOException {
594 this.admin.createTable(new HTableDescriptor());
595 }
596
597 @Test
598 public void testEnableDisableAddColumnDeleteColumn() throws Exception {
599 byte [] tableName = Bytes.toBytes("testMasterAdmin");
600 TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY);
601 this.admin.disableTable(tableName);
602 try {
603 new HTable(TEST_UTIL.getConfiguration(), tableName);
604 } catch (org.apache.hadoop.hbase.client.RegionOfflineException e) {
605
606 }
607 this.admin.addColumn(tableName, new HColumnDescriptor("col2"));
608 this.admin.enableTable(tableName);
609 try {
610 this.admin.deleteColumn(tableName, Bytes.toBytes("col2"));
611 } catch(TableNotDisabledException e) {
612
613 }
614 this.admin.disableTable(tableName);
615 this.admin.deleteColumn(tableName, Bytes.toBytes("col2"));
616 this.admin.deleteTable(tableName);
617 }
618
619 @Test
620 public void testCreateBadTables() throws IOException {
621 String msg = null;
622 try {
623 this.admin.createTable(HTableDescriptor.ROOT_TABLEDESC);
624 } catch (IllegalArgumentException e) {
625 msg = e.toString();
626 }
627 assertTrue("Unexcepted exception message " + msg, msg != null &&
628 msg.startsWith(IllegalArgumentException.class.getName()) &&
629 msg.contains(HTableDescriptor.ROOT_TABLEDESC.getNameAsString()));
630 msg = null;
631 try {
632 this.admin.createTable(HTableDescriptor.META_TABLEDESC);
633 } catch(IllegalArgumentException e) {
634 msg = e.toString();
635 }
636 assertTrue("Unexcepted exception message " + msg, msg != null &&
637 msg.startsWith(IllegalArgumentException.class.getName()) &&
638 msg.contains(HTableDescriptor.META_TABLEDESC.getNameAsString()));
639
640
641 final HTableDescriptor threadDesc =
642 new HTableDescriptor("threaded_testCreateBadTables");
643 threadDesc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
644 int count = 10;
645 Thread [] threads = new Thread [count];
646 final AtomicInteger successes = new AtomicInteger(0);
647 final AtomicInteger failures = new AtomicInteger(0);
648 final HBaseAdmin localAdmin = this.admin;
649 for (int i = 0; i < count; i++) {
650 threads[i] = new Thread(Integer.toString(i)) {
651 @Override
652 public void run() {
653 try {
654 localAdmin.createTable(threadDesc);
655 successes.incrementAndGet();
656 } catch (TableExistsException e) {
657 failures.incrementAndGet();
658 } catch (IOException e) {
659 throw new RuntimeException("Failed threaded create" + getName(), e);
660 }
661 }
662 };
663 }
664 for (int i = 0; i < count; i++) {
665 threads[i].start();
666 }
667 for (int i = 0; i < count; i++) {
668 while(threads[i].isAlive()) {
669 try {
670 Thread.sleep(1000);
671 } catch (InterruptedException e) {
672
673 }
674 }
675 }
676
677
678 assertEquals(1, successes.get());
679 assertEquals(count - 1, failures.get());
680 }
681
682
683
684
685
686 @Test
687 public void testTableNameClash() throws Exception {
688 String name = "testTableNameClash";
689 admin.createTable(new HTableDescriptor(name + "SOMEUPPERCASE"));
690 admin.createTable(new HTableDescriptor(name));
691
692 new HTable(TEST_UTIL.getConfiguration(), name);
693 }
694
695
696
697
698
699 @Test
700 public void testReadOnlyTable() throws Exception {
701 byte [] name = Bytes.toBytes("testReadOnlyTable");
702 HTable table = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
703 byte[] value = Bytes.toBytes("somedata");
704
705 Put put = new Put(value);
706 put.add(HConstants.CATALOG_FAMILY, HConstants.CATALOG_FAMILY, value);
707 table.put(put);
708 }
709
710
711
712
713
714
715 @Test
716 public void testTableNames() throws IOException {
717 byte[][] illegalNames = new byte[][] {
718 Bytes.toBytes("-bad"),
719 Bytes.toBytes(".bad"),
720 HConstants.ROOT_TABLE_NAME,
721 HConstants.META_TABLE_NAME
722 };
723 for (int i = 0; i < illegalNames.length; i++) {
724 try {
725 new HTableDescriptor(illegalNames[i]);
726 throw new IOException("Did not detect '" +
727 Bytes.toString(illegalNames[i]) + "' as an illegal user table name");
728 } catch (IllegalArgumentException e) {
729
730 }
731 }
732 byte[] legalName = Bytes.toBytes("g-oo.d");
733 try {
734 new HTableDescriptor(legalName);
735 } catch (IllegalArgumentException e) {
736 throw new IOException("Legal user table name: '" +
737 Bytes.toString(legalName) + "' caused IllegalArgumentException: " +
738 e.getMessage());
739 }
740 }
741
742
743
744
745
746 @Test (expected=TableExistsException.class)
747 public void testTableNotFoundExceptionWithATable() throws IOException {
748 final byte [] name = Bytes.toBytes("testTableNotFoundExceptionWithATable");
749 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
750 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
751 }
752
753
754
755
756
757 @Test (expected=TableNotFoundException.class)
758 public void testTableNotFoundExceptionWithoutAnyTables() throws IOException {
759 new HTable(TEST_UTIL.getConfiguration(),
760 "testTableNotFoundExceptionWithoutAnyTables");
761 }
762
763 @Test
764 public void testHundredsOfTable() throws IOException{
765 final int times = 100;
766 HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
767 HColumnDescriptor fam2 = new HColumnDescriptor("fam2");
768 HColumnDescriptor fam3 = new HColumnDescriptor("fam3");
769
770 for(int i = 0; i < times; i++) {
771 HTableDescriptor htd = new HTableDescriptor("table"+i);
772 htd.addFamily(fam1);
773 htd.addFamily(fam2);
774 htd.addFamily(fam3);
775 this.admin.createTable(htd);
776 }
777
778 for(int i = 0; i < times; i++) {
779 String tableName = "table"+i;
780 this.admin.disableTable(tableName);
781 byte [] tableNameBytes = Bytes.toBytes(tableName);
782 assertTrue(this.admin.isTableDisabled(tableNameBytes));
783 this.admin.enableTable(tableName);
784 assertFalse(this.admin.isTableDisabled(tableNameBytes));
785 this.admin.disableTable(tableName);
786 assertTrue(this.admin.isTableDisabled(tableNameBytes));
787 this.admin.deleteTable(tableName);
788 }
789 }
790 }