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