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