HBASE-24504 refactor call setupCluster/tearDownCluster in TestTableSnapshotInputForma...
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / regionserver / TestRegionInfoBuilder.java
blob90bab5c9a1fa2f7679c21f1244c1dde04239ddb6
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.regionserver;
20 import static org.junit.Assert.assertArrayEquals;
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;
26 import java.io.IOException;
27 import org.apache.hadoop.fs.FileStatus;
28 import org.apache.hadoop.fs.Path;
29 import org.apache.hadoop.hbase.HBaseClassTestRule;
30 import org.apache.hadoop.hbase.HBaseTestingUtility;
31 import org.apache.hadoop.hbase.HRegionInfo;
32 import org.apache.hadoop.hbase.TableName;
33 import org.apache.hadoop.hbase.client.RegionInfo;
34 import org.apache.hadoop.hbase.client.RegionInfoBuilder;
35 import org.apache.hadoop.hbase.client.TableDescriptor;
36 import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
37 import org.apache.hadoop.hbase.exceptions.DeserializationException;
38 import org.apache.hadoop.hbase.testclassification.RegionServerTests;
39 import org.apache.hadoop.hbase.testclassification.SmallTests;
40 import org.apache.hadoop.hbase.util.Bytes;
41 import org.apache.hadoop.hbase.util.FSTableDescriptors;
42 import org.apache.hadoop.hbase.util.MD5Hash;
43 import org.junit.ClassRule;
44 import org.junit.Rule;
45 import org.junit.Test;
46 import org.junit.experimental.categories.Category;
47 import org.junit.rules.TestName;
49 import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations;
51 import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
52 import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
54 @Category({RegionServerTests.class, SmallTests.class})
55 public class TestRegionInfoBuilder {
57 @ClassRule
58 public static final HBaseClassTestRule CLASS_RULE =
59 HBaseClassTestRule.forClass(TestRegionInfoBuilder.class);
61 @Rule
62 public TestName name = new TestName();
64 @Test
65 public void testBuilder() {
66 TableName tn = TableName.valueOf("test");
67 RegionInfoBuilder builder = RegionInfoBuilder.newBuilder(tn);
68 byte[] startKey = Bytes.toBytes("a");
69 builder.setStartKey(startKey);
70 byte[] endKey = Bytes.toBytes("z");
71 builder.setEndKey(endKey);
72 int regionId = 1;
73 builder.setRegionId(1);
74 int replicaId = 2;
75 builder.setReplicaId(replicaId);
76 boolean offline = true;
77 builder.setOffline(offline);
78 boolean isSplit = true;
79 builder.setSplit(isSplit);
80 RegionInfo ri = builder.build();
82 assertEquals(tn, ri.getTable());
83 assertArrayEquals(startKey, ri.getStartKey());
84 assertArrayEquals(endKey, ri.getEndKey());
85 assertEquals(regionId, ri.getRegionId());
86 assertEquals(replicaId, ri.getReplicaId());
87 assertEquals(offline, ri.isOffline());
88 assertEquals(isSplit, ri.isSplit());
91 @Test
92 public void testPb() throws DeserializationException {
93 RegionInfo ri = RegionInfoBuilder.FIRST_META_REGIONINFO;
94 byte [] bytes = RegionInfo.toByteArray(ri);
95 RegionInfo pbri = RegionInfo.parseFrom(bytes);
96 assertTrue(RegionInfo.COMPARATOR.compare(ri, pbri) == 0);
99 @Test
100 public void testReadAndWriteRegionInfoFile() throws IOException, InterruptedException {
101 HBaseTestingUtility htu = new HBaseTestingUtility();
102 RegionInfo ri = RegionInfoBuilder.FIRST_META_REGIONINFO;
103 Path basedir = htu.getDataTestDir();
104 // Create a region. That'll write the .regioninfo file.
105 FSTableDescriptors fsTableDescriptors = new FSTableDescriptors(htu.getConfiguration());
106 FSTableDescriptors.tryUpdateMetaTableDescriptor(htu.getConfiguration());
107 HRegion r = HBaseTestingUtility.createRegionAndWAL(convert(ri), basedir, htu.getConfiguration(),
108 fsTableDescriptors.get(TableName.META_TABLE_NAME));
109 // Get modtime on the file.
110 long modtime = getModTime(r);
111 HBaseTestingUtility.closeRegionAndWAL(r);
112 Thread.sleep(1001);
113 r = HRegion.openHRegion(basedir, convert(ri), fsTableDescriptors.get(TableName.META_TABLE_NAME),
114 null, htu.getConfiguration());
115 // Ensure the file is not written for a second time.
116 long modtime2 = getModTime(r);
117 assertEquals(modtime, modtime2);
118 // Now load the file.
119 RegionInfo deserializedRi = HRegionFileSystem.loadRegionInfoFileContent(
120 r.getRegionFileSystem().getFileSystem(), r.getRegionFileSystem().getRegionDir());
121 HBaseTestingUtility.closeRegionAndWAL(r);
124 long getModTime(final HRegion r) throws IOException {
125 FileStatus[] statuses = r.getRegionFileSystem().getFileSystem().listStatus(
126 new Path(r.getRegionFileSystem().getRegionDir(), HRegionFileSystem.REGION_INFO_FILE));
127 assertTrue(statuses != null && statuses.length == 1);
128 return statuses[0].getModificationTime();
131 @Test
132 public void testCreateRegionInfoName() throws Exception {
133 final String tableName = name.getMethodName();
134 final TableName tn = TableName.valueOf(tableName);
135 String startKey = "startkey";
136 final byte[] sk = Bytes.toBytes(startKey);
137 String id = "id";
139 // old format region name
140 byte [] name = RegionInfo.createRegionName(tn, sk, id, false);
141 String nameStr = Bytes.toString(name);
142 assertEquals(tableName + "," + startKey + "," + id, nameStr);
145 // new format region name.
146 String md5HashInHex = MD5Hash.getMD5AsHex(name);
147 assertEquals(RegionInfo.MD5_HEX_LENGTH, md5HashInHex.length());
148 name = RegionInfo.createRegionName(tn, sk, id, true);
149 nameStr = Bytes.toString(name);
150 assertEquals(tableName + "," + startKey + ","
151 + id + "." + md5HashInHex + ".",
152 nameStr);
155 @Test
156 public void testContainsRange() {
157 TableDescriptor tableDesc = TableDescriptorBuilder.newBuilder(
158 TableName.valueOf(name.getMethodName())).build();
159 RegionInfo ri = RegionInfoBuilder.newBuilder(tableDesc.getTableName())
160 .setStartKey(Bytes.toBytes("a"))
161 .setEndKey(Bytes.toBytes("g")).build();
162 // Single row range at start of region
163 assertTrue(ri.containsRange(Bytes.toBytes("a"), Bytes.toBytes("a")));
164 // Fully contained range
165 assertTrue(ri.containsRange(Bytes.toBytes("b"), Bytes.toBytes("c")));
166 // Range overlapping start of region
167 assertTrue(ri.containsRange(Bytes.toBytes("a"), Bytes.toBytes("c")));
168 // Fully contained single-row range
169 assertTrue(ri.containsRange(Bytes.toBytes("c"), Bytes.toBytes("c")));
170 // Range that overlaps end key and hence doesn't fit
171 assertFalse(ri.containsRange(Bytes.toBytes("a"), Bytes.toBytes("g")));
172 // Single row range on end key
173 assertFalse(ri.containsRange(Bytes.toBytes("g"), Bytes.toBytes("g")));
174 // Single row range entirely outside
175 assertFalse(ri.containsRange(Bytes.toBytes("z"), Bytes.toBytes("z")));
177 // Degenerate range
178 try {
179 ri.containsRange(Bytes.toBytes("z"), Bytes.toBytes("a"));
180 fail("Invalid range did not throw IAE");
181 } catch (IllegalArgumentException iae) {
185 @Test
186 public void testLastRegionCompare() {
187 TableDescriptor tableDesc = TableDescriptorBuilder
188 .newBuilder(TableName.valueOf(name.getMethodName())).build();
189 RegionInfo rip = RegionInfoBuilder.newBuilder(tableDesc.getTableName())
190 .setStartKey(Bytes.toBytes("a"))
191 .setEndKey(new byte[0]).build();
192 RegionInfo ric = RegionInfoBuilder.newBuilder(tableDesc.getTableName())
193 .setStartKey(Bytes.toBytes("a"))
194 .setEndKey(Bytes.toBytes("b")).build();
195 assertTrue(RegionInfo.COMPARATOR.compare(rip, ric) > 0);
198 @Test
199 public void testMetaTables() {
200 assertTrue(RegionInfoBuilder.FIRST_META_REGIONINFO.isMetaRegion());
203 @Test
204 public void testComparator() {
205 final TableName tableName = TableName.valueOf(name.getMethodName());
206 byte[] empty = new byte[0];
207 RegionInfo older = RegionInfoBuilder.newBuilder(tableName)
208 .setStartKey(empty)
209 .setEndKey(empty)
210 .setSplit(false)
211 .setRegionId(0L).build();
212 RegionInfo newer = RegionInfoBuilder.newBuilder(tableName)
213 .setStartKey(empty)
214 .setEndKey(empty)
215 .setSplit(false)
216 .setRegionId(1L).build();
217 assertTrue(RegionInfo.COMPARATOR.compare(older, newer) < 0);
218 assertTrue(RegionInfo.COMPARATOR.compare(newer, older) > 0);
219 assertTrue(RegionInfo.COMPARATOR.compare(older, older) == 0);
220 assertTrue(RegionInfo.COMPARATOR.compare(newer, newer) == 0);
223 @Test
224 public void testRegionNameForRegionReplicas() throws Exception {
225 String tableName = name.getMethodName();
226 final TableName tn = TableName.valueOf(tableName);
227 String startKey = "startkey";
228 final byte[] sk = Bytes.toBytes(startKey);
229 String id = "id";
231 // assert with only the region name without encoding
233 // primary, replicaId = 0
234 byte [] name = RegionInfo.createRegionName(tn, sk, Bytes.toBytes(id), 0, false);
235 String nameStr = Bytes.toString(name);
236 assertEquals(tableName + "," + startKey + "," + id, nameStr);
238 // replicaId = 1
239 name = RegionInfo.createRegionName(tn, sk, Bytes.toBytes(id), 1, false);
240 nameStr = Bytes.toString(name);
241 assertEquals(tableName + "," + startKey + "," + id + "_" +
242 String.format(RegionInfo.REPLICA_ID_FORMAT, 1), nameStr);
244 // replicaId = max
245 name = RegionInfo.createRegionName(tn, sk, Bytes.toBytes(id), 0xFFFF, false);
246 nameStr = Bytes.toString(name);
247 assertEquals(tableName + "," + startKey + "," + id + "_" +
248 String.format(RegionInfo.REPLICA_ID_FORMAT, 0xFFFF), nameStr);
251 @Test
252 public void testParseName() throws IOException {
253 final TableName tableName = TableName.valueOf(name.getMethodName());
254 byte[] startKey = Bytes.toBytes("startKey");
255 long regionId = System.currentTimeMillis();
256 int replicaId = 42;
258 // test without replicaId
259 byte[] regionName = RegionInfo.createRegionName(tableName, startKey, regionId, false);
261 byte[][] fields = RegionInfo.parseRegionName(regionName);
262 assertArrayEquals(Bytes.toString(fields[0]),tableName.getName(), fields[0]);
263 assertArrayEquals(Bytes.toString(fields[1]),startKey, fields[1]);
264 assertArrayEquals(Bytes.toString(fields[2]), Bytes.toBytes(Long.toString(regionId)),fields[2]);
265 assertEquals(3, fields.length);
267 // test with replicaId
268 regionName = RegionInfo.createRegionName(tableName, startKey, regionId,
269 replicaId, false);
271 fields = RegionInfo.parseRegionName(regionName);
272 assertArrayEquals(Bytes.toString(fields[0]),tableName.getName(), fields[0]);
273 assertArrayEquals(Bytes.toString(fields[1]),startKey, fields[1]);
274 assertArrayEquals(Bytes.toString(fields[2]), Bytes.toBytes(Long.toString(regionId)),fields[2]);
275 assertArrayEquals(Bytes.toString(fields[3]), Bytes.toBytes(
276 String.format(RegionInfo.REPLICA_ID_FORMAT, replicaId)), fields[3]);
279 @Test
280 public void testConvert() {
281 final TableName tableName = TableName.valueOf("ns1:" + name.getMethodName());
282 byte[] startKey = Bytes.toBytes("startKey");
283 byte[] endKey = Bytes.toBytes("endKey");
284 boolean split = false;
285 long regionId = System.currentTimeMillis();
286 int replicaId = 42;
289 RegionInfo ri = RegionInfoBuilder.newBuilder(tableName)
290 .setStartKey(startKey)
291 .setEndKey(endKey)
292 .setSplit(split)
293 .setRegionId(regionId)
294 .setReplicaId(replicaId).build();
296 // convert two times, compare
297 RegionInfo convertedRi = ProtobufUtil.toRegionInfo(ProtobufUtil.toRegionInfo(ri));
299 assertEquals(ri, convertedRi);
301 // test convert RegionInfo without replicaId
302 HBaseProtos.RegionInfo info = HBaseProtos.RegionInfo.newBuilder()
303 .setTableName(HBaseProtos.TableName.newBuilder()
304 .setQualifier(UnsafeByteOperations.unsafeWrap(tableName.getQualifier()))
305 .setNamespace(UnsafeByteOperations.unsafeWrap(tableName.getNamespace()))
306 .build())
307 .setStartKey(UnsafeByteOperations.unsafeWrap(startKey))
308 .setEndKey(UnsafeByteOperations.unsafeWrap(endKey))
309 .setSplit(split)
310 .setRegionId(regionId)
311 .build();
313 convertedRi = ProtobufUtil.toRegionInfo(info);
314 RegionInfo expectedRi = RegionInfoBuilder.newBuilder(tableName)
315 .setStartKey(startKey)
316 .setEndKey(endKey)
317 .setSplit(split)
318 .setRegionId(regionId)
319 .setReplicaId(0).build();
321 assertEquals(expectedRi, convertedRi);
324 // Duplicated method in TestRegionInfoDisplay too.
325 private HRegionInfo convert(RegionInfo ri) {
326 HRegionInfo hri = new HRegionInfo(
327 ri.getTable(), ri.getStartKey(), ri.getEndKey(), ri.isSplit(), ri.getRegionId());
328 hri.setOffline(ri.isOffline());
329 return hri;