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.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   * Tests a scanner on a corrupt hfile.
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 }