View Javadoc

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