1   /**
2    * Copyright 2007 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  package org.apache.hadoop.hbase.filter;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.ByteArrayOutputStream;
24  import java.io.DataInputStream;
25  import java.io.DataOutputStream;
26  
27  import org.apache.hadoop.hbase.KeyValue;
28  import org.apache.hadoop.hbase.SmallTests;
29  import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
30  import org.apache.hadoop.hbase.util.Bytes;
31  
32  import junit.framework.TestCase;
33  import org.junit.experimental.categories.Category;
34  
35  /**
36   * Tests the value filter
37   */
38  @Category(SmallTests.class)
39  public class TestSingleColumnValueFilter extends TestCase {
40    private static final byte[] ROW = Bytes.toBytes("test");
41    private static final byte[] COLUMN_FAMILY = Bytes.toBytes("test");
42    private static final byte [] COLUMN_QUALIFIER = Bytes.toBytes("foo");
43    private static final byte[] VAL_1 = Bytes.toBytes("a");
44    private static final byte[] VAL_2 = Bytes.toBytes("ab");
45    private static final byte[] VAL_3 = Bytes.toBytes("abc");
46    private static final byte[] VAL_4 = Bytes.toBytes("abcd");
47    private static final byte[] FULLSTRING_1 =
48      Bytes.toBytes("The quick brown fox jumps over the lazy dog.");
49    private static final byte[] FULLSTRING_2 =
50      Bytes.toBytes("The slow grey fox trips over the lazy dog.");
51    private static final String QUICK_SUBSTR = "quick";
52    private static final String QUICK_REGEX = ".+quick.+";
53  
54    Filter basicFilter;
55    Filter nullFilter;
56    Filter substrFilter;
57    Filter regexFilter;
58  
59    @Override
60    protected void setUp() throws Exception {
61      super.setUp();
62      basicFilter = basicFilterNew();
63      nullFilter = nullFilterNew();
64      substrFilter = substrFilterNew();
65      regexFilter = regexFilterNew();
66    }
67  
68    private Filter basicFilterNew() {
69      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER,
70        CompareOp.GREATER_OR_EQUAL, VAL_2);
71    }
72  
73    private Filter nullFilterNew() {
74      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER, CompareOp.NOT_EQUAL,
75          new NullComparator());
76    }
77  
78    private Filter substrFilterNew() {
79      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER,
80        CompareOp.EQUAL,
81        new SubstringComparator(QUICK_SUBSTR));
82    }
83  
84    private Filter regexFilterNew() {
85      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER,
86        CompareOp.EQUAL,
87        new RegexStringComparator(QUICK_REGEX));
88    }
89  
90    private void basicFilterTests(SingleColumnValueFilter filter)
91        throws Exception {
92      KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2);
93      assertTrue("basicFilter1", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
94      kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_3);
95      assertTrue("basicFilter2", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
96      kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_4);
97      assertTrue("basicFilter3", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
98      assertFalse("basicFilterNotNull", filter.filterRow());
99      filter.reset();
100     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1);
101     assertTrue("basicFilter4", filter.filterKeyValue(kv) == Filter.ReturnCode.NEXT_ROW);
102     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2);
103     assertTrue("basicFilter4", filter.filterKeyValue(kv) == Filter.ReturnCode.NEXT_ROW);
104     assertFalse("basicFilterAllRemaining", filter.filterAllRemaining());
105     assertTrue("basicFilterNotNull", filter.filterRow());
106     filter.reset();
107     filter.setLatestVersionOnly(false);
108     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1);
109     assertTrue("basicFilter5", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
110     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2);
111     assertTrue("basicFilter5", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
112     assertFalse("basicFilterNotNull", filter.filterRow());
113   }
114 
115   private void nullFilterTests(Filter filter) throws Exception {
116     ((SingleColumnValueFilter) filter).setFilterIfMissing(true);
117     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, FULLSTRING_1);
118     assertTrue("null1", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
119     assertFalse("null1FilterRow", filter.filterRow());
120     filter.reset();
121     kv = new KeyValue(ROW, COLUMN_FAMILY, Bytes.toBytes("qual2"), FULLSTRING_2);
122     assertTrue("null2", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
123     assertTrue("null2FilterRow", filter.filterRow());
124   }
125 
126   private void substrFilterTests(Filter filter)
127       throws Exception {
128     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
129       FULLSTRING_1);
130     assertTrue("substrTrue",
131       filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
132     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
133       FULLSTRING_2);
134     assertTrue("substrFalse", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
135     assertFalse("substrFilterAllRemaining", filter.filterAllRemaining());
136     assertFalse("substrFilterNotNull", filter.filterRow());
137   }
138 
139   private void regexFilterTests(Filter filter)
140       throws Exception {
141     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
142       FULLSTRING_1);
143     assertTrue("regexTrue",
144       filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
145     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
146       FULLSTRING_2);
147     assertTrue("regexFalse", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
148     assertFalse("regexFilterAllRemaining", filter.filterAllRemaining());
149     assertFalse("regexFilterNotNull", filter.filterRow());
150   }
151 
152   private Filter serializationTest(Filter filter)
153       throws Exception {
154     // Decompose filter to bytes.
155     ByteArrayOutputStream stream = new ByteArrayOutputStream();
156     DataOutputStream out = new DataOutputStream(stream);
157     filter.write(out);
158     out.close();
159     byte[] buffer = stream.toByteArray();
160 
161     // Recompose filter.
162     DataInputStream in =
163       new DataInputStream(new ByteArrayInputStream(buffer));
164     Filter newFilter = new SingleColumnValueFilter();
165     newFilter.readFields(in);
166 
167     return newFilter;
168   }
169 
170   /**
171    * Tests identification of the stop row
172    * @throws Exception
173    */
174   public void testStop() throws Exception {
175     basicFilterTests((SingleColumnValueFilter) basicFilter);
176     nullFilterTests(nullFilter);
177     substrFilterTests(substrFilter);
178     regexFilterTests(regexFilter);
179   }
180 
181   /**
182    * Tests serialization
183    * @throws Exception
184    */
185   public void testSerialization() throws Exception {
186     Filter newFilter = serializationTest(basicFilter);
187     basicFilterTests((SingleColumnValueFilter)newFilter);
188     newFilter = serializationTest(nullFilter);
189     nullFilterTests(newFilter);
190     newFilter = serializationTest(substrFilter);
191     substrFilterTests(newFilter);
192     newFilter = serializationTest(regexFilter);
193     regexFilterTests(newFilter);
194   }
195 
196   @org.junit.Rule
197   public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
198     new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
199 }
200