View Javadoc

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
9    * http://www.apache.org/licenses/LICENSE-2.0
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.hadoop.hbase.regionserver;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import org.apache.hadoop.conf.Configuration;
21  import org.apache.hadoop.hbase.HBaseTestingUtility;
22  import org.apache.hadoop.hbase.HTableDescriptor;
23  import org.apache.hadoop.hbase.TableName;
24  import org.apache.hadoop.hbase.client.Delete;
25  import org.apache.hadoop.hbase.client.Mutation;
26  import org.apache.hadoop.hbase.client.Put;
27  import org.apache.hadoop.hbase.client.Result;
28  import org.apache.hadoop.hbase.client.Scan;
29  import org.apache.hadoop.hbase.client.Table;
30  import org.apache.hadoop.hbase.filter.BinaryComparator;
31  import org.apache.hadoop.hbase.filter.CompareFilter;
32  import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;
33  import org.apache.hadoop.hbase.testclassification.FilterTests;
34  import org.apache.hadoop.hbase.testclassification.MediumTests;
35  import org.apache.hadoop.hbase.testclassification.RegionServerTests;
36  import org.apache.hadoop.hbase.util.Bytes;
37  import org.junit.AfterClass;
38  import org.junit.BeforeClass;
39  import org.junit.Rule;
40  import org.junit.Test;
41  import org.junit.experimental.categories.Category;
42  import org.junit.rules.TestName;
43  
44  /**
45   * Test failure in ScanDeleteTracker.isDeleted when ROWCOL bloom filter
46   * is used during a scan with a filter.
47   */
48  @Category({ RegionServerTests.class, FilterTests.class, MediumTests.class })
49  public class TestIsDeleteFailure {
50    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
51  
52    @Rule public TestName name = new TestName();
53  
54    @BeforeClass
55    public static void setUpBeforeClass() throws Exception {
56      TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
57      TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
58      TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 2);
59      TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true);
60      TEST_UTIL.startMiniCluster(1);
61    }
62  
63    @AfterClass
64    public static void tearDownAfterClass() throws Exception {
65      TEST_UTIL.shutdownMiniCluster();
66    }
67  
68    @Test
69    public void testIsDeleteFailure() throws Exception {
70      final HTableDescriptor table = new HTableDescriptor(TableName.valueOf(name.getMethodName()));
71      final byte[] family = Bytes.toBytes("0");
72      final byte[] c1 = Bytes.toBytes("C01");
73      final byte[] c2 = Bytes.toBytes("C02");
74      final byte[] c3 = Bytes.toBytes("C03");
75      final byte[] c4 = Bytes.toBytes("C04");
76      final byte[] c5 = Bytes.toBytes("C05");
77      final byte[] c6 = Bytes.toBytes("C07");
78      final byte[] c7 = Bytes.toBytes("C07");
79      final byte[] c8 = Bytes.toBytes("C08");
80      final byte[] c9 = Bytes.toBytes("C09");
81      final byte[] c10 = Bytes.toBytes("C10");
82      final byte[] c11 = Bytes.toBytes("C11");
83      final byte[] c12 = Bytes.toBytes("C12");
84      final byte[] c13 = Bytes.toBytes("C13");
85      final byte[] c14 = Bytes.toBytes("C14");
86      final byte[] c15 = Bytes.toBytes("C15");
87  
88      final byte[] val = Bytes.toBytes("foo");
89      List<byte[]> fams = new ArrayList<>(1);
90      fams.add(family);
91      Table ht = TEST_UTIL
92          .createTable(table, fams.toArray(new byte[0][]), null, BloomType.ROWCOL, 10000,
93              new Configuration(TEST_UTIL.getConfiguration()));
94      List<Mutation> pending = new ArrayList<Mutation>();
95      for (int i = 0; i < 1000; i++) {
96        byte[] row = Bytes.toBytes("key" + Integer.toString(i));
97        Put put = new Put(row);
98        put.addColumn(family, c3, val);
99        put.addColumn(family, c4, val);
100       put.addColumn(family, c5, val);
101       put.addColumn(family, c6, val);
102       put.addColumn(family, c7, val);
103       put.addColumn(family, c8, val);
104       put.addColumn(family, c12, val);
105       put.addColumn(family, c13, val);
106       put.addColumn(family, c15, val);
107       pending.add(put);
108       Delete del = new Delete(row);
109       del.addColumns(family, c2);
110       del.addColumns(family, c9);
111       del.addColumns(family, c10);
112       del.addColumns(family, c14);
113       pending.add(del);
114     }
115     ht.batch(pending, new Object[pending.size()]);
116     TEST_UTIL.flush();
117     TEST_UTIL.compact(true);
118     for (int i = 20; i < 300; i++) {
119       byte[] row = Bytes.toBytes("key" + Integer.toString(i));
120       Put put = new Put(row);
121       put.addColumn(family, c3, val);
122       put.addColumn(family, c4, val);
123       put.addColumn(family, c5, val);
124       put.addColumn(family, c6, val);
125       put.addColumn(family, c7, val);
126       put.addColumn(family, c8, val);
127       put.addColumn(family, c12, val);
128       put.addColumn(family, c13, val);
129       put.addColumn(family, c15, val);
130       pending.add(put);
131       Delete del = new Delete(row);
132       del.addColumns(family, c2);
133       del.addColumns(family, c9);
134       del.addColumns(family, c10);
135       del.addColumns(family, c14);
136       pending.add(del);
137     }
138     ht.batch(pending, new Object[pending.size()]);
139     TEST_UTIL.flush();
140 
141     Scan scan = new Scan();
142     scan.addColumn(family, c9);
143     scan.addColumn(family, c15);
144     SingleColumnValueFilter filter =
145         new SingleColumnValueFilter(family, c15, CompareFilter.CompareOp.EQUAL,
146             new BinaryComparator(c15));
147     scan.setFilter(filter);
148     //Trigger the scan for not existing row, so it will scan over all rows
149     for (Result result : ht.getScanner(scan)) {
150       result.advance();
151     }
152     ht.close();
153   }
154 }