View Javadoc

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