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