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.List;
30  import java.util.concurrent.atomic.AtomicInteger;
31  
32  import org.apache.commons.logging.Log;
33  import org.apache.commons.logging.LogFactory;
34  import org.apache.hadoop.conf.Configuration;
35  import org.apache.hadoop.hbase.HBaseTestingUtility;
36  import org.apache.hadoop.hbase.HColumnDescriptor;
37  import org.apache.hadoop.hbase.HConstants;
38  import org.apache.hadoop.hbase.HRegionInfo;
39  import org.apache.hadoop.hbase.HRegionLocation;
40  import org.apache.hadoop.hbase.HTableDescriptor;
41  import org.apache.hadoop.hbase.LargeTests;
42  import org.apache.hadoop.hbase.MasterNotRunningException;
43  import org.apache.hadoop.hbase.MiniHBaseCluster;
44  import org.apache.hadoop.hbase.NotServingRegionException;
45  import org.apache.hadoop.hbase.ServerName;
46  import org.apache.hadoop.hbase.TableExistsException;
47  import org.apache.hadoop.hbase.TableName;
48  import org.apache.hadoop.hbase.TableNotDisabledException;
49  import org.apache.hadoop.hbase.TableNotEnabledException;
50  import org.apache.hadoop.hbase.TableNotFoundException;
51  import org.apache.hadoop.hbase.ZooKeeperConnectionException;
52  import org.apache.hadoop.hbase.catalog.CatalogTracker;
53  import org.apache.hadoop.hbase.constraint.ConstraintException;
54  import org.apache.hadoop.hbase.ipc.RpcClient;
55  import org.apache.hadoop.hbase.master.AssignmentManager;
56  import org.apache.hadoop.hbase.master.HMaster;
57  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
58  import org.apache.hadoop.hbase.regionserver.HRegion;
59  import org.apache.hadoop.hbase.regionserver.HRegionServer;
60  import org.apache.hadoop.hbase.regionserver.wal.HLogUtilsForTests;
61  import org.apache.hadoop.hbase.util.Bytes;
62  import org.apache.hadoop.hbase.util.Pair;
63  import org.junit.After;
64  import org.junit.AfterClass;
65  import org.junit.Assert;
66  import org.junit.Before;
67  import org.junit.BeforeClass;
68  import org.junit.Test;
69  import org.junit.experimental.categories.Category;
70  
71  import com.google.protobuf.ServiceException;
72  
73  
74  /**
75   * Class to test HBaseAdmin.
76   * Spins up the minicluster once at test start and then takes it down afterward.
77   * Add any testing of HBaseAdmin functionality here.
78   */
79  @Category(LargeTests.class)
80  public class TestAdmin2 {
81    final Log LOG = LogFactory.getLog(getClass());
82    private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
83    private HBaseAdmin admin;
84  
85    @BeforeClass
86    public static void setUpBeforeClass() throws Exception {
87      TEST_UTIL.getConfiguration().setBoolean("hbase.online.schema.update.enable", true);
88      TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
89      TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
90      TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 6);
91      TEST_UTIL.getConfiguration().setBoolean(
92          "hbase.master.enabletable.roundrobin", true);
93      TEST_UTIL.startMiniCluster(3);
94    }
95  
96    @AfterClass
97    public static void tearDownAfterClass() throws Exception {
98      TEST_UTIL.shutdownMiniCluster();
99    }
100 
101   @Before
102   public void setUp() throws Exception {
103     this.admin = TEST_UTIL.getHBaseAdmin();
104   }
105 
106   @After
107   public void tearDown() throws Exception {
108     for (HTableDescriptor htd : this.admin.listTables()) {
109       TEST_UTIL.deleteTable(htd.getName());
110     }
111   }
112 
113   @Test (timeout=300000)
114   public void testCreateBadTables() throws IOException {
115     String msg = null;
116     try {
117       this.admin.createTable(new HTableDescriptor(TableName.META_TABLE_NAME));
118     } catch(TableExistsException e) {
119       msg = e.toString();
120     }
121     assertTrue("Unexcepted exception message " + msg, msg != null &&
122       msg.startsWith(TableExistsException.class.getName()) &&
123       msg.contains(TableName.META_TABLE_NAME.getNameAsString()));
124 
125     // Now try and do concurrent creation with a bunch of threads.
126     final HTableDescriptor threadDesc =
127       new HTableDescriptor(TableName.valueOf("threaded_testCreateBadTables"));
128     threadDesc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
129     int count = 10;
130     Thread [] threads = new Thread [count];
131     final AtomicInteger successes = new AtomicInteger(0);
132     final AtomicInteger failures = new AtomicInteger(0);
133     final HBaseAdmin localAdmin = this.admin;
134     for (int i = 0; i < count; i++) {
135       threads[i] = new Thread(Integer.toString(i)) {
136         @Override
137         public void run() {
138           try {
139             localAdmin.createTable(threadDesc);
140             successes.incrementAndGet();
141           } catch (TableExistsException e) {
142             failures.incrementAndGet();
143           } catch (IOException e) {
144             throw new RuntimeException("Failed threaded create" + getName(), e);
145           }
146         }
147       };
148     }
149     for (int i = 0; i < count; i++) {
150       threads[i].start();
151     }
152     for (int i = 0; i < count; i++) {
153       while(threads[i].isAlive()) {
154         try {
155           Thread.sleep(100);
156         } catch (InterruptedException e) {
157           // continue
158         }
159       }
160     }
161     // All threads are now dead.  Count up how many tables were created and
162     // how many failed w/ appropriate exception.
163     assertEquals(1, successes.get());
164     assertEquals(count - 1, failures.get());
165   }
166 
167   /**
168    * Test for hadoop-1581 'HBASE: Unopenable tablename bug'.
169    * @throws Exception
170    */
171   @Test (timeout=300000)
172   public void testTableNameClash() throws Exception {
173     String name = "testTableNameClash";
174     admin.createTable(new HTableDescriptor(TableName.valueOf(name + "SOMEUPPERCASE")));
175     admin.createTable(new HTableDescriptor(TableName.valueOf(name)));
176     // Before fix, below would fail throwing a NoServerForRegionException.
177     new HTable(TEST_UTIL.getConfiguration(), name).close();
178   }
179 
180   /***
181    * HMaster.createTable used to be kind of synchronous call
182    * Thus creating of table with lots of regions can cause RPC timeout
183    * After the fix to make createTable truly async, RPC timeout shouldn't be an
184    * issue anymore
185    * @throws Exception
186    */
187   @Test (timeout=300000)
188   public void testCreateTableRPCTimeOut() throws Exception {
189     String name = "testCreateTableRPCTimeOut";
190     int oldTimeout = TEST_UTIL.getConfiguration().
191       getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
192     TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500);
193     try {
194       int expectedRegions = 100;
195       // Use 80 bit numbers to make sure we aren't limited
196       byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
197       byte [] endKey =   { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
198       HBaseAdmin hbaseadmin = new HBaseAdmin(TEST_UTIL.getConfiguration());
199       hbaseadmin.createTable(new HTableDescriptor(TableName.valueOf(name)), startKey, endKey,
200         expectedRegions);
201       hbaseadmin.close();
202     } finally {
203       TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, oldTimeout);
204     }
205   }
206 
207   /**
208    * Test read only tables
209    * @throws Exception
210    */
211   @Test (timeout=300000)
212   public void testReadOnlyTable() throws Exception {
213     byte [] name = Bytes.toBytes("testReadOnlyTable");
214     HTable table = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
215     byte[] value = Bytes.toBytes("somedata");
216     // This used to use an empty row... That must have been a bug
217     Put put = new Put(value);
218     put.add(HConstants.CATALOG_FAMILY, HConstants.CATALOG_FAMILY, value);
219     table.put(put);
220     table.close();
221   }
222 
223   /**
224    * Test that user table names can contain '-' and '.' so long as they do not
225    * start with same. HBASE-771
226    * @throws IOException
227    */
228   @Test (timeout=300000)
229   public void testTableNames() throws IOException {
230     byte[][] illegalNames = new byte[][] {
231         Bytes.toBytes("-bad"),
232         Bytes.toBytes(".bad")
233     };
234     for (byte[] illegalName : illegalNames) {
235       try {
236         new HTableDescriptor(TableName.valueOf(illegalName));
237         throw new IOException("Did not detect '" +
238             Bytes.toString(illegalName) + "' as an illegal user table name");
239       } catch (IllegalArgumentException e) {
240         // expected
241       }
242     }
243     byte[] legalName = Bytes.toBytes("g-oo.d");
244     try {
245       new HTableDescriptor(TableName.valueOf(legalName));
246     } catch (IllegalArgumentException e) {
247       throw new IOException("Legal user table name: '" +
248         Bytes.toString(legalName) + "' caused IllegalArgumentException: " +
249         e.getMessage());
250     }
251   }
252 
253   /**
254    * For HADOOP-2579
255    * @throws IOException
256    */
257   @Test (expected=TableExistsException.class, timeout=300000)
258   public void testTableExistsExceptionWithATable() throws IOException {
259     final byte [] name = Bytes.toBytes("testTableExistsExceptionWithATable");
260     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
261     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
262   }
263 
264   /**
265    * Can't disable a table if the table isn't in enabled state
266    * @throws IOException
267    */
268   @Test (expected=TableNotEnabledException.class, timeout=300000)
269   public void testTableNotEnabledExceptionWithATable() throws IOException {
270     final byte [] name = Bytes.toBytes(
271       "testTableNotEnabledExceptionWithATable");
272     TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
273     this.admin.disableTable(name);
274     this.admin.disableTable(name);
275   }
276 
277   /**
278    * Can't enable a table if the table isn't in disabled state
279    * @throws IOException
280    */
281   @Test (expected=TableNotDisabledException.class, timeout=300000)
282   public void testTableNotDisabledExceptionWithATable() throws IOException {
283     final byte [] name = Bytes.toBytes(
284       "testTableNotDisabledExceptionWithATable");
285     HTable t = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
286     try {
287     this.admin.enableTable(name);
288     }finally {
289        t.close();
290     }
291   }
292 
293   /**
294    * For HADOOP-2579
295    * @throws IOException
296    */
297   @Test (expected=TableNotFoundException.class, timeout=300000)
298   public void testTableNotFoundExceptionWithoutAnyTables() throws IOException {
299     HTable ht =
300         new HTable(TEST_UTIL.getConfiguration(),"testTableNotFoundExceptionWithoutAnyTables");
301     ht.get(new Get("e".getBytes()));
302   }
303 
304 
305   @Test (timeout=300000)
306   public void testShouldCloseTheRegionBasedOnTheEncodedRegionName()
307       throws Exception {
308     TableName TABLENAME =
309         TableName.valueOf("TestHBACloseRegion");
310     createTableWithDefaultConf(TABLENAME);
311 
312     HRegionInfo info = null;
313     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
314     List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
315     for (HRegionInfo regionInfo : onlineRegions) {
316       if (!regionInfo.getTable().isSystemTable()) {
317         info = regionInfo;
318         admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(), rs
319             .getServerName().getServerName());
320       }
321     }
322     boolean isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
323     long timeout = System.currentTimeMillis() + 10000;
324     while ((System.currentTimeMillis() < timeout) && (isInList)) {
325       Thread.sleep(100);
326       isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
327     }
328 
329     assertFalse("The region should not be present in online regions list.",
330       isInList);
331   }
332 
333   @Test (timeout=300000)
334   public void testCloseRegionIfInvalidRegionNameIsPassed() throws Exception {
335     byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion1");
336     createTableWithDefaultConf(TABLENAME);
337 
338     HRegionInfo info = null;
339     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
340     List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
341     for (HRegionInfo regionInfo : onlineRegions) {
342       if (!regionInfo.isMetaTable()) {
343         if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion1")) {
344           info = regionInfo;
345           try {
346             admin.closeRegionWithEncodedRegionName("sample", rs.getServerName()
347               .getServerName());
348           } catch (NotServingRegionException nsre) {
349             // expected, ignore it
350           }
351         }
352       }
353     }
354     onlineRegions = ProtobufUtil.getOnlineRegions(rs);
355     assertTrue("The region should be present in online regions list.",
356         onlineRegions.contains(info));
357   }
358 
359   @Test (timeout=300000)
360   public void testCloseRegionThatFetchesTheHRIFromMeta() throws Exception {
361     TableName TABLENAME =
362         TableName.valueOf("TestHBACloseRegion2");
363     createTableWithDefaultConf(TABLENAME);
364 
365     HRegionInfo info = null;
366     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
367     List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
368     for (HRegionInfo regionInfo : onlineRegions) {
369       if (!regionInfo.isMetaTable()) {
370 
371         if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion2")) {
372           info = regionInfo;
373           admin.closeRegion(regionInfo.getRegionNameAsString(), rs
374               .getServerName().getServerName());
375         }
376       }
377     }
378 
379     boolean isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
380     long timeout = System.currentTimeMillis() + 10000;
381     while ((System.currentTimeMillis() < timeout) && (isInList)) {
382       Thread.sleep(100);
383       isInList = ProtobufUtil.getOnlineRegions(rs).contains(info);
384     }
385 
386     assertFalse("The region should not be present in online regions list.",
387       isInList);
388   }
389 
390   @Test (timeout=300000)
391   public void testCloseRegionWhenServerNameIsNull() throws Exception {
392     byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion3");
393     createTableWithDefaultConf(TABLENAME);
394 
395     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
396 
397     try {
398       List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
399       for (HRegionInfo regionInfo : onlineRegions) {
400         if (!regionInfo.isMetaTable()) {
401           if (regionInfo.getRegionNameAsString()
402               .contains("TestHBACloseRegion3")) {
403             admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(),
404                 null);
405           }
406         }
407       }
408       fail("The test should throw exception if the servername passed is null.");
409     } catch (IllegalArgumentException e) {
410     }
411   }
412 
413 
414   @Test (timeout=300000)
415   public void testCloseRegionWhenServerNameIsEmpty() throws Exception {
416     byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegionWhenServerNameIsEmpty");
417     createTableWithDefaultConf(TABLENAME);
418 
419     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
420 
421     try {
422       List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
423       for (HRegionInfo regionInfo : onlineRegions) {
424         if (!regionInfo.isMetaTable()) {
425           if (regionInfo.getRegionNameAsString()
426               .contains("TestHBACloseRegionWhenServerNameIsEmpty")) {
427             admin.closeRegionWithEncodedRegionName(regionInfo.getEncodedName(),
428                 " ");
429           }
430         }
431       }
432       fail("The test should throw exception if the servername passed is empty.");
433     } catch (IllegalArgumentException e) {
434     }
435   }
436 
437   @Test (timeout=300000)
438   public void testCloseRegionWhenEncodedRegionNameIsNotGiven() throws Exception {
439     byte[] TABLENAME = Bytes.toBytes("TestHBACloseRegion4");
440     createTableWithDefaultConf(TABLENAME);
441 
442     HRegionInfo info = null;
443     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLENAME);
444 
445     List<HRegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs);
446     for (HRegionInfo regionInfo : onlineRegions) {
447       if (!regionInfo.isMetaTable()) {
448         if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion4")) {
449           info = regionInfo;
450           try {
451             admin.closeRegionWithEncodedRegionName(regionInfo
452               .getRegionNameAsString(), rs.getServerName().getServerName());
453           } catch (NotServingRegionException nsre) {
454             // expected, ignore it.
455           }
456         }
457       }
458     }
459     onlineRegions = ProtobufUtil.getOnlineRegions(rs);
460     assertTrue("The region should be present in online regions list.",
461         onlineRegions.contains(info));
462   }
463 
464   private HBaseAdmin createTable(byte[] TABLENAME) throws IOException {
465 
466     Configuration config = TEST_UTIL.getConfiguration();
467     HBaseAdmin admin = new HBaseAdmin(config);
468 
469     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TABLENAME));
470     HColumnDescriptor hcd = new HColumnDescriptor("value");
471 
472     htd.addFamily(hcd);
473     admin.createTable(htd, null);
474     return admin;
475   }
476 
477   private void createTableWithDefaultConf(byte[] TABLENAME) throws IOException {
478     createTableWithDefaultConf(TableName.valueOf(TABLENAME));
479   }
480 
481   private void createTableWithDefaultConf(TableName TABLENAME) throws IOException {
482     HTableDescriptor htd = new HTableDescriptor(TABLENAME);
483     HColumnDescriptor hcd = new HColumnDescriptor("value");
484     htd.addFamily(hcd);
485 
486     admin.createTable(htd, null);
487   }
488 
489   /**
490    * For HBASE-2556
491    * @throws IOException
492    */
493   @Test (timeout=300000)
494   public void testGetTableRegions() throws IOException {
495 
496     byte[] tableName = Bytes.toBytes("testGetTableRegions");
497 
498     int expectedRegions = 10;
499 
500     // Use 80 bit numbers to make sure we aren't limited
501     byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
502     byte [] endKey =   { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
503 
504 
505     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
506     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
507     admin.createTable(desc, startKey, endKey, expectedRegions);
508 
509     List<HRegionInfo> RegionInfos = admin.getTableRegions(tableName);
510 
511     assertEquals("Tried to create " + expectedRegions + " regions " +
512         "but only found " + RegionInfos.size(),
513         expectedRegions, RegionInfos.size());
514 
515  }
516 
517   @Test (timeout=300000)
518   public void testHLogRollWriting() throws Exception {
519     setUpforLogRolling();
520     String className = this.getClass().getName();
521     StringBuilder v = new StringBuilder(className);
522     while (v.length() < 1000) {
523       v.append(className);
524     }
525     byte[] value = Bytes.toBytes(v.toString());
526     HRegionServer regionServer = startAndWriteData("TestLogRolling", value);
527     LOG.info("after writing there are "
528         + HLogUtilsForTests.getNumRolledLogFiles(regionServer.getWAL()) + " log files");
529 
530     // flush all regions
531 
532     List<HRegion> regions = new ArrayList<HRegion>(regionServer
533         .getOnlineRegionsLocalContext());
534     for (HRegion r : regions) {
535       r.flushcache();
536     }
537     admin.rollHLogWriter(regionServer.getServerName().getServerName());
538     int count = HLogUtilsForTests.getNumRolledLogFiles(regionServer.getWAL());
539     LOG.info("after flushing all regions and rolling logs there are " +
540         count + " log files");
541     assertTrue(("actual count: " + count), count <= 2);
542   }
543 
544   @Test (timeout=300000)
545   public void testMoveToPreviouslyAssignedRS() throws IOException, InterruptedException {
546     byte[] tableName = Bytes.toBytes("testMoveToPreviouslyAssignedRS");
547     MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
548     HMaster master = cluster.getMaster();
549     HBaseAdmin localAdmin = createTable(tableName);
550     List<HRegionInfo> tableRegions = localAdmin.getTableRegions(tableName);
551     HRegionInfo hri = tableRegions.get(0);
552     AssignmentManager am = master.getAssignmentManager();
553     assertTrue("Region " + hri.getRegionNameAsString()
554       + " should be assigned properly", am.waitForAssignment(hri));
555     ServerName server = am.getRegionStates().getRegionServerOfRegion(hri);
556     localAdmin.move(hri.getEncodedNameAsBytes(), Bytes.toBytes(server.getServerName()));
557     assertEquals("Current region server and region server before move should be same.", server,
558       am.getRegionStates().getRegionServerOfRegion(hri));
559   }
560 
561 
562   private void setUpforLogRolling() {
563     // Force a region split after every 768KB
564     TEST_UTIL.getConfiguration().setLong(HConstants.HREGION_MAX_FILESIZE,
565         768L * 1024L);
566 
567     // We roll the log after every 32 writes
568     TEST_UTIL.getConfiguration().setInt("hbase.regionserver.maxlogentries", 32);
569 
570     TEST_UTIL.getConfiguration().setInt(
571         "hbase.regionserver.logroll.errors.tolerated", 2);
572     TEST_UTIL.getConfiguration().setInt(RpcClient.PING_INTERVAL_NAME, 10 * 1000);
573     TEST_UTIL.getConfiguration().setInt(RpcClient.SOCKET_TIMEOUT, 10 * 1000);
574     TEST_UTIL.getConfiguration().setInt("hbase.rpc.timeout", 10 * 1000);
575 
576     // For less frequently updated regions flush after every 2 flushes
577     TEST_UTIL.getConfiguration().setInt(
578         "hbase.hregion.memstore.optionalflushcount", 2);
579 
580     // We flush the cache after every 8192 bytes
581     TEST_UTIL.getConfiguration().setInt(HConstants.HREGION_MEMSTORE_FLUSH_SIZE,
582         8192);
583 
584     // Increase the amount of time between client retries
585     TEST_UTIL.getConfiguration().setLong("hbase.client.pause", 10 * 1000);
586 
587     // Reduce thread wake frequency so that other threads can get
588     // a chance to run.
589     TEST_UTIL.getConfiguration().setInt(HConstants.THREAD_WAKE_FREQUENCY,
590         2 * 1000);
591 
592     /**** configuration for testLogRollOnDatanodeDeath ****/
593     // make sure log.hflush() calls syncFs() to open a pipeline
594     TEST_UTIL.getConfiguration().setBoolean("dfs.support.append", true);
595     // lower the namenode & datanode heartbeat so the namenode
596     // quickly detects datanode failures
597     TEST_UTIL.getConfiguration().setInt("heartbeat.recheck.interval", 5000);
598     TEST_UTIL.getConfiguration().setInt("dfs.heartbeat.interval", 1);
599     // the namenode might still try to choose the recently-dead datanode
600     // for a pipeline, so try to a new pipeline multiple times
601     TEST_UTIL.getConfiguration().setInt("dfs.client.block.write.retries", 30);
602     TEST_UTIL.getConfiguration().setInt(
603         "hbase.regionserver.hlog.tolerable.lowreplication", 2);
604     TEST_UTIL.getConfiguration().setInt(
605         "hbase.regionserver.hlog.lowreplication.rolllimit", 3);
606   }
607 
608   private HRegionServer startAndWriteData(String tableName, byte[] value)
609   throws IOException, InterruptedException {
610     // When the hbase:meta table can be opened, the region servers are running
611     new HTable(
612       TEST_UTIL.getConfiguration(), TableName.META_TABLE_NAME).close();
613 
614     // Create the test table and open it
615     HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
616     desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
617     admin.createTable(desc);
618     HTable table = new HTable(TEST_UTIL.getConfiguration(), tableName);
619 
620     HRegionServer regionServer = TEST_UTIL.getRSForFirstRegionInTable(Bytes.toBytes(tableName));
621     for (int i = 1; i <= 256; i++) { // 256 writes should cause 8 log rolls
622       Put put = new Put(Bytes.toBytes("row" + String.format("%1$04d", i)));
623       put.add(HConstants.CATALOG_FAMILY, null, value);
624       table.put(put);
625       if (i % 32 == 0) {
626         // After every 32 writes sleep to let the log roller run
627         try {
628           Thread.sleep(2000);
629         } catch (InterruptedException e) {
630           // continue
631         }
632       }
633     }
634 
635     table.close();
636     return regionServer;
637   }
638 
639   /**
640    * HBASE-4417 checkHBaseAvailable() doesn't close zk connections
641    */
642   @Test (timeout=300000)
643   public void testCheckHBaseAvailableClosesConnection() throws Exception {
644     Configuration conf = TEST_UTIL.getConfiguration();
645 
646     int initialCount = HConnectionTestingUtility.getConnectionCount();
647     HBaseAdmin.checkHBaseAvailable(conf);
648     int finalCount = HConnectionTestingUtility.getConnectionCount();
649 
650     Assert.assertEquals(initialCount, finalCount) ;
651   }
652 
653   /**
654    * Check that we have an exception if the cluster is not there.
655    */
656   @Test (timeout=300000)
657   public void testCheckHBaseAvailableWithoutCluster() {
658     Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
659 
660     // Change the ZK address to go to something not used.
661     conf.setInt(HConstants.ZOOKEEPER_CLIENT_PORT,
662       conf.getInt(HConstants.ZOOKEEPER_CLIENT_PORT, 9999)+10);
663 
664     int initialCount = HConnectionTestingUtility.getConnectionCount();
665 
666     long start = System.currentTimeMillis();
667     try {
668       HBaseAdmin.checkHBaseAvailable(conf);
669       assertTrue(false);
670     } catch (MasterNotRunningException ignored) {
671     } catch (ZooKeeperConnectionException ignored) {
672     } catch (ServiceException ignored) {
673     } catch (IOException ignored) {
674     }
675     long end = System.currentTimeMillis();
676 
677     int finalCount = HConnectionTestingUtility.getConnectionCount();
678 
679     Assert.assertEquals(initialCount, finalCount) ;
680 
681     LOG.info("It took "+(end-start)+" ms to find out that" +
682       " HBase was not available");
683   }
684 
685   @Test (timeout=300000)
686   public void testDisableCatalogTable() throws Exception {
687     try {
688       this.admin.disableTable(TableName.META_TABLE_NAME);
689       fail("Expected to throw ConstraintException");
690     } catch (ConstraintException e) {
691     }
692     // Before the fix for HBASE-6146, the below table creation was failing as the hbase:meta table
693     // actually getting disabled by the disableTable() call.
694     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("testDisableCatalogTable".getBytes()));
695     HColumnDescriptor hcd = new HColumnDescriptor("cf1".getBytes());
696     htd.addFamily(hcd);
697     TEST_UTIL.getHBaseAdmin().createTable(htd);
698   }
699 
700   @Test
701   public void testIsEnabledOrDisabledOnUnknownTable() throws Exception {
702     try {
703       admin.isTableEnabled(Bytes.toBytes("unkownTable"));
704       fail("Test should fail if isTableEnabled called on unknown table.");
705     } catch (IOException e) {
706     }
707 
708     try {
709       admin.isTableDisabled(Bytes.toBytes("unkownTable"));
710       fail("Test should fail if isTableDisabled called on unknown table.");
711     } catch (IOException e) {
712     }
713   }
714 
715   @Test (timeout=300000)
716   public void testGetRegion() throws Exception {
717     final String name = "testGetRegion";
718     LOG.info("Started " + name);
719     final byte [] nameBytes = Bytes.toBytes(name);
720     HTable t = TEST_UTIL.createTable(nameBytes, HConstants.CATALOG_FAMILY);
721     TEST_UTIL.createMultiRegions(t, HConstants.CATALOG_FAMILY);
722     CatalogTracker ct = new CatalogTracker(TEST_UTIL.getConfiguration());
723     ct.start();
724     try {
725       HRegionLocation regionLocation = t.getRegionLocation("mmm");
726       HRegionInfo region = regionLocation.getRegionInfo();
727       byte[] regionName = region.getRegionName();
728       Pair<HRegionInfo, ServerName> pair = admin.getRegion(regionName, ct);
729       assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
730       pair = admin.getRegion(region.getEncodedNameAsBytes(), ct);
731       assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
732     } finally {
733       ct.stop();
734     }
735   }
736 }