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