1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver;
20
21 import java.io.IOException;
22 import java.util.List;
23
24 import org.apache.hadoop.hbase.DoNotRetryIOException;
25 import org.apache.hadoop.hbase.HBaseTestingUtility;
26 import org.apache.hadoop.hbase.HColumnDescriptor;
27 import org.apache.hadoop.hbase.HTableDescriptor;
28 import org.apache.hadoop.hbase.TableName;
29 import org.apache.hadoop.hbase.client.Durability;
30 import org.apache.hadoop.hbase.client.Put;
31 import org.apache.hadoop.hbase.client.Result;
32 import org.apache.hadoop.hbase.client.ResultScanner;
33 import org.apache.hadoop.hbase.client.Scan;
34 import org.apache.hadoop.hbase.client.Table;
35 import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
36 import org.apache.hadoop.hbase.coprocessor.ObserverContext;
37 import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
38 import org.apache.hadoop.hbase.io.hfile.CorruptHFileException;
39 import org.apache.hadoop.hbase.testclassification.MediumTests;
40 import org.apache.hadoop.hbase.util.Bytes;
41 import org.junit.AfterClass;
42 import org.junit.BeforeClass;
43 import org.junit.Rule;
44 import org.junit.Test;
45 import org.junit.experimental.categories.Category;
46 import org.junit.rules.TestName;
47
48
49
50
51 @Category(MediumTests.class)
52 public class TestScannerWithCorruptHFile {
53 @Rule public TestName name = new TestName();
54 private static final byte[] FAMILY_NAME = Bytes.toBytes("f");
55 private final static HBaseTestingUtility TEST_UTIL = HBaseTestingUtility.createLocalHTU();
56
57
58 @BeforeClass
59 public static void setup() throws Exception {
60 TEST_UTIL.startMiniCluster(1);
61 }
62
63 @AfterClass
64 public static void tearDown() throws Exception {
65 TEST_UTIL.shutdownMiniCluster();
66 }
67
68 public static class CorruptHFileCoprocessor extends BaseRegionObserver {
69 @Override
70 public boolean preScannerNext(ObserverContext<RegionCoprocessorEnvironment> e,
71 InternalScanner s, List<Result> results, int limit, boolean hasMore) throws IOException {
72 throw new CorruptHFileException("For test");
73 }
74 }
75
76 @Test(expected = DoNotRetryIOException.class)
77 public void testScanOnCorruptHFile() throws IOException {
78 TableName tableName = TableName.valueOf(name.getMethodName());
79 HTableDescriptor htd = new HTableDescriptor(tableName);
80 htd.addCoprocessor(CorruptHFileCoprocessor.class.getName());
81 htd.addFamily(new HColumnDescriptor(FAMILY_NAME));
82 Table table = TEST_UTIL.createTable(htd, null);
83 try {
84 loadTable(table, 1);
85 scan(table);
86 } finally {
87 table.close();
88 }
89 }
90
91 private void loadTable(Table table, int numRows) throws IOException {
92 for (int i = 0; i < numRows; ++i) {
93 byte[] row = Bytes.toBytes(i);
94 Put put = new Put(row);
95 put.setDurability(Durability.SKIP_WAL);
96 put.addColumn(FAMILY_NAME, null, row);
97 table.put(put);
98 }
99 }
100
101 private void scan(Table table) throws IOException {
102 Scan scan = new Scan();
103 scan.setCaching(1);
104 scan.setCacheBlocks(false);
105 ResultScanner scanner = table.getScanner(scan);
106 try {
107 scanner.next();
108 } finally {
109 scanner.close();
110 }
111 }
112 }