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.master;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  import org.apache.hadoop.hbase.*;
24  import org.apache.hadoop.hbase.catalog.MetaReader;
25  import org.apache.hadoop.hbase.client.HBaseAdmin;
26  import org.apache.hadoop.hbase.client.HTable;
27  import org.apache.hadoop.hbase.util.Bytes;
28  import org.apache.hadoop.hbase.util.Pair;
29  
30  import java.io.IOException;
31  import java.util.List;
32  
33  import org.junit.AfterClass;
34  import org.junit.BeforeClass;
35  import org.junit.Test;
36  
37  import com.google.common.base.Joiner;
38  import org.junit.experimental.categories.Category;
39  
40  import static org.junit.Assert.*;
41  
42  @Category(MediumTests.class)
43  public class TestMaster {
44    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
45    private static final Log LOG = LogFactory.getLog(TestMaster.class);
46    private static final TableName TABLENAME =
47        TableName.valueOf("TestMaster");
48    private static final byte[] FAMILYNAME = Bytes.toBytes("fam");
49    private static HBaseAdmin admin;
50  
51    @BeforeClass
52    public static void beforeAllTests() throws Exception {
53      // Start a cluster of two regionservers.
54      TEST_UTIL.startMiniCluster(2);
55      admin = TEST_UTIL.getHBaseAdmin();
56    }
57  
58    @AfterClass
59    public static void afterAllTests() throws Exception {
60      TEST_UTIL.shutdownMiniCluster();
61    }
62  
63    @Test
64    public void testMasterOpsWhileSplitting() throws Exception {
65      MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
66      HMaster m = cluster.getMaster();
67  
68      HTable ht = TEST_UTIL.createTable(TABLENAME, FAMILYNAME);
69      assertTrue(m.assignmentManager.getZKTable().isEnabledTable(TABLENAME));
70      TEST_UTIL.loadTable(ht, FAMILYNAME);
71      ht.close();
72  
73      List<Pair<HRegionInfo, ServerName>> tableRegions =
74        MetaReader.getTableRegionsAndLocations(m.getCatalogTracker(), TABLENAME);
75      LOG.info("Regions after load: " + Joiner.on(',').join(tableRegions));
76      assertEquals(1, tableRegions.size());
77      assertArrayEquals(HConstants.EMPTY_START_ROW,
78          tableRegions.get(0).getFirst().getStartKey());
79      assertArrayEquals(HConstants.EMPTY_END_ROW,
80          tableRegions.get(0).getFirst().getEndKey());
81  
82      // Now trigger a split and stop when the split is in progress
83      LOG.info("Splitting table");
84      TEST_UTIL.getHBaseAdmin().split(TABLENAME.getName());
85      LOG.info("Waiting for split result to be about to open");
86      while (!m.assignmentManager.wasSplitHandlerCalled()) {
87        Thread.sleep(100);
88      }
89      LOG.info("Making sure we can call getTableRegions while opening");
90      tableRegions = MetaReader.getTableRegionsAndLocations(m.getCatalogTracker(),
91          TABLENAME, false);
92  
93      LOG.info("Regions: " + Joiner.on(',').join(tableRegions));
94      // We have three regions because one is split-in-progress
95      assertEquals(3, tableRegions.size());
96      LOG.info("Making sure we can call getTableRegionClosest while opening");
97      Pair<HRegionInfo, ServerName> pair =
98          m.getTableRegionForRow(TABLENAME, Bytes.toBytes("cde"));
99      LOG.info("Result is: " + pair);
100     Pair<HRegionInfo, ServerName> tableRegionFromName =
101         MetaReader.getRegion(m.getCatalogTracker(),
102             pair.getFirst().getRegionName());
103     assertEquals(tableRegionFromName.getFirst(), pair.getFirst());
104   }
105 
106   @Test
107   public void testMoveRegionWhenNotInitialized() {
108     MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
109     HMaster m = cluster.getMaster();
110     try {
111       m.initialized = false; // fake it, set back later
112       HRegionInfo meta = HRegionInfo.FIRST_META_REGIONINFO;
113       m.move(meta.getEncodedNameAsBytes(), null);
114       fail("Region should not be moved since master is not initialized");
115     } catch (IOException ioe) {
116       assertTrue(ioe instanceof PleaseHoldException);
117     } finally {
118       m.initialized = true;
119     }
120   }
121 
122   @Test
123   public void testMoveThrowsUnknownRegionException() throws IOException {
124     TableName tableName =
125         TableName.valueOf("testMoveThrowsUnknownRegionException");
126     HTableDescriptor htd = new HTableDescriptor(tableName);
127     HColumnDescriptor hcd = new HColumnDescriptor("value");
128     htd.addFamily(hcd);
129 
130     admin.createTable(htd, null);
131     try {
132       HRegionInfo hri = new HRegionInfo(
133         tableName, Bytes.toBytes("A"), Bytes.toBytes("Z"));
134       admin.move(hri.getEncodedNameAsBytes(), null);
135       fail("Region should not be moved since it is fake");
136     } catch (IOException ioe) {
137       assertTrue(ioe instanceof UnknownRegionException);
138     } finally {
139       TEST_UTIL.deleteTable(tableName);
140     }
141   }
142 
143   @Test
144   public void testMoveThrowsPleaseHoldException() throws IOException {
145     byte[] tableName = Bytes.toBytes("testMoveThrowsPleaseHoldException");
146     HMaster master = TEST_UTIL.getMiniHBaseCluster().getMaster();
147     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(tableName));
148     HColumnDescriptor hcd = new HColumnDescriptor("value");
149     htd.addFamily(hcd);
150 
151     admin.createTable(htd, null);
152     try {
153       List<HRegionInfo> tableRegions = admin.getTableRegions(tableName);
154 
155       master.initialized = false; // fake it, set back later
156       admin.move(tableRegions.get(0).getEncodedNameAsBytes(), null);
157       fail("Region should not be moved since master is not initialized");
158     } catch (IOException ioe) {
159       assertTrue(ioe instanceof PleaseHoldException);
160     } finally {
161       master.initialized = true;
162       TEST_UTIL.deleteTable(tableName);
163     }
164   }
165 }
166