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