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.ipc.RpcClient;
62  import org.apache.hadoop.hbase.master.AssignmentManager;
63  import org.apache.hadoop.hbase.master.HMaster;
64  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
65  import org.apache.hadoop.hbase.regionserver.HRegion;
66  import org.apache.hadoop.hbase.regionserver.HRegionServer;
67  import org.apache.hadoop.hbase.regionserver.wal.HLogUtilsForTests;
68  import org.apache.hadoop.hbase.util.Bytes;
69  import org.apache.hadoop.hbase.util.Pair;
70  import org.apache.hadoop.hbase.zookeeper.ZKTableReadOnly;
71  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
72  import org.junit.*;
73  import org.junit.experimental.categories.Category;
74  
75  import com.google.protobuf.ServiceException;
76  
77  
78  /**
79   * Class to test HBaseAdmin.
80   * Spins up the minicluster once at test start and then takes it down afterward.
81   * Add any testing of HBaseAdmin functionality here.
82   */
83  @Category(LargeTests.class)
84  public class TestAdmin {
85    final Log LOG = LogFactory.getLog(getClass());
86    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
87    private HBaseAdmin admin;
88  
89    @BeforeClass
90    public static void setUpBeforeClass() throws Exception {
91      TEST_UTIL.getConfiguration().setBoolean("hbase.online.schema.update.enable", true);
92      TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
93      TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
94      TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 6);
95      TEST_UTIL.getConfiguration().setBoolean(
96          "hbase.master.enabletable.roundrobin", true);
97      TEST_UTIL.startMiniCluster(3);
98    }
99  
100   @AfterClass
101   public static void tearDownAfterClass() throws Exception {
102     TEST_UTIL.shutdownMiniCluster();
103   }
104 
105   @Before
106   public void setUp() throws Exception {
107     this.admin = TEST_UTIL.getHBaseAdmin();
108   }
109 
110   @After
111   public void tearDown() throws Exception {
112   }
113 
114   @Test (timeout=300000)
115   public void testSplitFlushCompactUnknownTable() throws InterruptedException {
116     final String unknowntable = "fubar";
117     Exception exception = null;
118     try {
119       this.admin.compact(unknowntable);
120     } catch (IOException e) {
121       exception = e;
122     }
123     assertTrue(exception instanceof TableNotFoundException);
124 
125     exception = null;
126     try {
127       this.admin.flush(unknowntable);
128     } catch (IOException e) {
129       exception = e;
130     }
131     assertTrue(exception instanceof TableNotFoundException);
132 
133     exception = null;
134     try {
135       this.admin.split(unknowntable);
136     } catch (IOException e) {
137       exception = e;
138     }
139     assertTrue(exception instanceof TableNotFoundException);
140   }
141 
142   @Test (timeout=300000)
143   public void testDeleteEditUnknownColumnFamilyAndOrTable() throws IOException {
144     // Test we get exception if we try to
145     final String nonexistent = "nonexistent";
146     HColumnDescriptor nonexistentHcd = new HColumnDescriptor(nonexistent);
147     Exception exception = null;
148     try {
149       this.admin.addColumn(nonexistent, nonexistentHcd);
150     } catch (IOException e) {
151       exception = e;
152     }
153     assertTrue(exception instanceof TableNotFoundException);
154 
155     exception = null;
156     try {
157       this.admin.deleteTable(nonexistent);
158     } catch (IOException e) {
159       exception = e;
160     }
161     assertTrue(exception instanceof TableNotFoundException);
162 
163     exception = null;
164     try {
165       this.admin.deleteColumn(nonexistent, nonexistent);
166     } catch (IOException e) {
167       exception = e;
168     }
169     assertTrue(exception instanceof TableNotFoundException);
170 
171     exception = null;
172     try {
173       this.admin.disableTable(nonexistent);
174     } catch (IOException e) {
175       exception = e;
176     }
177     assertTrue(exception instanceof TableNotFoundException);
178 
179     exception = null;
180     try {
181       this.admin.enableTable(nonexistent);
182     } catch (IOException e) {
183       exception = e;
184     }
185     assertTrue(exception instanceof TableNotFoundException);
186 
187     exception = null;
188     try {
189       this.admin.modifyColumn(nonexistent, nonexistentHcd);
190     } catch (IOException e) {
191       exception = e;
192     }
193     assertTrue(exception instanceof TableNotFoundException);
194 
195     exception = null;
196     try {
197       HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(nonexistent));
198       this.admin.modifyTable(htd.getTableName(), htd);
199     } catch (IOException e) {
200       exception = e;
201     }
202     assertTrue(exception instanceof TableNotFoundException);
203 
204     // Now make it so at least the table exists and then do tests against a
205     // nonexistent column family -- see if we get right exceptions.
206     final String tableName =
207         "testDeleteEditUnknownColumnFamilyAndOrTable" + System.currentTimeMillis();
208     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName));
209     htd.addFamily(new HColumnDescriptor("cf"));
210     this.admin.createTable(htd);
211     try {
212       exception = null;
213       try {
214         this.admin.deleteColumn(htd.getTableName(), nonexistentHcd.getName());
215       } catch (IOException e) {
216         exception = e;
217       }
218       assertTrue("found=" + exception.getClass().getName(),
219           exception instanceof InvalidFamilyOperationException);
220 
221       exception = null;
222       try {
223         this.admin.modifyColumn(htd.getTableName(), nonexistentHcd);
224       } catch (IOException e) {
225         exception = e;
226       }
227       assertTrue("found=" + exception.getClass().getName(),
228           exception instanceof InvalidFamilyOperationException);
229     } finally {
230       this.admin.disableTable(tableName);
231       this.admin.deleteTable(tableName);
232     }
233   }
234 
235   @Test (timeout=300000)
236   public void testDisableAndEnableTable() throws IOException {
237     final byte [] row = Bytes.toBytes("row");
238     final byte [] qualifier = Bytes.toBytes("qualifier");
239     final byte [] value = Bytes.toBytes("value");
240     final byte [] table = Bytes.toBytes("testDisableAndEnableTable");
241     HTable ht = TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
242     Put put = new Put(row);
243     put.add(HConstants.CATALOG_FAMILY, qualifier, value);
244     ht.put(put);
245     Get get = new Get(row);
246     get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
247     ht.get(get);
248 
249     this.admin.disableTable(ht.getName());
250     assertTrue("Table must be disabled.", TEST_UTIL.getHBaseCluster()
251         .getMaster().getAssignmentManager().getZKTable().isDisabledTable(
252             ht.getName()));
253 
254     // Test that table is disabled
255     get = new Get(row);
256     get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
257     boolean ok = false;
258     try {
259       ht.get(get);
260     } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
261       ok = true;
262     }
263     assertTrue(ok);
264     this.admin.enableTable(table);
265     assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster()
266         .getMaster().getAssignmentManager().getZKTable().isEnabledTable(
267             ht.getName()));
268 
269     // Test that table is enabled
270     try {
271       ht.get(get);
272     } catch (RetriesExhaustedException e) {
273       ok = false;
274     }
275     assertTrue(ok);
276     ht.close();
277   }
278 
279   @Test (timeout=300000)
280   public void testDisableAndEnableTables() throws IOException {
281     final byte [] row = Bytes.toBytes("row");
282     final byte [] qualifier = Bytes.toBytes("qualifier");
283     final byte [] value = Bytes.toBytes("value");
284     final byte [] table1 = Bytes.toBytes("testDisableAndEnableTable1");
285     final byte [] table2 = Bytes.toBytes("testDisableAndEnableTable2");
286     HTable ht1 = TEST_UTIL.createTable(table1, HConstants.CATALOG_FAMILY);
287     HTable ht2 = TEST_UTIL.createTable(table2, HConstants.CATALOG_FAMILY);
288     Put put = new Put(row);
289     put.add(HConstants.CATALOG_FAMILY, qualifier, value);
290     ht1.put(put);
291     ht2.put(put);
292     Get get = new Get(row);
293     get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
294     ht1.get(get);
295     ht2.get(get);
296 
297     this.admin.disableTables("testDisableAndEnableTable.*");
298 
299     // Test that tables are disabled
300     get = new Get(row);
301     get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
302     boolean ok = false;
303     try {
304       ht1.get(get);
305       ht2.get(get);
306     } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
307       ok = true;
308     }
309 
310     assertTrue(ok);
311     this.admin.enableTables("testDisableAndEnableTable.*");
312 
313     // Test that tables are enabled
314     try {
315       ht1.get(get);
316     } catch (IOException e) {
317       ok = false;
318     }
319     try {
320       ht2.get(get);
321     } catch (IOException e) {
322       ok = false;
323     }
324     assertTrue(ok);
325 
326     ht1.close();
327     ht2.close();
328   }
329 
330   @Test (timeout=300000)
331   public void testCreateTable() throws IOException {
332     HTableDescriptor [] tables = admin.listTables();
333     int numTables = tables.length;
334     TEST_UTIL.createTable(Bytes.toBytes("testCreateTable"),
335       HConstants.CATALOG_FAMILY).close();
336     tables = this.admin.listTables();
337     assertEquals(numTables + 1, tables.length);
338     assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster()
339         .getMaster().getAssignmentManager().getZKTable().isEnabledTable(
340             TableName.valueOf("testCreateTable")));
341   }
342 
343   @Test (timeout=300000)
344   public void testGetTableDescriptor() throws IOException {
345     HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
346     HColumnDescriptor fam2 = new HColumnDescriptor("fam2");
347     HColumnDescriptor fam3 = new HColumnDescriptor("fam3");
348     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("myTestTable"));
349     htd.addFamily(fam1);
350     htd.addFamily(fam2);
351     htd.addFamily(fam3);
352     this.admin.createTable(htd);
353     HTable table = new HTable(TEST_UTIL.getConfiguration(), "myTestTable");
354     HTableDescriptor confirmedHtd = table.getTableDescriptor();
355     assertEquals(htd.compareTo(confirmedHtd), 0);
356     table.close();
357   }
358 
359   @Test (timeout=300000)
360   public void testHColumnValidName() {
361        boolean exceptionThrown;
362        try {
363          new HColumnDescriptor("\\test\\abc");
364        } catch(IllegalArgumentException iae) {
365            exceptionThrown = true;
366            assertTrue(exceptionThrown);
367        }
368    }
369   
370   /**
371    * Verify schema modification takes.
372    * @throws IOException
373    * @throws InterruptedException
374    */
375   @Test (timeout=300000)
376   public void testOnlineChangeTableSchema() throws IOException, InterruptedException {
377     final TableName tableName =
378         TableName.valueOf("changeTableSchemaOnline");
379     TEST_UTIL.getMiniHBaseCluster().getMaster().getConfiguration().setBoolean(
380         "hbase.online.schema.update.enable", true);
381     HTableDescriptor [] tables = admin.listTables();
382     int numTables = tables.length;
383     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
384     tables = this.admin.listTables();
385     assertEquals(numTables + 1, tables.length);
386 
387     // FIRST, do htabledescriptor changes.
388     HTableDescriptor htd = this.admin.getTableDescriptor(tableName);
389     // Make a copy and assert copy is good.
390     HTableDescriptor copy = new HTableDescriptor(htd);
391     assertTrue(htd.equals(copy));
392     // Now amend the copy. Introduce differences.
393     long newFlushSize = htd.getMemStoreFlushSize() / 2;
394     if (newFlushSize <=0) {
395       newFlushSize = HTableDescriptor.DEFAULT_MEMSTORE_FLUSH_SIZE / 2;
396     }
397     copy.setMemStoreFlushSize(newFlushSize);
398     final String key = "anyoldkey";
399     assertTrue(htd.getValue(key) == null);
400     copy.setValue(key, key);
401     boolean expectedException = false;
402     try {
403       admin.modifyTable(tableName, copy);
404     } catch (TableNotDisabledException re) {
405       expectedException = true;
406     }
407     assertFalse(expectedException);
408     HTableDescriptor modifiedHtd = this.admin.getTableDescriptor(tableName);
409     assertFalse(htd.equals(modifiedHtd));
410     assertTrue(copy.equals(modifiedHtd));
411     assertEquals(newFlushSize, modifiedHtd.getMemStoreFlushSize());
412     assertEquals(key, modifiedHtd.getValue(key));
413 
414     // Now work on column family changes.
415     int countOfFamilies = modifiedHtd.getFamilies().size();
416     assertTrue(countOfFamilies > 0);
417     HColumnDescriptor hcd = modifiedHtd.getFamilies().iterator().next();
418     int maxversions = hcd.getMaxVersions();
419     final int newMaxVersions = maxversions + 1;
420     hcd.setMaxVersions(newMaxVersions);
421     final byte [] hcdName = hcd.getName();
422     expectedException = false;
423     try {
424       this.admin.modifyColumn(tableName, hcd);
425     } catch (TableNotDisabledException re) {
426       expectedException = true;
427     }
428     assertFalse(expectedException);
429     modifiedHtd = this.admin.getTableDescriptor(tableName);
430     HColumnDescriptor modifiedHcd = modifiedHtd.getFamily(hcdName);
431     assertEquals(newMaxVersions, modifiedHcd.getMaxVersions());
432 
433     // Try adding a column
434     assertFalse(this.admin.isTableDisabled(tableName));
435     final String xtracolName = "xtracol";
436     HColumnDescriptor xtracol = new HColumnDescriptor(xtracolName);
437     xtracol.setValue(xtracolName, xtracolName);
438     expectedException = false;
439     try {
440       this.admin.addColumn(tableName, xtracol);
441     } catch (TableNotDisabledException re) {
442       expectedException = true;
443     }
444     // Add column should work even if the table is enabled
445     assertFalse(expectedException);
446     modifiedHtd = this.admin.getTableDescriptor(tableName);
447     hcd = modifiedHtd.getFamily(xtracol.getName());
448     assertTrue(hcd != null);
449     assertTrue(hcd.getValue(xtracolName).equals(xtracolName));
450 
451     // Delete the just-added column.
452     this.admin.deleteColumn(tableName, xtracol.getName());
453     modifiedHtd = this.admin.getTableDescriptor(tableName);
454     hcd = modifiedHtd.getFamily(xtracol.getName());
455     assertTrue(hcd == null);
456 
457     // Delete the table
458     this.admin.disableTable(tableName);
459     this.admin.deleteTable(tableName);
460     this.admin.listTables();
461     assertFalse(this.admin.tableExists(tableName));
462   }
463 
464   @Test (timeout=300000)
465   public void testShouldFailOnlineSchemaUpdateIfOnlineSchemaIsNotEnabled()
466       throws Exception {
467     final byte[] tableName = Bytes.toBytes("changeTableSchemaOnlineFailure");
468     TEST_UTIL.getMiniHBaseCluster().getMaster().getConfiguration().setBoolean(
469         "hbase.online.schema.update.enable", false);
470     HTableDescriptor[] tables = admin.listTables();
471     int numTables = tables.length;
472     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
473     tables = this.admin.listTables();
474     assertEquals(numTables + 1, tables.length);
475 
476     // FIRST, do htabledescriptor changes.
477     HTableDescriptor htd = this.admin.getTableDescriptor(tableName);
478     // Make a copy and assert copy is good.
479     HTableDescriptor copy = new HTableDescriptor(htd);
480     assertTrue(htd.equals(copy));
481     // Now amend the copy. Introduce differences.
482     long newFlushSize = htd.getMemStoreFlushSize() / 2;
483     if (newFlushSize <=0) {
484       newFlushSize = HTableDescriptor.DEFAULT_MEMSTORE_FLUSH_SIZE / 2;
485     }
486     copy.setMemStoreFlushSize(newFlushSize);
487     final String key = "anyoldkey";
488     assertTrue(htd.getValue(key) == null);
489     copy.setValue(key, key);
490     boolean expectedException = false;
491     try {
492       admin.modifyTable(tableName, copy);
493     } catch (TableNotDisabledException re) {
494       expectedException = true;
495     }
496     assertTrue("Online schema update should not happen.", expectedException);
497 
498     // Reset the value for the other tests
499     TEST_UTIL.getMiniHBaseCluster().getMaster().getConfiguration().setBoolean(
500         "hbase.online.schema.update.enable", true);
501   }
502 
503   /**
504    * Listens for when an event is done in Master.
505    */
506   static class DoneListener implements EventHandler.EventHandlerListener {
507     private final AtomicBoolean done;
508 
509     DoneListener(final AtomicBoolean done) {
510       super();
511       this.done = done;
512     }
513 
514     @Override
515     public void afterProcess(EventHandler event) {
516       this.done.set(true);
517       synchronized (this.done) {
518         // Wake anyone waiting on this value to change.
519         this.done.notifyAll();
520       }
521     }
522 
523     @Override
524     public void beforeProcess(EventHandler event) {
525       // continue
526     }
527   }
528 
529   @SuppressWarnings("deprecation")
530   protected void verifyRoundRobinDistribution(HTable ht, int expectedRegions) throws IOException {
531     int numRS = ht.getConnection().getCurrentNrHRS();
532     Map<HRegionInfo, ServerName> regions = ht.getRegionLocations();
533     Map<ServerName, List<HRegionInfo>> server2Regions = new HashMap<ServerName, List<HRegionInfo>>();
534     for (Map.Entry<HRegionInfo, ServerName> entry : regions.entrySet()) {
535       ServerName server = entry.getValue();
536       List<HRegionInfo> regs = server2Regions.get(server);
537       if (regs == null) {
538         regs = new ArrayList<HRegionInfo>();
539         server2Regions.put(server, regs);
540       }
541       regs.add(entry.getKey());
542     }
543     float average = (float) expectedRegions/numRS;
544     int min = (int)Math.floor(average);
545     int max = (int)Math.ceil(average);
546     for (List<HRegionInfo> regionList : server2Regions.values()) {
547       assertTrue(regionList.size() == min || regionList.size() == max);
548     }
549   }
550 
551   @Test (timeout=300000)
552   public void testCreateTableNumberOfRegions() throws IOException, InterruptedException {
553     byte[] tableName = Bytes.toBytes("testCreateTableNumberOfRegions");
554     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
555     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
556     admin.createTable(desc);
557     HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
558     Map<HRegionInfo, ServerName> regions = ht.getRegionLocations();
559     assertEquals("Table should have only 1 region", 1, regions.size());
560     ht.close();
561 
562     byte [] TABLE_2 = Bytes.add(tableName, Bytes.toBytes("_2"));
563     desc = new HTableDescriptor(TableName.valueOf(TABLE_2));
564     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
565     admin.createTable(desc, new byte[][]{new byte[]{42}});
566     HTable ht2 = new HTable(TEST_UTIL.getConfiguration(), TABLE_2);
567     regions = ht2.getRegionLocations();
568     assertEquals("Table should have only 2 region", 2, regions.size());
569     ht2.close();
570 
571     byte [] TABLE_3 = Bytes.add(tableName, Bytes.toBytes("_3"));
572     desc = new HTableDescriptor(TableName.valueOf(TABLE_3));
573     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
574     admin.createTable(desc, "a".getBytes(), "z".getBytes(), 3);
575     HTable ht3 = new HTable(TEST_UTIL.getConfiguration(), TABLE_3);
576     regions = ht3.getRegionLocations();
577     assertEquals("Table should have only 3 region", 3, regions.size());
578     ht3.close();
579 
580     byte [] TABLE_4 = Bytes.add(tableName, Bytes.toBytes("_4"));
581     desc = new HTableDescriptor(TableName.valueOf(TABLE_4));
582     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
583     try {
584       admin.createTable(desc, "a".getBytes(), "z".getBytes(), 2);
585       fail("Should not be able to create a table with only 2 regions using this API.");
586     } catch (IllegalArgumentException eae) {
587     // Expected
588     }
589 
590     byte [] TABLE_5 = Bytes.add(tableName, Bytes.toBytes("_5"));
591     desc = new HTableDescriptor(TableName.valueOf(TABLE_5));
592     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
593     admin.createTable(desc, new byte[] {1}, new byte[] {127}, 16);
594     HTable ht5 = new HTable(TEST_UTIL.getConfiguration(), TABLE_5);
595     regions = ht5.getRegionLocations();
596     assertEquals("Table should have 16 region", 16, regions.size());
597     ht5.close();
598   }
599 
600   @Test (timeout=300000)
601   public void testCreateTableWithRegions() throws IOException, InterruptedException {
602 
603     byte[] tableName = Bytes.toBytes("testCreateTableWithRegions");
604 
605     byte [][] splitKeys = {
606         new byte [] { 1, 1, 1 },
607         new byte [] { 2, 2, 2 },
608         new byte [] { 3, 3, 3 },
609         new byte [] { 4, 4, 4 },
610         new byte [] { 5, 5, 5 },
611         new byte [] { 6, 6, 6 },
612         new byte [] { 7, 7, 7 },
613         new byte [] { 8, 8, 8 },
614         new byte [] { 9, 9, 9 },
615     };
616     int expectedRegions = splitKeys.length + 1;
617 
618     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
619     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
620     admin.createTable(desc, splitKeys);
621 
622     boolean tableAvailable = admin.isTableAvailable(Bytes.toString(tableName), splitKeys);
623     assertTrue("Table should be created with splitKyes + 1 rows in META", tableAvailable);
624 
625     HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
626     Map<HRegionInfo, ServerName> regions = ht.getRegionLocations();
627     assertEquals("Tried to create " + expectedRegions + " regions " +
628         "but only found " + regions.size(),
629         expectedRegions, regions.size());
630     System.err.println("Found " + regions.size() + " regions");
631 
632     Iterator<HRegionInfo> hris = regions.keySet().iterator();
633     HRegionInfo hri = hris.next();
634     assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0);
635     assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[0]));
636     hri = hris.next();
637     assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[0]));
638     assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[1]));
639     hri = hris.next();
640     assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[1]));
641     assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[2]));
642     hri = hris.next();
643     assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[2]));
644     assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[3]));
645     hri = hris.next();
646     assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[3]));
647     assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[4]));
648     hri = hris.next();
649     assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[4]));
650     assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[5]));
651     hri = hris.next();
652     assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[5]));
653     assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[6]));
654     hri = hris.next();
655     assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[6]));
656     assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[7]));
657     hri = hris.next();
658     assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[7]));
659     assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[8]));
660     hri = hris.next();
661     assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[8]));
662     assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0);
663 
664     verifyRoundRobinDistribution(ht, expectedRegions);
665     ht.close();
666 
667     // Now test using start/end with a number of regions
668 
669     // Use 80 bit numbers to make sure we aren't limited
670     byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
671     byte [] endKey =   { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
672 
673     // Splitting into 10 regions, we expect (null,1) ... (9, null)
674     // with (1,2) (2,3) (3,4) (4,5) (5,6) (6,7) (7,8) (8,9) in the middle
675 
676     expectedRegions = 10;
677 
678     byte [] TABLE_2 = Bytes.add(tableName, Bytes.toBytes("_2"));
679 
680     desc = new HTableDescriptor(TableName.valueOf(TABLE_2));
681     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
682     admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
683     admin.createTable(desc, startKey, endKey, expectedRegions);
684 
685     HTable ht2 = new HTable(TEST_UTIL.getConfiguration(), TABLE_2);
686     regions = ht2.getRegionLocations();
687     assertEquals("Tried to create " + expectedRegions + " regions " +
688         "but only found " + regions.size(),
689         expectedRegions, regions.size());
690     System.err.println("Found " + regions.size() + " regions");
691 
692     hris = regions.keySet().iterator();
693     hri = hris.next();
694     assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0);
695     assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {1,1,1,1,1,1,1,1,1,1}));
696     hri = hris.next();
697     assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {1,1,1,1,1,1,1,1,1,1}));
698     assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {2,2,2,2,2,2,2,2,2,2}));
699     hri = hris.next();
700     assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {2,2,2,2,2,2,2,2,2,2}));
701     assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {3,3,3,3,3,3,3,3,3,3}));
702     hri = hris.next();
703     assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {3,3,3,3,3,3,3,3,3,3}));
704     assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {4,4,4,4,4,4,4,4,4,4}));
705     hri = hris.next();
706     assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {4,4,4,4,4,4,4,4,4,4}));
707     assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {5,5,5,5,5,5,5,5,5,5}));
708     hri = hris.next();
709     assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {5,5,5,5,5,5,5,5,5,5}));
710     assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {6,6,6,6,6,6,6,6,6,6}));
711     hri = hris.next();
712     assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {6,6,6,6,6,6,6,6,6,6}));
713     assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {7,7,7,7,7,7,7,7,7,7}));
714     hri = hris.next();
715     assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {7,7,7,7,7,7,7,7,7,7}));
716     assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {8,8,8,8,8,8,8,8,8,8}));
717     hri = hris.next();
718     assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {8,8,8,8,8,8,8,8,8,8}));
719     assertTrue(Bytes.equals(hri.getEndKey(), new byte [] {9,9,9,9,9,9,9,9,9,9}));
720     hri = hris.next();
721     assertTrue(Bytes.equals(hri.getStartKey(), new byte [] {9,9,9,9,9,9,9,9,9,9}));
722     assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0);
723 
724     verifyRoundRobinDistribution(ht2, expectedRegions);
725     ht2.close();
726 
727     // Try once more with something that divides into something infinite
728 
729     startKey = new byte [] { 0, 0, 0, 0, 0, 0 };
730     endKey = new byte [] { 1, 0, 0, 0, 0, 0 };
731 
732     expectedRegions = 5;
733 
734     byte [] TABLE_3 = Bytes.add(tableName, Bytes.toBytes("_3"));
735 
736     desc = new HTableDescriptor(TableName.valueOf(TABLE_3));
737     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
738     admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
739     admin.createTable(desc, startKey, endKey, expectedRegions);
740 
741 
742     HTable ht3 = new HTable(TEST_UTIL.getConfiguration(), TABLE_3);
743     regions = ht3.getRegionLocations();
744     assertEquals("Tried to create " + expectedRegions + " regions " +
745         "but only found " + regions.size(),
746         expectedRegions, regions.size());
747     System.err.println("Found " + regions.size() + " regions");
748 
749     verifyRoundRobinDistribution(ht3, expectedRegions);
750     ht3.close();
751 
752 
753     // Try an invalid case where there are duplicate split keys
754     splitKeys = new byte [][] {
755         new byte [] { 1, 1, 1 },
756         new byte [] { 2, 2, 2 },
757         new byte [] { 3, 3, 3 },
758         new byte [] { 2, 2, 2 }
759     };
760 
761     byte [] TABLE_4 = Bytes.add(tableName, Bytes.toBytes("_4"));
762     desc = new HTableDescriptor(TableName.valueOf(TABLE_4));
763     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
764     HBaseAdmin ladmin = new HBaseAdmin(TEST_UTIL.getConfiguration());
765     try {
766       ladmin.createTable(desc, splitKeys);
767       assertTrue("Should not be able to create this table because of " +
768           "duplicate split keys", false);
769     } catch(IllegalArgumentException iae) {
770       // Expected
771     }
772     ladmin.close();
773   }
774 
775   @Test (timeout=300000)
776   public void testTableAvailableWithRandomSplitKeys() throws Exception {
777     byte[] tableName = Bytes.toBytes("testTableAvailableWithRandomSplitKeys");
778     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
779     desc.addFamily(new HColumnDescriptor("col"));
780     byte[][] splitKeys = new byte[1][];
781     splitKeys = new byte [][] {
782         new byte [] { 1, 1, 1 },
783         new byte [] { 2, 2, 2 }
784     };
785     admin.createTable(desc);
786     boolean tableAvailable = admin.isTableAvailable(Bytes.toString(tableName), splitKeys);
787     assertFalse("Table should be created with 1 row in META", tableAvailable);
788   }
789 
790   @Test (timeout=300000)
791   public void testCreateTableWithOnlyEmptyStartRow() throws IOException {
792     byte[] tableName = Bytes.toBytes("testCreateTableWithOnlyEmptyStartRow");
793     byte[][] splitKeys = new byte[1][];
794     splitKeys[0] = HConstants.EMPTY_BYTE_ARRAY;
795     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
796     desc.addFamily(new HColumnDescriptor("col"));
797     try {
798       admin.createTable(desc, splitKeys);
799       fail("Test case should fail as empty split key is passed.");
800     } catch (IllegalArgumentException e) {
801     }
802   }
803 
804   @Test (timeout=300000)
805   public void testCreateTableWithEmptyRowInTheSplitKeys() throws IOException{
806     byte[] tableName = Bytes.toBytes("testCreateTableWithEmptyRowInTheSplitKeys");
807     byte[][] splitKeys = new byte[3][];
808     splitKeys[0] = "region1".getBytes();
809     splitKeys[1] = HConstants.EMPTY_BYTE_ARRAY;
810     splitKeys[2] = "region2".getBytes();
811     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
812     desc.addFamily(new HColumnDescriptor("col"));
813     try {
814       admin.createTable(desc, splitKeys);
815       fail("Test case should fail as empty split key is passed.");
816     } catch (IllegalArgumentException e) {
817       LOG.info("Expected ", e);
818     }
819   }
820 
821   @Test (timeout=120000)
822   public void testTableExist() throws IOException {
823     final byte [] table = Bytes.toBytes("testTableExist");
824     boolean exist;
825     exist = this.admin.tableExists(table);
826     assertEquals(false, exist);
827     TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
828     exist = this.admin.tableExists(table);
829     assertEquals(true, exist);
830   }
831 
832   /**
833    * Tests forcing split from client and having scanners successfully ride over split.
834    * @throws Exception
835    * @throws IOException
836    */
837   @Test (timeout=300000)
838   public void testForceSplit() throws Exception {
839     byte[][] familyNames = new byte[][] { Bytes.toBytes("cf") };
840     int[] rowCounts = new int[] { 6000 };
841     int numVersions = HColumnDescriptor.DEFAULT_VERSIONS;
842     int blockSize = 256;
843     splitTest(null, familyNames, rowCounts, numVersions, blockSize);
844 
845     byte[] splitKey = Bytes.toBytes(3500);
846     splitTest(splitKey, familyNames, rowCounts, numVersions, blockSize);
847   }
848 
849   /**
850    * Test retain assignment on enableTable.
851    *
852    * @throws IOException
853    */
854   @Test (timeout=300000)
855   public void testEnableTableRetainAssignment() throws IOException {
856     byte[] tableName = Bytes.toBytes("testEnableTableAssignment");
857     byte[][] splitKeys = { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 },
858         new byte[] { 3, 3, 3 }, new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 },
859         new byte[] { 6, 6, 6 }, new byte[] { 7, 7, 7 }, new byte[] { 8, 8, 8 },
860         new byte[] { 9, 9, 9 } };
861     int expectedRegions = splitKeys.length + 1;
862     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
863     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
864     admin.createTable(desc, splitKeys);
865     HTable ht = new HTable(TEST_UTIL.getConfiguration(), tableName);
866     Map<HRegionInfo, ServerName> regions = ht.getRegionLocations();
867     ht.close();
868     assertEquals("Tried to create " + expectedRegions + " regions "
869         + "but only found " + regions.size(), expectedRegions, regions.size());
870     // Disable table.
871     admin.disableTable(tableName);
872     // Enable table, use retain assignment to assign regions.
873     admin.enableTable(tableName);
874     Map<HRegionInfo, ServerName> regions2 = ht.getRegionLocations();
875 
876     // Check the assignment.
877     assertEquals(regions.size(), regions2.size());
878     for (Map.Entry<HRegionInfo, ServerName> entry : regions.entrySet()) {
879       assertEquals(regions2.get(entry.getKey()), entry.getValue());
880     }
881   }
882 
883   /**
884    * Multi-family scenario. Tests forcing split from client and
885    * having scanners successfully ride over split.
886    * @throws Exception
887    * @throws IOException
888    */
889   @Test (timeout=300000)
890   public void testForceSplitMultiFamily() throws Exception {
891     int numVersions = HColumnDescriptor.DEFAULT_VERSIONS;
892 
893     // use small HFile block size so that we can have lots of blocks in HFile
894     // Otherwise, if there is only one block,
895     // HFileBlockIndex.midKey()'s value == startKey
896     int blockSize = 256;
897     byte[][] familyNames = new byte[][] { Bytes.toBytes("cf1"),
898       Bytes.toBytes("cf2") };
899 
900     // one of the column families isn't splittable
901     int[] rowCounts = new int[] { 6000, 1 };
902     splitTest(null, familyNames, rowCounts, numVersions, blockSize);
903 
904     rowCounts = new int[] { 1, 6000 };
905     splitTest(null, familyNames, rowCounts, numVersions, blockSize);
906 
907     // one column family has much smaller data than the other
908     // the split key should be based on the largest column family
909     rowCounts = new int[] { 6000, 300 };
910     splitTest(null, familyNames, rowCounts, numVersions, blockSize);
911 
912     rowCounts = new int[] { 300, 6000 };
913     splitTest(null, familyNames, rowCounts, numVersions, blockSize);
914 
915   }
916 
917   void splitTest(byte[] splitPoint, byte[][] familyNames, int[] rowCounts,
918     int numVersions, int blockSize) throws Exception {
919     TableName tableName = TableName.valueOf("testForceSplit");
920     StringBuilder sb = new StringBuilder();
921     // Add tail to String so can see better in logs where a test is running.
922     for (int i = 0; i < rowCounts.length; i++) {
923       sb.append("_").append(Integer.toString(rowCounts[i]));
924     }
925     assertFalse(admin.tableExists(tableName));
926     final HTable table = TEST_UTIL.createTable(tableName, familyNames,
927       numVersions, blockSize);
928 
929     int rowCount = 0;
930     byte[] q = new byte[0];
931 
932     // insert rows into column families. The number of rows that have values
933     // in a specific column family is decided by rowCounts[familyIndex]
934     for (int index = 0; index < familyNames.length; index++) {
935       ArrayList<Put> puts = new ArrayList<Put>(rowCounts[index]);
936       for (int i = 0; i < rowCounts[index]; i++) {
937         byte[] k = Bytes.toBytes(i);
938         Put put = new Put(k);
939         put.add(familyNames[index], q, k);
940         puts.add(put);
941       }
942       table.put(puts);
943 
944       if ( rowCount < rowCounts[index] ) {
945         rowCount = rowCounts[index];
946       }
947     }
948 
949     // get the initial layout (should just be one region)
950     Map<HRegionInfo, ServerName> m = table.getRegionLocations();
951     LOG.info("Initial regions (" + m.size() + "): " + m);
952     assertTrue(m.size() == 1);
953 
954     // Verify row count
955     Scan scan = new Scan();
956     ResultScanner scanner = table.getScanner(scan);
957     int rows = 0;
958     for(@SuppressWarnings("unused") Result result : scanner) {
959       rows++;
960     }
961     scanner.close();
962     assertEquals(rowCount, rows);
963 
964     // Have an outstanding scan going on to make sure we can scan over splits.
965     scan = new Scan();
966     scanner = table.getScanner(scan);
967     // Scan first row so we are into first region before split happens.
968     scanner.next();
969 
970     // Split the table
971     this.admin.split(tableName.getName(), splitPoint);
972 
973     final AtomicInteger count = new AtomicInteger(0);
974     Thread t = new Thread("CheckForSplit") {
975       public void run() {
976         for (int i = 0; i < 20; i++) {
977           try {
978             sleep(1000);
979           } catch (InterruptedException e) {
980             continue;
981           }
982           // check again    table = new HTable(conf, tableName);
983           Map<HRegionInfo, ServerName> regions = null;
984           try {
985             regions = table.getRegionLocations();
986           } catch (IOException e) {
987             e.printStackTrace();
988           }
989           if (regions == null) continue;
990           count.set(regions.size());
991           if (count.get() >= 2) {
992             LOG.info("Found: " + regions);
993             break;
994           }
995           LOG.debug("Cycle waiting on split");
996         }
997         LOG.debug("CheckForSplit thread exited, current region count: " + count.get());
998       }
999     };
1000     t.setPriority(Thread.NORM_PRIORITY - 2);
1001     t.start();
1002     t.join();
1003 
1004     // Verify row count
1005     rows = 1; // We counted one row above.
1006     for (@SuppressWarnings("unused") Result result : scanner) {
1007       rows++;
1008       if (rows > rowCount) {
1009         scanner.close();
1010         assertTrue("Scanned more than expected (" + rowCount + ")", false);
1011       }
1012     }
1013     scanner.close();
1014     assertEquals(rowCount, rows);
1015 
1016     Map<HRegionInfo, ServerName> regions = null;
1017     try {
1018       regions = table.getRegionLocations();
1019     } catch (IOException e) {
1020       e.printStackTrace();
1021     }
1022     assertEquals(2, regions.size());
1023     Set<HRegionInfo> hRegionInfos = regions.keySet();
1024     HRegionInfo[] r = hRegionInfos.toArray(new HRegionInfo[hRegionInfos.size()]);
1025     if (splitPoint != null) {
1026       // make sure the split point matches our explicit configuration
1027       assertEquals(Bytes.toString(splitPoint),
1028           Bytes.toString(r[0].getEndKey()));
1029       assertEquals(Bytes.toString(splitPoint),
1030           Bytes.toString(r[1].getStartKey()));
1031       LOG.debug("Properly split on " + Bytes.toString(splitPoint));
1032     } else {
1033       if (familyNames.length > 1) {
1034         int splitKey = Bytes.toInt(r[0].getEndKey());
1035         // check if splitKey is based on the largest column family
1036         // in terms of it store size
1037         int deltaForLargestFamily = Math.abs(rowCount/2 - splitKey);
1038         LOG.debug("SplitKey=" + splitKey + "&deltaForLargestFamily=" + deltaForLargestFamily +
1039           ", r=" + r[0]);
1040         for (int index = 0; index < familyNames.length; index++) {
1041           int delta = Math.abs(rowCounts[index]/2 - splitKey);
1042           if (delta < deltaForLargestFamily) {
1043             assertTrue("Delta " + delta + " for family " + index
1044               + " should be at least deltaForLargestFamily " + deltaForLargestFamily,
1045               false);
1046           }
1047         }
1048       }
1049     }
1050     TEST_UTIL.deleteTable(tableName);
1051     table.close();
1052   }
1053 
1054   /**
1055    * HADOOP-2156
1056    * @throws IOException
1057    */
1058   @SuppressWarnings("deprecation")
1059   @Test (expected=IllegalArgumentException.class, timeout=300000)
1060   public void testEmptyHTableDescriptor() throws IOException {
1061     this.admin.createTable(new HTableDescriptor());
1062   }
1063 
1064   @Test (expected=IllegalArgumentException.class, timeout=300000)
1065   public void testInvalidHColumnDescriptor() throws IOException {
1066      new HColumnDescriptor("/cfamily/name");
1067   }
1068 
1069   @Test (timeout=300000)
1070   public void testEnableDisableAddColumnDeleteColumn() throws Exception {
1071     ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(TEST_UTIL);
1072     TableName tableName = TableName.valueOf("testMasterAdmin");
1073     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
1074     while (!ZKTableReadOnly.isEnabledTable(zkw,
1075         TableName.valueOf("testMasterAdmin"))) {
1076       Thread.sleep(10);
1077     }
1078     this.admin.disableTable(tableName);
1079     try {
1080       new HTable(TEST_UTIL.getConfiguration(), tableName);
1081     } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
1082       //expected
1083     }
1084 
1085     this.admin.addColumn(tableName, new HColumnDescriptor("col2"));
1086     this.admin.enableTable(tableName);
1087     try {
1088       this.admin.deleteColumn(tableName, Bytes.toBytes("col2"));
1089     } catch (TableNotDisabledException e) {
1090       LOG.info(e);
1091     }
1092     this.admin.disableTable(tableName);
1093     this.admin.deleteTable(tableName);
1094   }
1095 
1096   @Test (timeout=300000)
1097   public void testCreateBadTables() throws IOException {
1098     String msg = null;
1099     try {
1100       this.admin.createTable(HTableDescriptor.META_TABLEDESC);
1101     } catch(TableExistsException e) {
1102       msg = e.toString();
1103     }
1104     assertTrue("Unexcepted exception message " + msg, msg != null &&
1105       msg.startsWith(TableExistsException.class.getName()) &&
1106       msg.contains(HTableDescriptor.META_TABLEDESC.getTableName().getNameAsString()));
1107 
1108     // Now try and do concurrent creation with a bunch of threads.
1109     final HTableDescriptor threadDesc =
1110       new HTableDescriptor(TableName.valueOf("threaded_testCreateBadTables"));
1111     threadDesc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
1112     int count = 10;
1113     Thread [] threads = new Thread [count];
1114     final AtomicInteger successes = new AtomicInteger(0);
1115     final AtomicInteger failures = new AtomicInteger(0);
1116     final HBaseAdmin localAdmin = this.admin;
1117     for (int i = 0; i < count; i++) {
1118       threads[i] = new Thread(Integer.toString(i)) {
1119         @Override
1120         public void run() {
1121           try {
1122             localAdmin.createTable(threadDesc);
1123             successes.incrementAndGet();
1124           } catch (TableExistsException e) {
1125             failures.incrementAndGet();
1126           } catch (IOException e) {
1127             throw new RuntimeException("Failed threaded create" + getName(), e);
1128           }
1129         }
1130       };
1131     }
1132     for (int i = 0; i < count; i++) {
1133       threads[i].start();
1134     }
1135     for (int i = 0; i < count; i++) {
1136       while(threads[i].isAlive()) {
1137         try {
1138           Thread.sleep(100);
1139         } catch (InterruptedException e) {
1140           // continue
1141         }
1142       }
1143     }
1144     // All threads are now dead.  Count up how many tables were created and
1145     // how many failed w/ appropriate exception.
1146     assertEquals(1, successes.get());
1147     assertEquals(count - 1, failures.get());
1148   }
1149 
1150   /**
1151    * Test for hadoop-1581 'HBASE: Unopenable tablename bug'.
1152    * @throws Exception
1153    */
1154   @Test (timeout=300000)
1155   public void testTableNameClash() throws Exception {
1156     String name = "testTableNameClash";
1157     admin.createTable(new HTableDescriptor(TableName.valueOf(name + "SOMEUPPERCASE")));
1158     admin.createTable(new HTableDescriptor(TableName.valueOf(name)));
1159     // Before fix, below would fail throwing a NoServerForRegionException.
1160     new HTable(TEST_UTIL.getConfiguration(), name).close();
1161   }
1162 
1163   /***
1164    * HMaster.createTable used to be kind of synchronous call
1165    * Thus creating of table with lots of regions can cause RPC timeout
1166    * After the fix to make createTable truly async, RPC timeout shouldn't be an
1167    * issue anymore
1168    * @throws Exception
1169    */
1170   @Test (timeout=300000)
1171   public void testCreateTableRPCTimeOut() throws Exception {
1172     String name = "testCreateTableRPCTimeOut";
1173     int oldTimeout = TEST_UTIL.getConfiguration().
1174       getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
1175     TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500);
1176     try {
1177       int expectedRegions = 100;
1178       // Use 80 bit numbers to make sure we aren't limited
1179       byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
1180       byte [] endKey =   { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
1181       HBaseAdmin hbaseadmin = new HBaseAdmin(TEST_UTIL.getConfiguration());
1182       hbaseadmin.createTable(new HTableDescriptor(TableName.valueOf(name)), startKey, endKey,
1183         expectedRegions);
1184       hbaseadmin.close();
1185     } finally {
1186       TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, oldTimeout);
1187     }
1188   }
1189 
1190   /**
1191    * Test read only tables
1192    * @throws Exception
1193    */
1194   @Test (timeout=300000)
1195   public void testReadOnlyTable() throws Exception {
1196     byte [] name = Bytes.toBytes("testReadOnlyTable");
1197     HTable table = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1198     byte[] value = Bytes.toBytes("somedata");
1199     // This used to use an empty row... That must have been a bug
1200     Put put = new Put(value);
1201     put.add(HConstants.CATALOG_FAMILY, HConstants.CATALOG_FAMILY, value);
1202     table.put(put);
1203     table.close();
1204   }
1205 
1206   /**
1207    * Test that user table names can contain '-' and '.' so long as they do not
1208    * start with same. HBASE-771
1209    * @throws IOException
1210    */
1211   @Test (timeout=300000)
1212   public void testTableNames() throws IOException {
1213     byte[][] illegalNames = new byte[][] {
1214         Bytes.toBytes("-bad"),
1215         Bytes.toBytes(".bad")
1216     };
1217     for (byte[] illegalName : illegalNames) {
1218       try {
1219         new HTableDescriptor(TableName.valueOf(illegalName));
1220         throw new IOException("Did not detect '" +
1221             Bytes.toString(illegalName) + "' as an illegal user table name");
1222       } catch (IllegalArgumentException e) {
1223         // expected
1224       }
1225     }
1226     byte[] legalName = Bytes.toBytes("g-oo.d");
1227     try {
1228       new HTableDescriptor(TableName.valueOf(legalName));
1229     } catch (IllegalArgumentException e) {
1230       throw new IOException("Legal user table name: '" +
1231         Bytes.toString(legalName) + "' caused IllegalArgumentException: " +
1232         e.getMessage());
1233     }
1234   }
1235 
1236   /**
1237    * For HADOOP-2579
1238    * @throws IOException
1239    */
1240   @Test (expected=TableExistsException.class, timeout=300000)
1241   public void testTableExistsExceptionWithATable() throws IOException {
1242     final byte [] name = Bytes.toBytes("testTableExistsExceptionWithATable");
1243     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
1244     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1245   }
1246 
1247   /**
1248    * Can't disable a table if the table isn't in enabled state
1249    * @throws IOException
1250    */
1251   @Test (expected=TableNotEnabledException.class, timeout=300000)
1252   public void testTableNotEnabledExceptionWithATable() throws IOException {
1253     final byte [] name = Bytes.toBytes(
1254       "testTableNotEnabledExceptionWithATable");
1255     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
1256     this.admin.disableTable(name);
1257     this.admin.disableTable(name);
1258   }
1259 
1260   /**
1261    * Can't enable a table if the table isn't in disabled state
1262    * @throws IOException
1263    */
1264   @Test (expected=TableNotDisabledException.class, timeout=300000)
1265   public void testTableNotDisabledExceptionWithATable() throws IOException {
1266     final byte [] name = Bytes.toBytes(
1267       "testTableNotDisabledExceptionWithATable");
1268     HTable t = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1269     try {
1270     this.admin.enableTable(name);
1271     }finally {
1272        t.close();
1273     }
1274   }
1275 
1276   /**
1277    * For HADOOP-2579
1278    * @throws IOException
1279    */
1280   @Test (expected=TableNotFoundException.class, timeout=300000)
1281   public void testTableNotFoundExceptionWithoutAnyTables() throws IOException {
1282     HTable ht =
1283         new HTable(TEST_UTIL.getConfiguration(),"testTableNotFoundExceptionWithoutAnyTables");
1284     ht.get(new Get("e".getBytes()));
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(RpcClient.PING_INTERVAL_NAME, 10 * 1000);
1556     TEST_UTIL.getConfiguration().setInt(RpcClient.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 }