HBASE-24033 Add ut for loading the corrupt recovered hfiles (#1322)
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / client / TestResult.java
blobb38fb6a6c66e3a8ef53f9efd539d9d3df5e37a5c
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.client;
20 import static org.apache.hadoop.hbase.HBaseTestCase.assertByteEquals;
22 import java.io.IOException;
23 import java.nio.ByteBuffer;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.NoSuchElementException;
27 import junit.framework.TestCase;
28 import org.apache.hadoop.hbase.Cell;
29 import org.apache.hadoop.hbase.CellComparator;
30 import org.apache.hadoop.hbase.CellScanner;
31 import org.apache.hadoop.hbase.CellUtil;
32 import org.apache.hadoop.hbase.HBaseClassTestRule;
33 import org.apache.hadoop.hbase.KeyValue;
34 import org.apache.hadoop.hbase.testclassification.ClientTests;
35 import org.apache.hadoop.hbase.testclassification.SmallTests;
36 import org.apache.hadoop.hbase.util.Bytes;
37 import org.junit.ClassRule;
38 import org.junit.experimental.categories.Category;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
42 @Category({SmallTests.class, ClientTests.class})
43 public class TestResult extends TestCase {
45 @ClassRule
46 public static final HBaseClassTestRule CLASS_RULE =
47 HBaseClassTestRule.forClass(TestResult.class);
49 private static final Logger LOG = LoggerFactory.getLogger(TestResult.class.getName());
51 static KeyValue[] genKVs(final byte[] row, final byte[] family,
52 final byte[] value,
53 final long timestamp,
54 final int cols) {
55 KeyValue [] kvs = new KeyValue[cols];
57 for (int i = 0; i < cols ; i++) {
58 kvs[i] = new KeyValue(
59 row, family, Bytes.toBytes(i),
60 timestamp,
61 Bytes.add(value, Bytes.toBytes(i)));
63 return kvs;
66 static final byte [] row = Bytes.toBytes("row");
67 static final byte [] family = Bytes.toBytes("family");
68 static final byte [] value = Bytes.toBytes("value");
70 /**
71 * Run some tests to ensure Result acts like a proper CellScanner.
72 * @throws IOException
74 public void testResultAsCellScanner() throws IOException {
75 Cell [] cells = genKVs(row, family, value, 1, 10);
76 Arrays.sort(cells, CellComparator.getInstance());
77 Result r = Result.create(cells);
78 assertSame(r, cells);
79 // Assert I run over same result multiple times.
80 assertSame(r.cellScanner(), cells);
81 assertSame(r.cellScanner(), cells);
82 // Assert we are not creating new object when doing cellscanner
83 assertTrue(r == r.cellScanner());
86 private void assertSame(final CellScanner cellScanner, final Cell [] cells) throws IOException {
87 int count = 0;
88 while (cellScanner.advance()) {
89 assertTrue(cells[count].equals(cellScanner.current()));
90 count++;
92 assertEquals(cells.length, count);
95 public void testBasicGetColumn() throws Exception {
96 KeyValue [] kvs = genKVs(row, family, value, 1, 100);
98 Arrays.sort(kvs, CellComparator.getInstance());
100 Result r = Result.create(kvs);
102 for (int i = 0; i < 100; ++i) {
103 final byte[] qf = Bytes.toBytes(i);
105 List<Cell> ks = r.getColumnCells(family, qf);
106 assertEquals(1, ks.size());
107 assertTrue(CellUtil.matchingQualifier(ks.get(0), qf));
108 assertEquals(ks.get(0), r.getColumnLatestCell(family, qf));
112 public void testCurrentOnEmptyCell() throws IOException {
113 Result r = Result.create(new Cell[0]);
114 assertFalse(r.advance());
115 assertNull(r.current());
118 public void testAdvanceTwiceOnEmptyCell() throws IOException {
119 Result r = Result.create(new Cell[0]);
120 assertFalse(r.advance());
121 try {
122 r.advance();
123 fail("NoSuchElementException should have been thrown!");
124 } catch (NoSuchElementException ex) {
125 LOG.debug("As expected: " + ex.getMessage());
129 public void testMultiVersionGetColumn() throws Exception {
130 KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
131 KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
133 KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
134 System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
135 System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
137 Arrays.sort(kvs, CellComparator.getInstance());
139 Result r = Result.create(kvs);
140 for (int i = 0; i < 100; ++i) {
141 final byte[] qf = Bytes.toBytes(i);
143 List<Cell> ks = r.getColumnCells(family, qf);
144 assertEquals(2, ks.size());
145 assertTrue(CellUtil.matchingQualifier(ks.get(0), qf));
146 assertEquals(200, ks.get(0).getTimestamp());
147 assertEquals(ks.get(0), r.getColumnLatestCell(family, qf));
151 public void testBasicGetValue() throws Exception {
152 KeyValue [] kvs = genKVs(row, family, value, 1, 100);
154 Arrays.sort(kvs, CellComparator.getInstance());
156 Result r = Result.create(kvs);
158 for (int i = 0; i < 100; ++i) {
159 final byte[] qf = Bytes.toBytes(i);
161 assertByteEquals(Bytes.add(value, Bytes.toBytes(i)), r.getValue(family, qf));
162 assertTrue(r.containsColumn(family, qf));
166 public void testMultiVersionGetValue() throws Exception {
167 KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
168 KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
170 KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
171 System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
172 System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
174 Arrays.sort(kvs, CellComparator.getInstance());
176 Result r = Result.create(kvs);
177 for (int i = 0; i < 100; ++i) {
178 final byte[] qf = Bytes.toBytes(i);
180 assertByteEquals(Bytes.add(value, Bytes.toBytes(i)), r.getValue(family, qf));
181 assertTrue(r.containsColumn(family, qf));
185 public void testBasicLoadValue() throws Exception {
186 KeyValue [] kvs = genKVs(row, family, value, 1, 100);
188 Arrays.sort(kvs, CellComparator.getInstance());
190 Result r = Result.create(kvs);
191 ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
193 for (int i = 0; i < 100; ++i) {
194 final byte[] qf = Bytes.toBytes(i);
196 loadValueBuffer.clear();
197 r.loadValue(family, qf, loadValueBuffer);
198 loadValueBuffer.flip();
199 assertEquals(loadValueBuffer, ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))));
200 assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))),
201 r.getValueAsByteBuffer(family, qf));
205 public void testMultiVersionLoadValue() throws Exception {
206 KeyValue [] kvs1 = genKVs(row, family, value, 1, 100);
207 KeyValue [] kvs2 = genKVs(row, family, value, 200, 100);
209 KeyValue [] kvs = new KeyValue[kvs1.length+kvs2.length];
210 System.arraycopy(kvs1, 0, kvs, 0, kvs1.length);
211 System.arraycopy(kvs2, 0, kvs, kvs1.length, kvs2.length);
213 Arrays.sort(kvs, CellComparator.getInstance());
215 ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
217 Result r = Result.create(kvs);
218 for (int i = 0; i < 100; ++i) {
219 final byte[] qf = Bytes.toBytes(i);
221 loadValueBuffer.clear();
222 r.loadValue(family, qf, loadValueBuffer);
223 loadValueBuffer.flip();
224 assertEquals(loadValueBuffer, ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))));
225 assertEquals(ByteBuffer.wrap(Bytes.add(value, Bytes.toBytes(i))),
226 r.getValueAsByteBuffer(family, qf));
231 * Verify that Result.compareResults(...) behaves correctly.
233 public void testCompareResults() throws Exception {
234 byte [] value1 = Bytes.toBytes("value1");
235 byte [] qual = Bytes.toBytes("qual");
237 KeyValue kv1 = new KeyValue(row, family, qual, value);
238 KeyValue kv2 = new KeyValue(row, family, qual, value1);
240 Result r1 = Result.create(new KeyValue[] {kv1});
241 Result r2 = Result.create(new KeyValue[] {kv2});
242 // no exception thrown
243 Result.compareResults(r1, r1);
244 try {
245 // these are different (HBASE-4800)
246 Result.compareResults(r1, r2);
247 fail();
248 } catch (Exception x) {
249 assertTrue(x.getMessage().startsWith("This result was different:"));
254 * Verifies that one can't modify instance of EMPTY_RESULT.
256 public void testEmptyResultIsReadonly() {
257 Result emptyResult = Result.EMPTY_RESULT;
258 Result otherResult = new Result();
260 try {
261 emptyResult.copyFrom(otherResult);
262 fail("UnsupportedOperationException should have been thrown!");
263 } catch (UnsupportedOperationException ex) {
264 LOG.debug("As expected: " + ex.getMessage());
266 try {
267 emptyResult.setExists(true);
268 fail("UnsupportedOperationException should have been thrown!");
269 } catch (UnsupportedOperationException ex) {
270 LOG.debug("As expected: " + ex.getMessage());
275 * Microbenchmark that compares {@link Result#getValue} and {@link Result#loadValue} performance.
277 * @throws Exception
279 public void doReadBenchmark() throws Exception {
281 final int n = 5;
282 final int m = 100000000;
284 StringBuilder valueSB = new StringBuilder();
285 for (int i = 0; i < 100; i++) {
286 valueSB.append((byte)(Math.random() * 10));
289 StringBuilder rowSB = new StringBuilder();
290 for (int i = 0; i < 50; i++) {
291 rowSB.append((byte)(Math.random() * 10));
294 KeyValue [] kvs = genKVs(Bytes.toBytes(rowSB.toString()), family,
295 Bytes.toBytes(valueSB.toString()), 1, n);
296 Arrays.sort(kvs, CellComparator.getInstance());
297 ByteBuffer loadValueBuffer = ByteBuffer.allocate(1024);
298 Result r = Result.create(kvs);
300 byte[][] qfs = new byte[n][Bytes.SIZEOF_INT];
301 for (int i = 0; i < n; ++i) {
302 System.arraycopy(qfs[i], 0, Bytes.toBytes(i), 0, Bytes.SIZEOF_INT);
305 // warm up
306 for (int k = 0; k < 100000; k++) {
307 for (int i = 0; i < n; ++i) {
308 r.getValue(family, qfs[i]);
309 loadValueBuffer.clear();
310 r.loadValue(family, qfs[i], loadValueBuffer);
311 loadValueBuffer.flip();
315 System.gc();
316 long start = System.nanoTime();
317 for (int k = 0; k < m; k++) {
318 for (int i = 0; i < n; ++i) {
319 loadValueBuffer.clear();
320 r.loadValue(family, qfs[i], loadValueBuffer);
321 loadValueBuffer.flip();
324 long stop = System.nanoTime();
325 System.out.println("loadValue(): " + (stop - start));
327 System.gc();
328 start = System.nanoTime();
329 for (int k = 0; k < m; k++) {
330 for (int i = 0; i < n; i++) {
331 r.getValue(family, qfs[i]);
334 stop = System.nanoTime();
335 System.out.println("getValue(): " + (stop - start));
339 * Calls non-functional test methods.
341 * @param args
343 public static void main(String[] args) {
344 TestResult testResult = new TestResult();
345 try {
346 testResult.doReadBenchmark();
347 } catch (Exception e) {
348 LOG.error("Unexpected exception", e);