View Javadoc

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