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.filter.CompareFilter.CompareOp;
29  import org.apache.hadoop.hbase.util.Bytes;
30  
31  import junit.framework.TestCase;
32  
33  /**
34   * Tests the value filter
35   */
36  public class TestSingleColumnValueFilter extends TestCase {
37    private static final byte[] ROW = Bytes.toBytes("test");
38    private static final byte[] COLUMN_FAMILY = Bytes.toBytes("test");
39    private static final byte [] COLUMN_QUALIFIER = Bytes.toBytes("foo");
40    private static final byte[] VAL_1 = Bytes.toBytes("a");
41    private static final byte[] VAL_2 = Bytes.toBytes("ab");
42    private static final byte[] VAL_3 = Bytes.toBytes("abc");
43    private static final byte[] VAL_4 = Bytes.toBytes("abcd");
44    private static final byte[] FULLSTRING_1 =
45      Bytes.toBytes("The quick brown fox jumps over the lazy dog.");
46    private static final byte[] FULLSTRING_2 =
47      Bytes.toBytes("The slow grey fox trips over the lazy dog.");
48    private static final String QUICK_SUBSTR = "quick";
49    private static final String QUICK_REGEX = ".+quick.+";
50  
51    Filter basicFilter;
52    Filter substrFilter;
53    Filter regexFilter;
54  
55    @Override
56    protected void setUp() throws Exception {
57      super.setUp();
58      basicFilter = basicFilterNew();
59      substrFilter = substrFilterNew();
60      regexFilter = regexFilterNew();
61    }
62  
63    private Filter basicFilterNew() {
64      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER,
65        CompareOp.GREATER_OR_EQUAL, VAL_2);
66    }
67  
68    private Filter substrFilterNew() {
69      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER,
70        CompareOp.EQUAL,
71        new SubstringComparator(QUICK_SUBSTR));
72    }
73  
74    private Filter regexFilterNew() {
75      return new SingleColumnValueFilter(COLUMN_FAMILY, COLUMN_QUALIFIER,
76        CompareOp.EQUAL,
77        new RegexStringComparator(QUICK_REGEX));
78    }
79  
80    private void basicFilterTests(SingleColumnValueFilter filter)
81        throws Exception {
82      KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2);
83      assertTrue("basicFilter1", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
84      kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_3);
85      assertTrue("basicFilter2", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
86      kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_4);
87      assertTrue("basicFilter3", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
88      assertFalse("basicFilterNotNull", filter.filterRow());
89      filter.reset();
90      kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1);
91      assertTrue("basicFilter4", filter.filterKeyValue(kv) == Filter.ReturnCode.NEXT_ROW);
92      kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2);
93      assertTrue("basicFilter4", filter.filterKeyValue(kv) == Filter.ReturnCode.NEXT_ROW);
94      assertFalse("basicFilterAllRemaining", filter.filterAllRemaining());
95      assertTrue("basicFilterNotNull", filter.filterRow());
96      filter.reset();
97      filter.setLatestVersionOnly(false);
98      kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_1);
99      assertTrue("basicFilter5", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
100     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER, VAL_2);
101     assertTrue("basicFilter5", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
102     assertFalse("basicFilterNotNull", filter.filterRow());
103   }
104 
105   private void substrFilterTests(Filter filter)
106       throws Exception {
107     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
108       FULLSTRING_1);
109     assertTrue("substrTrue",
110       filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
111     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
112       FULLSTRING_2);
113     assertTrue("substrFalse", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
114     assertFalse("substrFilterAllRemaining", filter.filterAllRemaining());
115     assertFalse("substrFilterNotNull", filter.filterRow());
116   }
117 
118   private void regexFilterTests(Filter filter)
119       throws Exception {
120     KeyValue kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
121       FULLSTRING_1);
122     assertTrue("regexTrue",
123       filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
124     kv = new KeyValue(ROW, COLUMN_FAMILY, COLUMN_QUALIFIER,
125       FULLSTRING_2);
126     assertTrue("regexFalse", filter.filterKeyValue(kv) == Filter.ReturnCode.INCLUDE);
127     assertFalse("regexFilterAllRemaining", filter.filterAllRemaining());
128     assertFalse("regexFilterNotNull", filter.filterRow());
129   }
130 
131   private Filter serializationTest(Filter filter)
132       throws Exception {
133     // Decompose filter to bytes.
134     ByteArrayOutputStream stream = new ByteArrayOutputStream();
135     DataOutputStream out = new DataOutputStream(stream);
136     filter.write(out);
137     out.close();
138     byte[] buffer = stream.toByteArray();
139 
140     // Recompose filter.
141     DataInputStream in =
142       new DataInputStream(new ByteArrayInputStream(buffer));
143     Filter newFilter = new SingleColumnValueFilter();
144     newFilter.readFields(in);
145 
146     return newFilter;
147   }
148 
149   /**
150    * Tests identification of the stop row
151    * @throws Exception
152    */
153   public void testStop() throws Exception {
154     basicFilterTests((SingleColumnValueFilter)basicFilter);
155     substrFilterTests(substrFilter);
156     regexFilterTests(regexFilter);
157   }
158 
159   /**
160    * Tests serialization
161    * @throws Exception
162    */
163   public void testSerialization() throws Exception {
164     Filter newFilter = serializationTest(basicFilter);
165     basicFilterTests((SingleColumnValueFilter)newFilter);
166     newFilter = serializationTest(substrFilter);
167     substrFilterTests(newFilter);
168     newFilter = serializationTest(regexFilter);
169     regexFilterTests(newFilter);
170   }
171 }