View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.client;
20  
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertFalse;
24  import static org.junit.Assert.assertTrue;
25  import static org.junit.Assert.fail;
26  
27  import java.io.IOException;
28  import java.util.ArrayList;
29  import java.util.Collections;
30  import java.util.Comparator;
31  import java.util.HashMap;
32  import java.util.Iterator;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Set;
36  import java.util.concurrent.atomic.AtomicBoolean;
37  import java.util.concurrent.atomic.AtomicInteger;
38  
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  import org.apache.hadoop.conf.Configuration;
42  import org.apache.hadoop.hbase.HBaseTestingUtility;
43  import org.apache.hadoop.hbase.HColumnDescriptor;
44  import org.apache.hadoop.hbase.HConstants;
45  import org.apache.hadoop.hbase.HRegionInfo;
46  import org.apache.hadoop.hbase.HRegionLocation;
47  import org.apache.hadoop.hbase.HTableDescriptor;
48  import org.apache.hadoop.hbase.InvalidFamilyOperationException;
49  import org.apache.hadoop.hbase.LargeTests;
50  import org.apache.hadoop.hbase.MasterNotRunningException;
51  import org.apache.hadoop.hbase.MiniHBaseCluster;
52  import org.apache.hadoop.hbase.NotServingRegionException;
53  import org.apache.hadoop.hbase.ServerName;
54  import org.apache.hadoop.hbase.TableExistsException;
55  import org.apache.hadoop.hbase.TableName;
56  import org.apache.hadoop.hbase.TableNotDisabledException;
57  import org.apache.hadoop.hbase.TableNotEnabledException;
58  import org.apache.hadoop.hbase.TableNotFoundException;
59  import org.apache.hadoop.hbase.ZooKeeperConnectionException;
60  import org.apache.hadoop.hbase.catalog.CatalogTracker;
61  import org.apache.hadoop.hbase.constraint.ConstraintException;
62  import org.apache.hadoop.hbase.executor.EventHandler;
63  import org.apache.hadoop.hbase.master.AssignmentManager;
64  import org.apache.hadoop.hbase.master.HMaster;
65  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
66  import org.apache.hadoop.hbase.regionserver.HRegion;
67  import org.apache.hadoop.hbase.regionserver.HRegionServer;
68  import org.apache.hadoop.hbase.regionserver.wal.HLogUtilsForTests;
69  import org.apache.hadoop.hbase.util.Bytes;
70  import org.apache.hadoop.hbase.util.Pair;
71  import org.apache.hadoop.hbase.zookeeper.ZKTableReadOnly;
72  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
73  import org.junit.*;
74  import org.junit.experimental.categories.Category;
75  
76  import com.google.protobuf.ServiceException;
77  
78  
79  /**
80   * Class to test HBaseAdmin.
81   * Spins up the minicluster once at test start and then takes it down afterward.
82   * Add any testing of HBaseAdmin functionality here.
83   */
84  @Category(LargeTests.class)
85  public class TestAdmin {
86    final Log LOG = LogFactory.getLog(getClass());
87    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
88    private HBaseAdmin admin;
89  
90    @BeforeClass
91    public static void setUpBeforeClass() throws Exception {
92      TEST_UTIL.getConfiguration().setBoolean("hbase.online.schema.update.enable", true);
93      TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
94      TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
95      TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 6);
96      TEST_UTIL.getConfiguration().setBoolean(
97          "hbase.master.enabletable.roundrobin", true);
98      TEST_UTIL.startMiniCluster(3);
99    }
100 
101   @AfterClass
102   public static void tearDownAfterClass() throws Exception {
103     TEST_UTIL.shutdownMiniCluster();
104   }
105 
106   @Before
107   public void setUp() throws Exception {
108     this.admin = TEST_UTIL.getHBaseAdmin();
109   }
110 
111   @After
112   public void tearDown() throws Exception {
113   }
114 
115   @Test (timeout=300000)
116   public void testSplitFlushCompactUnknownTable() throws InterruptedException {
117     final String unknowntable = "fubar";
118     Exception exception = null;
119     try {
120       this.admin.compact(unknowntable);
121     } catch (IOException e) {
122       exception = e;
123     }
124     assertTrue(exception instanceof TableNotFoundException);
125 
126     exception = null;
127     try {
128       this.admin.flush(unknowntable);
129     } catch (IOException e) {
130       exception = e;
131     }
132     assertTrue(exception instanceof TableNotFoundException);
133 
134     exception = null;
135     try {
136       this.admin.split(unknowntable);
137     } catch (IOException e) {
138       exception = e;
139     }
140     assertTrue(exception instanceof TableNotFoundException);
141   }
142 
143   @Test (timeout=300000)
144   public void testDeleteEditUnknownColumnFamilyAndOrTable() throws IOException {
145     // Test we get exception if we try to
146     final String nonexistent = "nonexistent";
147     HColumnDescriptor nonexistentHcd = new HColumnDescriptor(nonexistent);
148     Exception exception = null;
149     try {
150       this.admin.addColumn(nonexistent, nonexistentHcd);
151     } catch (IOException e) {
152       exception = e;
153     }
154     assertTrue(exception instanceof TableNotFoundException);
155 
156     exception = null;
157     try {
158       this.admin.deleteTable(nonexistent);
159     } catch (IOException e) {
160       exception = e;
161     }
162     assertTrue(exception instanceof TableNotFoundException);
163 
164     exception = null;
165     try {
166       this.admin.deleteColumn(nonexistent, nonexistent);
167     } catch (IOException e) {
168       exception = e;
169     }
170     assertTrue(exception instanceof TableNotFoundException);
171 
172     exception = null;
173     try {
174       this.admin.disableTable(nonexistent);
175     } catch (IOException e) {
176       exception = e;
177     }
178     assertTrue(exception instanceof TableNotFoundException);
179 
180     exception = null;
181     try {
182       this.admin.enableTable(nonexistent);
183     } catch (IOException e) {
184       exception = e;
185     }
186     assertTrue(exception instanceof TableNotFoundException);
187 
188     exception = null;
189     try {
190       this.admin.modifyColumn(nonexistent, nonexistentHcd);
191     } catch (IOException e) {
192       exception = e;
193     }
194     assertTrue(exception instanceof TableNotFoundException);
195 
196     exception = null;
197     try {
198       HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(nonexistent));
199       this.admin.modifyTable(htd.getTableName(), htd);
200     } catch (IOException e) {
201       exception = e;
202     }
203     assertTrue(exception instanceof TableNotFoundException);
204 
205     // Now make it so at least the table exists and then do tests against a
206     // nonexistent column family -- see if we get right exceptions.
207     final String tableName =
208         "testDeleteEditUnknownColumnFamilyAndOrTable" + System.currentTimeMillis();
209     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName));
210     htd.addFamily(new HColumnDescriptor("cf"));
211     this.admin.createTable(htd);
212     try {
213       exception = null;
214       try {
215         this.admin.deleteColumn(htd.getTableName(), nonexistentHcd.getName());
216       } catch (IOException e) {
217         exception = e;
218       }
219       assertTrue("found=" + exception.getClass().getName(),
220           exception instanceof InvalidFamilyOperationException);
221 
222       exception = null;
223       try {
224         this.admin.modifyColumn(htd.getTableName(), nonexistentHcd);
225       } catch (IOException e) {
226         exception = e;
227       }
228       assertTrue("found=" + exception.getClass().getName(),
229           exception instanceof InvalidFamilyOperationException);
230     } finally {
231       this.admin.disableTable(tableName);
232       this.admin.deleteTable(tableName);
233     }
234   }
235 
236   @Test (timeout=300000)
237   public void testDisableAndEnableTable() throws IOException {
238     final byte [] row = Bytes.toBytes("row");
239     final byte [] qualifier = Bytes.toBytes("qualifier");
240     final byte [] value = Bytes.toBytes("value");
241     final byte [] table = Bytes.toBytes("testDisableAndEnableTable");
242     HTable ht = TEST_UTIL.createTable(table, HConstants.CATALOG_FAMILY);
243     Put put = new Put(row);
244     put.add(HConstants.CATALOG_FAMILY, qualifier, value);
245     ht.put(put);
246     Get get = new Get(row);
247     get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
248     ht.get(get);
249 
250     this.admin.disableTable(ht.getName());
251     assertTrue("Table must be disabled.", TEST_UTIL.getHBaseCluster()
252         .getMaster().getAssignmentManager().getZKTable().isDisabledTable(
253             ht.getName()));
254 
255     // Test that table is disabled
256     get = new Get(row);
257     get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
258     boolean ok = false;
259     try {
260       ht.get(get);
261     } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
262       ok = true;
263     }
264     assertTrue(ok);
265     this.admin.enableTable(table);
266     assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster()
267         .getMaster().getAssignmentManager().getZKTable().isEnabledTable(
268             ht.getName()));
269 
270     // Test that table is enabled
271     try {
272       ht.get(get);
273     } catch (RetriesExhaustedException e) {
274       ok = false;
275     }
276     assertTrue(ok);
277     ht.close();
278   }
279 
280   @Test (timeout=300000)
281   public void testDisableAndEnableTables() throws IOException {
282     final byte [] row = Bytes.toBytes("row");
283     final byte [] qualifier = Bytes.toBytes("qualifier");
284     final byte [] value = Bytes.toBytes("value");
285     final byte [] table1 = Bytes.toBytes("testDisableAndEnableTable1");
286     final byte [] table2 = Bytes.toBytes("testDisableAndEnableTable2");
287     HTable ht1 = TEST_UTIL.createTable(table1, HConstants.CATALOG_FAMILY);
288     HTable ht2 = TEST_UTIL.createTable(table2, HConstants.CATALOG_FAMILY);
289     Put put = new Put(row);
290     put.add(HConstants.CATALOG_FAMILY, qualifier, value);
291     ht1.put(put);
292     ht2.put(put);
293     Get get = new Get(row);
294     get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
295     ht1.get(get);
296     ht2.get(get);
297 
298     this.admin.disableTables("testDisableAndEnableTable.*");
299 
300     // Test that tables are disabled
301     get = new Get(row);
302     get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
303     boolean ok = false;
304     try {
305       ht1.get(get);
306       ht2.get(get);
307     } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
308       ok = true;
309     }
310 
311     assertTrue(ok);
312     this.admin.enableTables("testDisableAndEnableTable.*");
313 
314     // Test that tables are enabled
315     try {
316       ht1.get(get);
317     } catch (IOException e) {
318       ok = false;
319     }
320     try {
321       ht2.get(get);
322     } catch (IOException e) {
323       ok = false;
324     }
325     assertTrue(ok);
326 
327     ht1.close();
328     ht2.close();
329   }
330 
331   @Test (timeout=300000)
332   public void testCreateTable() throws IOException {
333     HTableDescriptor [] tables = admin.listTables();
334     int numTables = tables.length;
335     TEST_UTIL.createTable(Bytes.toBytes("testCreateTable"),
336       HConstants.CATALOG_FAMILY).close();
337     tables = this.admin.listTables();
338     assertEquals(numTables + 1, tables.length);
339     assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster()
340         .getMaster().getAssignmentManager().getZKTable().isEnabledTable(
341             TableName.valueOf("testCreateTable")));
342   }
343 
344   @Test (timeout=300000)
345   public void testGetTableDescriptor() throws IOException {
346     HColumnDescriptor fam1 = new HColumnDescriptor("fam1");
347     HColumnDescriptor fam2 = new HColumnDescriptor("fam2");
348     HColumnDescriptor fam3 = new HColumnDescriptor("fam3");
349     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("myTestTable"));
350     htd.addFamily(fam1);
351     htd.addFamily(fam2);
352     htd.addFamily(fam3);
353     this.admin.createTable(htd);
354     HTable table = new HTable(TEST_UTIL.getConfiguration(), "myTestTable");
355     HTableDescriptor confirmedHtd = table.getTableDescriptor();
356     assertEquals(htd.compareTo(confirmedHtd), 0);
357     table.close();
358   }
359 
360   @Test (timeout=300000)
361   public void testHColumnValidName() {
362        boolean exceptionThrown;
363        try {
364          new HColumnDescriptor("\\test\\abc");
365        } catch(IllegalArgumentException iae) {
366            exceptionThrown = true;
367            assertTrue(exceptionThrown);
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 round-robin assignment on enableTable.
851    *
852    * @throws IOException
853    */
854   @Test (timeout=300000)
855   public void testEnableTableRoundRobinAssignment() 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 round-robin assignment to assign regions.
873     admin.enableTable(tableName);
874 
875     // Check the assignment.
876     HTable metaTable = new HTable(TEST_UTIL.getConfiguration(),
877         TableName.META_TABLE_NAME);
878     List<HRegionInfo> regionInfos = admin.getTableRegions(tableName);
879     Map<String, Integer> serverMap = new HashMap<String, Integer>();
880     for (HRegionInfo hri : regionInfos) {
881       Get get = new Get(hri.getRegionName());
882       Result result = metaTable.get(get);
883       String server = Bytes.toString(result.getValue(HConstants.CATALOG_FAMILY,
884           HConstants.SERVER_QUALIFIER));
885       Integer regioncount = serverMap.get(server);
886       if (regioncount == null) {
887         regioncount = 0;
888       }
889       regioncount++;
890       serverMap.put(server, regioncount);
891     }
892     metaTable.close();
893     List<Map.Entry<String, Integer>> entryList = new ArrayList<Map.Entry<String, Integer>>(
894         serverMap.entrySet());
895     Collections.sort(entryList, new Comparator<Map.Entry<String, Integer>>() {
896       public int compare(Map.Entry<String, Integer> oa,
897           Map.Entry<String, Integer> ob) {
898         return (oa.getValue() - ob.getValue());
899       }
900     });
901     assertTrue(entryList.size() == 3);
902     assertTrue((entryList.get(2).getValue() - entryList.get(0).getValue()) < 2);
903   }
904 
905   /**
906    * Multi-family scenario. Tests forcing split from client and
907    * having scanners successfully ride over split.
908    * @throws Exception
909    * @throws IOException
910    */
911   @Test (timeout=300000)
912   public void testForceSplitMultiFamily() throws Exception {
913     int numVersions = HColumnDescriptor.DEFAULT_VERSIONS;
914 
915     // use small HFile block size so that we can have lots of blocks in HFile
916     // Otherwise, if there is only one block,
917     // HFileBlockIndex.midKey()'s value == startKey
918     int blockSize = 256;
919     byte[][] familyNames = new byte[][] { Bytes.toBytes("cf1"),
920       Bytes.toBytes("cf2") };
921 
922     // one of the column families isn't splittable
923     int[] rowCounts = new int[] { 6000, 1 };
924     splitTest(null, familyNames, rowCounts, numVersions, blockSize);
925 
926     rowCounts = new int[] { 1, 6000 };
927     splitTest(null, familyNames, rowCounts, numVersions, blockSize);
928 
929     // one column family has much smaller data than the other
930     // the split key should be based on the largest column family
931     rowCounts = new int[] { 6000, 300 };
932     splitTest(null, familyNames, rowCounts, numVersions, blockSize);
933 
934     rowCounts = new int[] { 300, 6000 };
935     splitTest(null, familyNames, rowCounts, numVersions, blockSize);
936 
937   }
938 
939   void splitTest(byte[] splitPoint, byte[][] familyNames, int[] rowCounts,
940     int numVersions, int blockSize) throws Exception {
941     TableName tableName = TableName.valueOf("testForceSplit");
942     StringBuilder sb = new StringBuilder();
943     // Add tail to String so can see better in logs where a test is running.
944     for (int i = 0; i < rowCounts.length; i++) {
945       sb.append("_").append(Integer.toString(rowCounts[i]));
946     }
947     assertFalse(admin.tableExists(tableName));
948     final HTable table = TEST_UTIL.createTable(tableName, familyNames,
949       numVersions, blockSize);
950 
951     int rowCount = 0;
952     byte[] q = new byte[0];
953 
954     // insert rows into column families. The number of rows that have values
955     // in a specific column family is decided by rowCounts[familyIndex]
956     for (int index = 0; index < familyNames.length; index++) {
957       ArrayList<Put> puts = new ArrayList<Put>(rowCounts[index]);
958       for (int i = 0; i < rowCounts[index]; i++) {
959         byte[] k = Bytes.toBytes(i);
960         Put put = new Put(k);
961         put.add(familyNames[index], q, k);
962         puts.add(put);
963       }
964       table.put(puts);
965 
966       if ( rowCount < rowCounts[index] ) {
967         rowCount = rowCounts[index];
968       }
969     }
970 
971     // get the initial layout (should just be one region)
972     Map<HRegionInfo, ServerName> m = table.getRegionLocations();
973     LOG.info("Initial regions (" + m.size() + "): " + m);
974     assertTrue(m.size() == 1);
975 
976     // Verify row count
977     Scan scan = new Scan();
978     ResultScanner scanner = table.getScanner(scan);
979     int rows = 0;
980     for(@SuppressWarnings("unused") Result result : scanner) {
981       rows++;
982     }
983     scanner.close();
984     assertEquals(rowCount, rows);
985 
986     // Have an outstanding scan going on to make sure we can scan over splits.
987     scan = new Scan();
988     scanner = table.getScanner(scan);
989     // Scan first row so we are into first region before split happens.
990     scanner.next();
991 
992     // Split the table
993     this.admin.split(tableName.getName(), splitPoint);
994 
995     final AtomicInteger count = new AtomicInteger(0);
996     Thread t = new Thread("CheckForSplit") {
997       public void run() {
998         for (int i = 0; i < 20; i++) {
999           try {
1000             sleep(1000);
1001           } catch (InterruptedException e) {
1002             continue;
1003           }
1004           // check again    table = new HTable(conf, tableName);
1005           Map<HRegionInfo, ServerName> regions = null;
1006           try {
1007             regions = table.getRegionLocations();
1008           } catch (IOException e) {
1009             e.printStackTrace();
1010           }
1011           if (regions == null) continue;
1012           count.set(regions.size());
1013           if (count.get() >= 2) {
1014             LOG.info("Found: " + regions);
1015             break;
1016           }
1017           LOG.debug("Cycle waiting on split");
1018         }
1019         LOG.debug("CheckForSplit thread exited, current region count: " + count.get());
1020       }
1021     };
1022     t.setPriority(Thread.NORM_PRIORITY - 2);
1023     t.start();
1024     t.join();
1025 
1026     // Verify row count
1027     rows = 1; // We counted one row above.
1028     for (@SuppressWarnings("unused") Result result : scanner) {
1029       rows++;
1030       if (rows > rowCount) {
1031         scanner.close();
1032         assertTrue("Scanned more than expected (" + rowCount + ")", false);
1033       }
1034     }
1035     scanner.close();
1036     assertEquals(rowCount, rows);
1037 
1038     Map<HRegionInfo, ServerName> regions = null;
1039     try {
1040       regions = table.getRegionLocations();
1041     } catch (IOException e) {
1042       e.printStackTrace();
1043     }
1044     assertEquals(2, regions.size());
1045     Set<HRegionInfo> hRegionInfos = regions.keySet();
1046     HRegionInfo[] r = hRegionInfos.toArray(new HRegionInfo[hRegionInfos.size()]);
1047     if (splitPoint != null) {
1048       // make sure the split point matches our explicit configuration
1049       assertEquals(Bytes.toString(splitPoint),
1050           Bytes.toString(r[0].getEndKey()));
1051       assertEquals(Bytes.toString(splitPoint),
1052           Bytes.toString(r[1].getStartKey()));
1053       LOG.debug("Properly split on " + Bytes.toString(splitPoint));
1054     } else {
1055       if (familyNames.length > 1) {
1056         int splitKey = Bytes.toInt(r[0].getEndKey());
1057         // check if splitKey is based on the largest column family
1058         // in terms of it store size
1059         int deltaForLargestFamily = Math.abs(rowCount/2 - splitKey);
1060         LOG.debug("SplitKey=" + splitKey + "&deltaForLargestFamily=" + deltaForLargestFamily +
1061           ", r=" + r[0]);
1062         for (int index = 0; index < familyNames.length; index++) {
1063           int delta = Math.abs(rowCounts[index]/2 - splitKey);
1064           if (delta < deltaForLargestFamily) {
1065             assertTrue("Delta " + delta + " for family " + index
1066               + " should be at least deltaForLargestFamily " + deltaForLargestFamily,
1067               false);
1068           }
1069         }
1070       }
1071     }
1072     TEST_UTIL.deleteTable(tableName);
1073     table.close();
1074   }
1075 
1076   /**
1077    * HADOOP-2156
1078    * @throws IOException
1079    */
1080   @SuppressWarnings("deprecation")
1081   @Test (expected=IllegalArgumentException.class, timeout=300000)
1082   public void testEmptyHTableDescriptor() throws IOException {
1083     this.admin.createTable(new HTableDescriptor());
1084   }
1085 
1086   @Test (expected=IllegalArgumentException.class, timeout=300000)
1087   public void testInvalidHColumnDescriptor() throws IOException {
1088      new HColumnDescriptor("/cfamily/name");
1089   }
1090 
1091   @Test (timeout=300000)
1092   public void testEnableDisableAddColumnDeleteColumn() throws Exception {
1093     ZooKeeperWatcher zkw = HBaseTestingUtility.getZooKeeperWatcher(TEST_UTIL);
1094     TableName tableName = TableName.valueOf("testMasterAdmin");
1095     TEST_UTIL.createTable(tableName, HConstants.CATALOG_FAMILY).close();
1096     while (!ZKTableReadOnly.isEnabledTable(zkw,
1097         TableName.valueOf("testMasterAdmin"))) {
1098       Thread.sleep(10);
1099     }
1100     this.admin.disableTable(tableName);
1101     try {
1102       new HTable(TEST_UTIL.getConfiguration(), tableName);
1103     } catch (org.apache.hadoop.hbase.DoNotRetryIOException e) {
1104       //expected
1105     }
1106 
1107     this.admin.addColumn(tableName, new HColumnDescriptor("col2"));
1108     this.admin.enableTable(tableName);
1109     try {
1110       this.admin.deleteColumn(tableName, Bytes.toBytes("col2"));
1111     } catch (TableNotDisabledException e) {
1112       LOG.info(e);
1113     }
1114     this.admin.disableTable(tableName);
1115     this.admin.deleteTable(tableName);
1116   }
1117 
1118   @Test (timeout=300000)
1119   public void testCreateBadTables() throws IOException {
1120     String msg = null;
1121     try {
1122       this.admin.createTable(HTableDescriptor.META_TABLEDESC);
1123     } catch(TableExistsException e) {
1124       msg = e.toString();
1125     }
1126     assertTrue("Unexcepted exception message " + msg, msg != null &&
1127       msg.startsWith(TableExistsException.class.getName()) &&
1128       msg.contains(HTableDescriptor.META_TABLEDESC.getTableName().getNameAsString()));
1129 
1130     // Now try and do concurrent creation with a bunch of threads.
1131     final HTableDescriptor threadDesc =
1132       new HTableDescriptor(TableName.valueOf("threaded_testCreateBadTables"));
1133     threadDesc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
1134     int count = 10;
1135     Thread [] threads = new Thread [count];
1136     final AtomicInteger successes = new AtomicInteger(0);
1137     final AtomicInteger failures = new AtomicInteger(0);
1138     final HBaseAdmin localAdmin = this.admin;
1139     for (int i = 0; i < count; i++) {
1140       threads[i] = new Thread(Integer.toString(i)) {
1141         @Override
1142         public void run() {
1143           try {
1144             localAdmin.createTable(threadDesc);
1145             successes.incrementAndGet();
1146           } catch (TableExistsException e) {
1147             failures.incrementAndGet();
1148           } catch (IOException e) {
1149             throw new RuntimeException("Failed threaded create" + getName(), e);
1150           }
1151         }
1152       };
1153     }
1154     for (int i = 0; i < count; i++) {
1155       threads[i].start();
1156     }
1157     for (int i = 0; i < count; i++) {
1158       while(threads[i].isAlive()) {
1159         try {
1160           Thread.sleep(100);
1161         } catch (InterruptedException e) {
1162           // continue
1163         }
1164       }
1165     }
1166     // All threads are now dead.  Count up how many tables were created and
1167     // how many failed w/ appropriate exception.
1168     assertEquals(1, successes.get());
1169     assertEquals(count - 1, failures.get());
1170   }
1171 
1172   /**
1173    * Test for hadoop-1581 'HBASE: Unopenable tablename bug'.
1174    * @throws Exception
1175    */
1176   @Test (timeout=300000)
1177   public void testTableNameClash() throws Exception {
1178     String name = "testTableNameClash";
1179     admin.createTable(new HTableDescriptor(TableName.valueOf(name + "SOMEUPPERCASE")));
1180     admin.createTable(new HTableDescriptor(TableName.valueOf(name)));
1181     // Before fix, below would fail throwing a NoServerForRegionException.
1182     new HTable(TEST_UTIL.getConfiguration(), name).close();
1183   }
1184 
1185   /***
1186    * HMaster.createTable used to be kind of synchronous call
1187    * Thus creating of table with lots of regions can cause RPC timeout
1188    * After the fix to make createTable truly async, RPC timeout shouldn't be an
1189    * issue anymore
1190    * @throws Exception
1191    */
1192   @Test (timeout=300000)
1193   public void testCreateTableRPCTimeOut() throws Exception {
1194     String name = "testCreateTableRPCTimeOut";
1195     int oldTimeout = TEST_UTIL.getConfiguration().
1196       getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
1197     TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500);
1198     try {
1199       int expectedRegions = 100;
1200       // Use 80 bit numbers to make sure we aren't limited
1201       byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
1202       byte [] endKey =   { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
1203       HBaseAdmin hbaseadmin = new HBaseAdmin(TEST_UTIL.getConfiguration());
1204       hbaseadmin.createTable(new HTableDescriptor(TableName.valueOf(name)), startKey, endKey,
1205         expectedRegions);
1206       hbaseadmin.close();
1207     } finally {
1208       TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, oldTimeout);
1209     }
1210   }
1211 
1212   /**
1213    * Test read only tables
1214    * @throws Exception
1215    */
1216   @Test (timeout=300000)
1217   public void testReadOnlyTable() throws Exception {
1218     byte [] name = Bytes.toBytes("testReadOnlyTable");
1219     HTable table = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1220     byte[] value = Bytes.toBytes("somedata");
1221     // This used to use an empty row... That must have been a bug
1222     Put put = new Put(value);
1223     put.add(HConstants.CATALOG_FAMILY, HConstants.CATALOG_FAMILY, value);
1224     table.put(put);
1225     table.close();
1226   }
1227 
1228   /**
1229    * Test that user table names can contain '-' and '.' so long as they do not
1230    * start with same. HBASE-771
1231    * @throws IOException
1232    */
1233   @Test (timeout=300000)
1234   public void testTableNames() throws IOException {
1235     byte[][] illegalNames = new byte[][] {
1236         Bytes.toBytes("-bad"),
1237         Bytes.toBytes(".bad")
1238     };
1239     for (byte[] illegalName : illegalNames) {
1240       try {
1241         new HTableDescriptor(TableName.valueOf(illegalName));
1242         throw new IOException("Did not detect '" +
1243             Bytes.toString(illegalName) + "' as an illegal user table name");
1244       } catch (IllegalArgumentException e) {
1245         // expected
1246       }
1247     }
1248     byte[] legalName = Bytes.toBytes("g-oo.d");
1249     try {
1250       new HTableDescriptor(TableName.valueOf(legalName));
1251     } catch (IllegalArgumentException e) {
1252       throw new IOException("Legal user table name: '" +
1253         Bytes.toString(legalName) + "' caused IllegalArgumentException: " +
1254         e.getMessage());
1255     }
1256   }
1257 
1258   /**
1259    * For HADOOP-2579
1260    * @throws IOException
1261    */
1262   @Test (expected=TableExistsException.class, timeout=300000)
1263   public void testTableExistsExceptionWithATable() throws IOException {
1264     final byte [] name = Bytes.toBytes("testTableExistsExceptionWithATable");
1265     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
1266     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1267   }
1268 
1269   /**
1270    * Can't disable a table if the table isn't in enabled state
1271    * @throws IOException
1272    */
1273   @Test (expected=TableNotEnabledException.class, timeout=300000)
1274   public void testTableNotEnabledExceptionWithATable() throws IOException {
1275     final byte [] name = Bytes.toBytes(
1276       "testTableNotEnabledExceptionWithATable");
1277     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
1278     this.admin.disableTable(name);
1279     this.admin.disableTable(name);
1280   }
1281 
1282   /**
1283    * Can't enable a table if the table isn't in disabled state
1284    * @throws IOException
1285    */
1286   @Test (expected=TableNotDisabledException.class, timeout=300000)
1287   public void testTableNotDisabledExceptionWithATable() throws IOException {
1288     final byte [] name = Bytes.toBytes(
1289       "testTableNotDisabledExceptionWithATable");
1290     HTable t = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
1291     try {
1292     this.admin.enableTable(name);
1293     }finally {
1294        t.close();
1295     }
1296   }
1297 
1298   /**
1299    * For HADOOP-2579
1300    * @throws IOException
1301    */
1302   @Test (expected=TableNotFoundException.class, timeout=300000)
1303   public void testTableNotFoundExceptionWithoutAnyTables() throws IOException {
1304     new HTable(TEST_UTIL.getConfiguration(),"testTableNotFoundExceptionWithoutAnyTables");
1305   }
1306 
1307 
1308   @Test (timeout=300000)
1309   public void testShouldCloseTheRegionBasedOnTheEncodedRegionName()
1310       throws Exception {
1311     TableName TABLENAME =
1312         TableName.valueOf("TestHBACloseRegion");
1313     createTableWithDefaultConf(TABLENAME);
1314 
1315     HRegionInfo info = null;
1316     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1317     List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1318     for (HRegionInfo regionInfo : onlineRegions) {
1319       if (!HTableDescriptor.isSystemTable(regionInfo.getTableName())) {
1320         info = regionInfo;
1321         admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), rs
1322             .getServerName().getServerName());
1323       }
1324     }
1325     boolean isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
1326     long timeout = System.currentTimeMillis() + 10000;
1327     while ((System.currentTimeMillis() < timeout) && (isInList)) {
1328       Thread.sleep(100);
1329       isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
1330     }
1331 
1332     assertFalse("The region should not be present in online regions list.",
1333       isInList);
1334   }
1335 
1336   @Test (timeout=300000)
1337   public void testCloseRegionIfInvalidRegionNameIsPassed() throws Exception {
1338     byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion1");
1339     createTableWithDefaultConf(TABLENAME);
1340 
1341     HRegionInfo info = null;
1342     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1343     List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1344     for (HRegionInfo regionInfo : onlineRegions) {
1345       if (!regionInfo.isMetaTable()) {
1346         if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion1")) {
1347           info = regionInfo;
1348           try {
1349             admin.closeRegionWithEncodedRegionName("sample", rs.getServerName()
1350               .getServerName());
1351           } catch (NotServingRegionException nsre) {
1352             // expected, ignore it
1353           }
1354         }
1355       }
1356     }
1357     onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1358     assertTrue("The region should be present in online regions list.",
1359         onlineRegions.contains(info));
1360   }
1361 
1362   @Test (timeout=300000)
1363   public void testCloseRegionThatFetchesTheHRIFromMeta() throws Exception {
1364     TableName TABLENAME =
1365         TableName.valueOf("TestHBACloseRegion2");
1366     createTableWithDefaultConf(TABLENAME);
1367 
1368     HRegionInfo info = null;
1369     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1370     List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1371     for (HRegionInfo regionInfo : onlineRegions) {
1372       if (!regionInfo.isMetaTable()) {
1373 
1374         if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion2")) {
1375           info = regionInfo;
1376           admin.closeRegion(regionInfo.getRegionNameAsString(), rs
1377               .getServerName().getServerName());
1378         }
1379       }
1380     }
1381 
1382     boolean isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
1383     long timeout = System.currentTimeMillis() + 10000;
1384     while ((System.currentTimeMillis() < timeout) && (isInList)) {
1385       Thread.sleep(100);
1386       isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
1387     }
1388 
1389     assertFalse("The region should not be present in online regions list.",
1390       isInList);
1391   }
1392 
1393   @Test (timeout=300000)
1394   public void testCloseRegionWhenServerNameIsNull() throws Exception {
1395     byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion3");
1396     createTableWithDefaultConf(TABLENAME);
1397 
1398     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1399 
1400     try {
1401       List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1402       for (HRegionInfo regionInfo : onlineRegions) {
1403         if (!regionInfo.isMetaTable()) {
1404           if (regionInfo.getRegionNameAsString()
1405               .contains("TestHBACloseRegion3")) {
1406             admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(),
1407                 null);
1408           }
1409         }
1410       }
1411       fail("The test should throw exception if the servername passed is null.");
1412     } catch (IllegalArgumentException e) {
1413     }
1414   }
1415 
1416 
1417   @Test (timeout=300000)
1418   public void testCloseRegionWhenServerNameIsEmpty() throws Exception {
1419     byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegionWhenServerNameIsEmpty");
1420     createTableWithDefaultConf(TABLENAME);
1421 
1422     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1423 
1424     try {
1425       List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1426       for (HRegionInfo regionInfo : onlineRegions) {
1427         if (!regionInfo.isMetaTable()) {
1428           if (regionInfo.getRegionNameAsString()
1429               .contains("TestHBACloseRegionWhenServerNameIsEmpty")) {
1430             admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(),
1431                 " ");
1432           }
1433         }
1434       }
1435       fail("The test should throw exception if the servername passed is empty.");
1436     } catch (IllegalArgumentException e) {
1437     }
1438   }
1439 
1440   @Test (timeout=300000)
1441   public void testCloseRegionWhenEncodedRegionNameIsNotGiven() throws Exception {
1442     byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion4");
1443     createTableWithDefaultConf(TABLENAME);
1444 
1445     HRegionInfo info = null;
1446     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
1447 
1448     List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1449     for (HRegionInfo regionInfo : onlineRegions) {
1450       if (!regionInfo.isMetaTable()) {
1451         if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion4")) {
1452           info = regionInfo;
1453           try {
1454             admin.closeRegionWithEncodedRegionName(regionInfo
1455               .getRegionNameAsString(), rs.getServerName().getServerName());
1456           } catch (NotServingRegionException nsre) {
1457             // expected, ignore it.
1458           }
1459         }
1460       }
1461     }
1462     onlineRegions = ProtobufUtil.getOnlineRegions(rs);
1463     assertTrue("The region should be present in online regions list.",
1464         onlineRegions.contains(info));
1465   }
1466 
1467   private HBaseAdmin createTable(byte[] TABLENAME) throws IOException {
1468 
1469     Configuration config = TEST_UTIL.getConfiguration();
1470     HBaseAdmin admin = new HBaseAdmin(config);
1471 
1472     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TABLENAME));
1473     HColumnDescriptor hcd = new HColumnDescriptor("value");
1474 
1475     htd.addFamily(hcd);
1476     admin.createTable(htd, null);
1477     return admin;
1478   }
1479 
1480   private void createTableWithDefaultConf(byte[] TABLENAME) throws IOException {
1481     createTableWithDefaultConf(TableName.valueOf(TABLENAME));
1482   }
1483 
1484   private void createTableWithDefaultConf(TableName TABLENAME) throws IOException {
1485     HTableDescriptor htd = new HTableDescriptor(TABLENAME);
1486     HColumnDescriptor hcd = new HColumnDescriptor("value");
1487     htd.addFamily(hcd);
1488 
1489     admin.createTable(htd, null);
1490   }
1491 
1492   /**
1493    * For HBASE-2556
1494    * @throws IOException
1495    */
1496   @Test (timeout=300000)
1497   public void testGetTableRegions() throws IOException {
1498 
1499     byte[] tableName = Bytes.toBytes("testGetTableRegions");
1500 
1501     int expectedRegions = 10;
1502 
1503     // Use 80 bit numbers to make sure we aren't limited
1504     byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
1505     byte [] endKey =   { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
1506 
1507 
1508     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
1509     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
1510     admin.createTable(desc, startKey, endKey, expectedRegions);
1511 
1512     List<HRegionInfo> RegionInfos = admin.getTableRegions(tableName);
1513 
1514     assertEquals("Tried to create " + expectedRegions + " regions " +
1515         "but only found " + RegionInfos.size(),
1516         expectedRegions, RegionInfos.size());
1517 
1518  }
1519 
1520   @Test (timeout=300000)
1521   public void testHLogRollWriting() throws Exception {
1522     setUpforLogRolling();
1523     String className = this.getClass().getName();
1524     StringBuilder v = new StringBuilder(className);
1525     while (v.length() < 1000) {
1526       v.append(className);
1527     }
1528     byte[] value = Bytes.toBytes(v.toString());
1529     HRegionServer regionServer = startAndWriteData("TestLogRolling", value);
1530     LOG.info("after writing there are "
1531         + HLogUtilsForTests.getNumLogFiles(regionServer.getWAL()) + " log files");
1532 
1533     // flush all regions
1534 
1535     List<HRegion> regions = new ArrayList<HRegion>(regionServer
1536         .getOnlineRegionsLocalContext());
1537     for (HRegion r : regions) {
1538       r.flushcache();
1539     }
1540     admin.rollHLogWriter(regionServer.getServerName().getServerName());
1541     int count = HLogUtilsForTests.getNumLogFiles(regionServer.getWAL());
1542     LOG.info("after flushing all regions and rolling logs there are " +
1543         count + " log files");
1544     assertTrue(("actual count: " + count), count <= 2);
1545   }
1546 
1547   @Test (timeout=300000)
1548   public void testMoveToPreviouslyAssignedRS() throws IOException, InterruptedException {
1549     byte[] tableName = Bytes.toBytes("testMoveToPreviouslyAssignedRS");
1550     MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
1551     HMaster master = cluster.getMaster();
1552     HBaseAdmin localAdmin = createTable(tableName);
1553     List<HRegionInfo> tableRegions = localAdmin.getTableRegions(tableName);
1554     HRegionInfo hri = tableRegions.get(0);
1555     AssignmentManager am = master.getAssignmentManager();
1556     assertTrue("Region " + hri.getRegionNameAsString()
1557       + " should be assigned properly", am.waitForAssignment(hri));
1558     ServerName server = am.getRegionStates().getRegionServerOfRegion(hri);
1559     localAdmin.move(hri.getEncodedNameAsBytes(), Bytes.toBytes(server.getServerName()));
1560     assertEquals("Current region server and region server before move should be same.", server,
1561       am.getRegionStates().getRegionServerOfRegion(hri));
1562   }
1563 
1564 
1565   private void setUpforLogRolling() {
1566     // Force a region split after every 768KB
1567     TEST_UTIL.getConfiguration().setLong(HConstants.HREGION_MAX_FILESIZE,
1568         768L * 1024L);
1569 
1570     // We roll the log after every 32 writes
1571     TEST_UTIL.getConfiguration().setInt("hbase.regionserver.maxlogentries", 32);
1572 
1573     TEST_UTIL.getConfiguration().setInt(
1574         "hbase.regionserver.logroll.errors.tolerated", 2);
1575     TEST_UTIL.getConfiguration().setInt("ipc.ping.interval", 10 * 1000);
1576     TEST_UTIL.getConfiguration().setInt("ipc.socket.timeout", 10 * 1000);
1577     TEST_UTIL.getConfiguration().setInt("hbase.rpc.timeout", 10 * 1000);
1578 
1579     // For less frequently updated regions flush after every 2 flushes
1580     TEST_UTIL.getConfiguration().setInt(
1581         "hbase.hregion.memstore.optionalflushcount", 2);
1582 
1583     // We flush the cache after every 8192 bytes
1584     TEST_UTIL.getConfiguration().setInt(HConstants.HREGION_MEMSTORE_FLUSH_SIZE,
1585         8192);
1586 
1587     // Increase the amount of time between client retries
1588     TEST_UTIL.getConfiguration().setLong("hbase.client.pause", 10 * 1000);
1589 
1590     // Reduce thread wake frequency so that other threads can get
1591     // a chance to run.
1592     TEST_UTIL.getConfiguration().setInt(HConstants.THREAD_WAKE_FREQUENCY,
1593         2 * 1000);
1594 
1595     /**** configuration for testLogRollOnDatanodeDeath ****/
1596     // make sure log.hflush() calls syncFs() to open a pipeline
1597     TEST_UTIL.getConfiguration().setBoolean("dfs.support.append", true);
1598     // lower the namenode & datanode heartbeat so the namenode
1599     // quickly detects datanode failures
1600     TEST_UTIL.getConfiguration().setInt("heartbeat.recheck.interval", 5000);
1601     TEST_UTIL.getConfiguration().setInt("dfs.heartbeat.interval", 1);
1602     // the namenode might still try to choose the recently-dead datanode
1603     // for a pipeline, so try to a new pipeline multiple times
1604     TEST_UTIL.getConfiguration().setInt("dfs.client.block.write.retries", 30);
1605     TEST_UTIL.getConfiguration().setInt(
1606         "hbase.regionserver.hlog.tolerable.lowreplication", 2);
1607     TEST_UTIL.getConfiguration().setInt(
1608         "hbase.regionserver.hlog.lowreplication.rolllimit", 3);
1609   }
1610 
1611   private HRegionServer startAndWriteData(String tableName, byte[] value)
1612   throws IOException, InterruptedException {
1613     // When the META table can be opened, the region servers are running
1614     new HTable(
1615       TEST_UTIL.getConfiguration(), TableName.META_TABLE_NAME).close();
1616 
1617     // Create the test table and open it
1618     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
1619     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
1620     admin.createTable(desc);
1621     HTable table = new HTable(TEST_UTIL.getConfiguration(), tableName);
1622 
1623     HRegionServer regionServer = TEST_UTIL.getRSForFirstRegionInTable(Bytes.toBytes(tableName));
1624     for (int i = 1; i <= 256; i++) { // 256 writes should cause 8 log rolls
1625       Put put = new Put(Bytes.toBytes("row" + String.format("%1$04d", i)));
1626       put.add(HConstants.CATALOG_FAMILY, null, value);
1627       table.put(put);
1628       if (i % 32 == 0) {
1629         // After every 32 writes sleep to let the log roller run
1630         try {
1631           Thread.sleep(2000);
1632         } catch (InterruptedException e) {
1633           // continue
1634         }
1635       }
1636     }
1637 
1638     table.close();
1639     return regionServer;
1640   }
1641 
1642   /**
1643    * HBASE-4417 checkHBaseAvailable() doesn't close zk connections
1644    */
1645   @Test (timeout=300000)
1646   public void testCheckHBaseAvailableClosesConnection() throws Exception {
1647     Configuration conf = TEST_UTIL.getConfiguration();
1648 
1649     int initialCount = HConnectionTestingUtility.getConnectionCount();
1650     HBaseAdmin.checkHBaseAvailable(conf);
1651     int finalCount = HConnectionTestingUtility.getConnectionCount();
1652 
1653     Assert.assertEquals(initialCount, finalCount) ;
1654   }
1655 
1656   /**
1657    * Check that we have an exception if the cluster is not there.
1658    */
1659   @Test (timeout=300000)
1660   public void testCheckHBaseAvailableWithoutCluster() {
1661     Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
1662 
1663     // Change the ZK address to go to something not used.
1664     conf.setInt(HConstants.ZOOKEEPER_CLIENT_PORT,
1665       conf.getInt(HConstants.ZOOKEEPER_CLIENT_PORT, 9999)+10);
1666 
1667     int initialCount = HConnectionTestingUtility.getConnectionCount();
1668 
1669     long start = System.currentTimeMillis();
1670     try {
1671       HBaseAdmin.checkHBaseAvailable(conf);
1672       assertTrue(false);
1673     } catch (MasterNotRunningException ignored) {
1674     } catch (ZooKeeperConnectionException ignored) {
1675     } catch (ServiceException ignored) {
1676     } catch (IOException ignored) {
1677     }
1678     long end = System.currentTimeMillis();
1679 
1680     int finalCount = HConnectionTestingUtility.getConnectionCount();
1681 
1682     Assert.assertEquals(initialCount, finalCount) ;
1683 
1684     LOG.info("It took "+(end-start)+" ms to find out that" +
1685       " HBase was not available");
1686   }
1687 
1688   @Test (timeout=300000)
1689   public void testDisableCatalogTable() throws Exception {
1690     try {
1691       this.admin.disableTable(TableName.META_TABLE_NAME);
1692       fail("Expected to throw ConstraintException");
1693     } catch (ConstraintException e) {
1694     }
1695     // Before the fix for HBASE-6146, the below table creation was failing as the META table
1696     // actually getting disabled by the disableTable() call.
1697     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("testDisableCatalogTable".getBytes()));
1698     HColumnDescriptor hcd = new HColumnDescriptor("cf1".getBytes());
1699     htd.addFamily(hcd);
1700     TEST_UTIL.getHBaseAdmin().createTable(htd);
1701   }
1702 
1703   @Test (timeout=300000)
1704   public void testGetRegion() throws Exception {
1705     final String name = "testGetRegion";
1706     LOG.info("Started " + name);
1707     final byte [] nameBytes = Bytes.toBytes(name);
1708     HTable t = TEST_UTIL.createTable(nameBytes, HConstants.CATALOG_FAMILY);
1709     TEST_UTIL.createMultiRegions(t, HConstants.CATALOG_FAMILY);
1710     CatalogTracker ct = new CatalogTracker(TEST_UTIL.getConfiguration());
1711     ct.start();
1712     try {
1713       HRegionLocation regionLocation = t.getRegionLocation("mmm");
1714       HRegionInfo region = regionLocation.getRegionInfo();
1715       byte[] regionName = region.getRegionName();
1716       Pair<HRegionInfo, ServerName> pair = admin.getRegion(regionName, ct);
1717       assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
1718       pair = admin.getRegion(region.getEncodedNameAsBytes(), ct);
1719       assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
1720     } finally {
1721       ct.stop();
1722     }
1723   }
1724 }