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