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.filter;
20  
21  import static org.junit.Assert.*;
22  
23  import java.io.IOException;
24  import java.nio.charset.StandardCharsets;
25  import java.util.ArrayList;
26  import java.util.List;
27  import java.util.regex.Pattern;
28  
29  import org.apache.hadoop.hbase.testclassification.SmallTests;
30  import org.apache.hadoop.hbase.util.Bytes;
31  import org.junit.After;
32  import org.junit.Before;
33  import org.junit.Test;
34  import org.junit.experimental.categories.Category;
35  
36  /**
37   * This class tests ParseFilter.java
38   * It tests the entire work flow from when a string is given by the user
39   * and how it is parsed to construct the corresponding Filter object
40   */
41  @Category(SmallTests.class)
42  public class TestParseFilter {
43  
44    ParseFilter f;
45    Filter filter;
46  
47    @Before
48    public void setUp() throws Exception {
49      f = new ParseFilter();
50    }
51  
52    @After
53    public void tearDown() throws Exception {
54      // Nothing to do.
55    }
56  
57    @Test
58    public void testKeyOnlyFilter() throws IOException {
59      String filterString = "KeyOnlyFilter()";
60      doTestFilter(filterString, KeyOnlyFilter.class);
61  
62      String filterString2 = "KeyOnlyFilter ('') ";
63      byte [] filterStringAsByteArray2 = Bytes.toBytes(filterString2);
64      try {
65        filter = f.parseFilterString(filterStringAsByteArray2);
66        assertTrue(false);
67      } catch (IllegalArgumentException e) {
68        System.out.println(e.getMessage());
69      }
70    }
71  
72    @Test
73    public void testFirstKeyOnlyFilter() throws IOException {
74      String filterString = " FirstKeyOnlyFilter( ) ";
75      doTestFilter(filterString, FirstKeyOnlyFilter.class);
76  
77      String filterString2 = " FirstKeyOnlyFilter ('') ";
78      byte [] filterStringAsByteArray2 = Bytes.toBytes(filterString2);
79      try {
80        filter = f.parseFilterString(filterStringAsByteArray2);
81        assertTrue(false);
82      } catch (IllegalArgumentException e) {
83        System.out.println(e.getMessage());
84      }
85    }
86  
87    @Test
88    public void testPrefixFilter() throws IOException {
89      String filterString = " PrefixFilter('row' ) ";
90      PrefixFilter prefixFilter = doTestFilter(filterString, PrefixFilter.class);
91      byte [] prefix = prefixFilter.getPrefix();
92      assertEquals(new String(prefix), "row");
93  
94  
95      filterString = " PrefixFilter(row)";
96      try {
97        doTestFilter(filterString, PrefixFilter.class);
98        assertTrue(false);
99      } catch (IllegalArgumentException e) {
100       System.out.println(e.getMessage());
101     }
102   }
103 
104   @Test
105   public void testColumnPrefixFilter() throws IOException {
106     String filterString = " ColumnPrefixFilter('qualifier' ) ";
107     ColumnPrefixFilter columnPrefixFilter =
108       doTestFilter(filterString, ColumnPrefixFilter.class);
109     byte [] columnPrefix = columnPrefixFilter.getPrefix();
110     assertEquals(new String(columnPrefix), "qualifier");
111   }
112 
113   @Test
114   public void testMultipleColumnPrefixFilter() throws IOException {
115     String filterString = " MultipleColumnPrefixFilter('qualifier1', 'qualifier2' ) ";
116     MultipleColumnPrefixFilter multipleColumnPrefixFilter =
117       doTestFilter(filterString, MultipleColumnPrefixFilter.class);
118     byte [][] prefixes = multipleColumnPrefixFilter.getPrefix();
119     assertEquals(new String(prefixes[0]), "qualifier1");
120     assertEquals(new String(prefixes[1]), "qualifier2");
121   }
122 
123   @Test
124   public void testColumnCountGetFilter() throws IOException {
125     String filterString = " ColumnCountGetFilter(4)";
126     ColumnCountGetFilter columnCountGetFilter =
127       doTestFilter(filterString, ColumnCountGetFilter.class);
128     int limit = columnCountGetFilter.getLimit();
129     assertEquals(limit, 4);
130 
131     filterString = " ColumnCountGetFilter('abc')";
132     try {
133       doTestFilter(filterString, ColumnCountGetFilter.class);
134       assertTrue(false);
135     } catch (IllegalArgumentException e) {
136       System.out.println(e.getMessage());
137     }
138 
139     filterString = " ColumnCountGetFilter(2147483648)";
140     try {
141       doTestFilter(filterString, ColumnCountGetFilter.class);
142       assertTrue(false);
143     } catch (IllegalArgumentException e) {
144       System.out.println(e.getMessage());
145     }
146   }
147 
148   @Test
149   public void testPageFilter() throws IOException {
150     String filterString = " PageFilter(4)";
151     PageFilter pageFilter =
152       doTestFilter(filterString, PageFilter.class);
153     long pageSize = pageFilter.getPageSize();
154     assertEquals(pageSize, 4);
155 
156     filterString = " PageFilter('123')";
157     try {
158       doTestFilter(filterString, PageFilter.class);
159       assertTrue(false);
160     } catch (IllegalArgumentException e) {
161       System.out.println("PageFilter needs an int as an argument");
162     }
163   }
164 
165   @Test
166   public void testColumnPaginationFilter() throws IOException {
167     String filterString = "ColumnPaginationFilter(4, 6)";
168     ColumnPaginationFilter columnPaginationFilter =
169       doTestFilter(filterString, ColumnPaginationFilter.class);
170     int limit = columnPaginationFilter.getLimit();
171     assertEquals(limit, 4);
172     int offset = columnPaginationFilter.getOffset();
173     assertEquals(offset, 6);
174 
175     filterString = " ColumnPaginationFilter('124')";
176     try {
177       doTestFilter(filterString, ColumnPaginationFilter.class);
178       assertTrue(false);
179     } catch (IllegalArgumentException e) {
180       System.out.println("ColumnPaginationFilter needs two arguments");
181     }
182 
183     filterString = " ColumnPaginationFilter('4' , '123a')";
184     try {
185       doTestFilter(filterString, ColumnPaginationFilter.class);
186       assertTrue(false);
187     } catch (IllegalArgumentException e) {
188       System.out.println("ColumnPaginationFilter needs two ints as arguments");
189     }
190 
191     filterString = " ColumnPaginationFilter('4' , '-123')";
192     try {
193       doTestFilter(filterString, ColumnPaginationFilter.class);
194       assertTrue(false);
195     } catch (IllegalArgumentException e) {
196       System.out.println("ColumnPaginationFilter arguments should not be negative");
197     }
198   }
199 
200   @Test
201   public void testInclusiveStopFilter() throws IOException {
202     String filterString = "InclusiveStopFilter ('row 3')";
203     InclusiveStopFilter inclusiveStopFilter =
204       doTestFilter(filterString, InclusiveStopFilter.class);
205     byte [] stopRowKey = inclusiveStopFilter.getStopRowKey();
206     assertEquals(new String(stopRowKey), "row 3");
207   }
208 
209 
210   @Test
211   public void testTimestampsFilter() throws IOException {
212     String filterString = "TimestampsFilter(9223372036854775806, 6)";
213     TimestampsFilter timestampsFilter =
214       doTestFilter(filterString, TimestampsFilter.class);
215     List<Long> timestamps = timestampsFilter.getTimestamps();
216     assertEquals(timestamps.size(), 2);
217     assertEquals(timestamps.get(0), new Long(6));
218 
219     filterString = "TimestampsFilter()";
220     timestampsFilter = doTestFilter(filterString, TimestampsFilter.class);
221     timestamps = timestampsFilter.getTimestamps();
222     assertEquals(timestamps.size(), 0);
223 
224     filterString = "TimestampsFilter(9223372036854775808, 6)";
225     try {
226       doTestFilter(filterString, ColumnPaginationFilter.class);
227       assertTrue(false);
228     } catch (IllegalArgumentException e) {
229       System.out.println("Long Argument was too large");
230     }
231 
232     filterString = "TimestampsFilter(-45, 6)";
233     try {
234       doTestFilter(filterString, ColumnPaginationFilter.class);
235       assertTrue(false);
236     } catch (IllegalArgumentException e) {
237       System.out.println("Timestamp Arguments should not be negative");
238     }
239   }
240 
241   @Test
242   public void testRowFilter() throws IOException {
243     String filterString = "RowFilter ( =,   'binary:regionse')";
244     RowFilter rowFilter =
245       doTestFilter(filterString, RowFilter.class);
246     assertEquals(CompareFilter.CompareOp.EQUAL, rowFilter.getOperator());
247     assertTrue(rowFilter.getComparator() instanceof BinaryComparator);
248     BinaryComparator binaryComparator = (BinaryComparator) rowFilter.getComparator();
249     assertEquals("regionse", new String(binaryComparator.getValue()));
250   }
251 
252   @Test
253   public void testFamilyFilter() throws IOException {
254     String filterString = "FamilyFilter(>=, 'binaryprefix:pre')";
255     FamilyFilter familyFilter =
256       doTestFilter(filterString, FamilyFilter.class);
257     assertEquals(CompareFilter.CompareOp.GREATER_OR_EQUAL, familyFilter.getOperator());
258     assertTrue(familyFilter.getComparator() instanceof BinaryPrefixComparator);
259     BinaryPrefixComparator binaryPrefixComparator =
260       (BinaryPrefixComparator) familyFilter.getComparator();
261     assertEquals("pre", new String(binaryPrefixComparator.getValue()));
262   }
263 
264   @Test
265   public void testQualifierFilter() throws IOException {
266     String filterString = "QualifierFilter(=, 'regexstring:pre*')";
267     QualifierFilter qualifierFilter =
268       doTestFilter(filterString, QualifierFilter.class);
269     assertEquals(CompareFilter.CompareOp.EQUAL, qualifierFilter.getOperator());
270     assertTrue(qualifierFilter.getComparator() instanceof RegexStringComparator);
271     RegexStringComparator regexStringComparator =
272       (RegexStringComparator) qualifierFilter.getComparator();
273     assertEquals("pre*", new String(regexStringComparator.getValue()));
274   }
275 
276   @Test
277   public void testQualifierFilterNoCase() throws IOException {
278     String filterString = "QualifierFilter(=, 'regexstringnocase:pre*')";
279     QualifierFilter qualifierFilter =
280       doTestFilter(filterString, QualifierFilter.class);
281     assertEquals(CompareFilter.CompareOp.EQUAL, qualifierFilter.getOperator());
282     assertTrue(qualifierFilter.getComparator() instanceof RegexStringComparator);
283     RegexStringComparator regexStringComparator =
284       (RegexStringComparator) qualifierFilter.getComparator();
285     assertEquals("pre*", new String(regexStringComparator.getValue(), StandardCharsets.UTF_8));
286     int regexComparatorFlags = regexStringComparator.getEngine().getFlags();
287     assertEquals(Pattern.CASE_INSENSITIVE | Pattern.DOTALL, regexComparatorFlags);
288   }
289 
290   @Test
291   public void testValueFilter() throws IOException {
292     String filterString = "ValueFilter(!=, 'substring:pre')";
293     ValueFilter valueFilter =
294       doTestFilter(filterString, ValueFilter.class);
295     assertEquals(CompareFilter.CompareOp.NOT_EQUAL, valueFilter.getOperator());
296     assertTrue(valueFilter.getComparator() instanceof SubstringComparator);
297     SubstringComparator substringComparator =
298       (SubstringComparator) valueFilter.getComparator();
299     assertEquals("pre", new String(substringComparator.getValue()));
300   }
301 
302   @Test
303   public void testColumnRangeFilter() throws IOException {
304     String filterString = "ColumnRangeFilter('abc', true, 'xyz', false)";
305     ColumnRangeFilter columnRangeFilter =
306       doTestFilter(filterString, ColumnRangeFilter.class);
307     assertEquals("abc", new String(columnRangeFilter.getMinColumn()));
308     assertEquals("xyz", new String(columnRangeFilter.getMaxColumn()));
309     assertTrue(columnRangeFilter.isMinColumnInclusive());
310     assertFalse(columnRangeFilter.isMaxColumnInclusive());
311   }
312 
313   @Test
314   public void testDependentColumnFilter() throws IOException {
315     String filterString = "DependentColumnFilter('family', 'qualifier', true, =, 'binary:abc')";
316     DependentColumnFilter dependentColumnFilter =
317       doTestFilter(filterString, DependentColumnFilter.class);
318     assertEquals("family", new String(dependentColumnFilter.getFamily()));
319     assertEquals("qualifier", new String(dependentColumnFilter.getQualifier()));
320     assertTrue(dependentColumnFilter.getDropDependentColumn());
321     assertEquals(CompareFilter.CompareOp.EQUAL, dependentColumnFilter.getOperator());
322     assertTrue(dependentColumnFilter.getComparator() instanceof BinaryComparator);
323     BinaryComparator binaryComparator = (BinaryComparator)dependentColumnFilter.getComparator();
324     assertEquals("abc", new String(binaryComparator.getValue()));
325   }
326 
327   @Test
328   public void testSingleColumnValueFilter() throws IOException {
329     String filterString = "SingleColumnValueFilter " +
330       "('family', 'qualifier', >=, 'binary:a', true, false)";
331     SingleColumnValueFilter singleColumnValueFilter =
332       doTestFilter(filterString, SingleColumnValueFilter.class);
333     assertEquals("family", new String(singleColumnValueFilter.getFamily()));
334     assertEquals("qualifier", new String(singleColumnValueFilter.getQualifier()));
335     assertEquals(singleColumnValueFilter.getOperator(), CompareFilter.CompareOp.GREATER_OR_EQUAL);
336     assertTrue(singleColumnValueFilter.getComparator() instanceof BinaryComparator);
337     BinaryComparator binaryComparator = (BinaryComparator) singleColumnValueFilter.getComparator();
338     assertEquals(new String(binaryComparator.getValue()), "a");
339     assertTrue(singleColumnValueFilter.getFilterIfMissing());
340     assertFalse(singleColumnValueFilter.getLatestVersionOnly());
341 
342 
343     filterString = "SingleColumnValueFilter ('family', 'qualifier', >, 'binaryprefix:a')";
344     singleColumnValueFilter = doTestFilter(filterString, SingleColumnValueFilter.class);
345     assertEquals("family", new String(singleColumnValueFilter.getFamily()));
346     assertEquals("qualifier", new String(singleColumnValueFilter.getQualifier()));
347     assertEquals(singleColumnValueFilter.getOperator(), CompareFilter.CompareOp.GREATER);
348     assertTrue(singleColumnValueFilter.getComparator() instanceof BinaryPrefixComparator);
349     BinaryPrefixComparator binaryPrefixComparator =
350       (BinaryPrefixComparator) singleColumnValueFilter.getComparator();
351     assertEquals(new String(binaryPrefixComparator.getValue()), "a");
352     assertFalse(singleColumnValueFilter.getFilterIfMissing());
353     assertTrue(singleColumnValueFilter.getLatestVersionOnly());
354   }
355 
356   @Test
357   public void testSingleColumnValueExcludeFilter() throws IOException {
358     String filterString =
359       "SingleColumnValueExcludeFilter ('family', 'qualifier', <, 'binaryprefix:a')";
360     SingleColumnValueExcludeFilter singleColumnValueExcludeFilter =
361       doTestFilter(filterString, SingleColumnValueExcludeFilter.class);
362     assertEquals(singleColumnValueExcludeFilter.getOperator(), CompareFilter.CompareOp.LESS);
363     assertEquals("family", new String(singleColumnValueExcludeFilter.getFamily()));
364     assertEquals("qualifier", new String(singleColumnValueExcludeFilter.getQualifier()));
365     assertEquals(new String(singleColumnValueExcludeFilter.getComparator().getValue()), "a");
366     assertFalse(singleColumnValueExcludeFilter.getFilterIfMissing());
367     assertTrue(singleColumnValueExcludeFilter.getLatestVersionOnly());
368 
369     filterString = "SingleColumnValueExcludeFilter " +
370       "('family', 'qualifier', <=, 'binaryprefix:a', true, false)";
371     singleColumnValueExcludeFilter =
372       doTestFilter(filterString, SingleColumnValueExcludeFilter.class);
373     assertEquals("family", new String(singleColumnValueExcludeFilter.getFamily()));
374     assertEquals("qualifier", new String(singleColumnValueExcludeFilter.getQualifier()));
375     assertEquals(singleColumnValueExcludeFilter.getOperator(),
376                  CompareFilter.CompareOp.LESS_OR_EQUAL);
377     assertTrue(singleColumnValueExcludeFilter.getComparator() instanceof BinaryPrefixComparator);
378     BinaryPrefixComparator binaryPrefixComparator =
379       (BinaryPrefixComparator) singleColumnValueExcludeFilter.getComparator();
380     assertEquals(new String(binaryPrefixComparator.getValue()), "a");
381     assertTrue(singleColumnValueExcludeFilter.getFilterIfMissing());
382     assertFalse(singleColumnValueExcludeFilter.getLatestVersionOnly());
383   }
384 
385   @Test
386   public void testSkipFilter() throws IOException {
387     String filterString = "SKIP ValueFilter( =,  'binary:0')";
388     SkipFilter skipFilter =
389       doTestFilter(filterString, SkipFilter.class);
390     assertTrue(skipFilter.getFilter() instanceof ValueFilter);
391     ValueFilter valueFilter = (ValueFilter) skipFilter.getFilter();
392 
393     assertEquals(CompareFilter.CompareOp.EQUAL, valueFilter.getOperator());
394     assertTrue(valueFilter.getComparator() instanceof BinaryComparator);
395     BinaryComparator binaryComparator = (BinaryComparator) valueFilter.getComparator();
396     assertEquals("0", new String(binaryComparator.getValue()));
397   }
398 
399   @Test
400   public void testWhileFilter() throws IOException {
401     String filterString = " WHILE   RowFilter ( !=, 'binary:row1')";
402     WhileMatchFilter whileMatchFilter =
403       doTestFilter(filterString, WhileMatchFilter.class);
404     assertTrue(whileMatchFilter.getFilter() instanceof RowFilter);
405     RowFilter rowFilter = (RowFilter) whileMatchFilter.getFilter();
406 
407     assertEquals(CompareFilter.CompareOp.NOT_EQUAL, rowFilter.getOperator());
408     assertTrue(rowFilter.getComparator() instanceof BinaryComparator);
409     BinaryComparator binaryComparator = (BinaryComparator) rowFilter.getComparator();
410     assertEquals("row1", new String(binaryComparator.getValue()));
411   }
412 
413   @Test
414   public void testCompoundFilter1() throws IOException {
415     String filterString = " (PrefixFilter ('realtime')AND  FirstKeyOnlyFilter())";
416     FilterList filterList =
417       doTestFilter(filterString, FilterList.class);
418     ArrayList<Filter> filters = (ArrayList<Filter>) filterList.getFilters();
419 
420     assertTrue(filters.get(0) instanceof PrefixFilter);
421     assertTrue(filters.get(1) instanceof FirstKeyOnlyFilter);
422     PrefixFilter PrefixFilter = (PrefixFilter) filters.get(0);
423     byte [] prefix = PrefixFilter.getPrefix();
424     assertEquals(new String(prefix), "realtime");
425     FirstKeyOnlyFilter firstKeyOnlyFilter = (FirstKeyOnlyFilter) filters.get(1);
426   }
427 
428   @Test
429   public void testCompoundFilter2() throws IOException {
430     String filterString = "(PrefixFilter('realtime') AND QualifierFilter (>=, 'binary:e'))" +
431       "OR FamilyFilter (=, 'binary:qualifier') ";
432     FilterList filterList =
433       doTestFilter(filterString, FilterList.class);
434     ArrayList<Filter> filterListFilters = (ArrayList<Filter>) filterList.getFilters();
435     assertTrue(filterListFilters.get(0) instanceof FilterList);
436     assertTrue(filterListFilters.get(1) instanceof FamilyFilter);
437     assertEquals(filterList.getOperator(), FilterList.Operator.MUST_PASS_ONE);
438 
439     filterList = (FilterList) filterListFilters.get(0);
440     FamilyFilter familyFilter = (FamilyFilter) filterListFilters.get(1);
441 
442     filterListFilters = (ArrayList<Filter>)filterList.getFilters();
443     assertTrue(filterListFilters.get(0) instanceof PrefixFilter);
444     assertTrue(filterListFilters.get(1) instanceof QualifierFilter);
445     assertEquals(filterList.getOperator(), FilterList.Operator.MUST_PASS_ALL);
446 
447     assertEquals(CompareFilter.CompareOp.EQUAL, familyFilter.getOperator());
448     assertTrue(familyFilter.getComparator() instanceof BinaryComparator);
449     BinaryComparator binaryComparator = (BinaryComparator) familyFilter.getComparator();
450     assertEquals("qualifier", new String(binaryComparator.getValue()));
451 
452     PrefixFilter prefixFilter = (PrefixFilter) filterListFilters.get(0);
453     byte [] prefix = prefixFilter.getPrefix();
454     assertEquals(new String(prefix), "realtime");
455 
456     QualifierFilter qualifierFilter = (QualifierFilter) filterListFilters.get(1);
457     assertEquals(CompareFilter.CompareOp.GREATER_OR_EQUAL, qualifierFilter.getOperator());
458     assertTrue(qualifierFilter.getComparator() instanceof BinaryComparator);
459     binaryComparator = (BinaryComparator) qualifierFilter.getComparator();
460     assertEquals("e", new String(binaryComparator.getValue()));
461   }
462 
463   @Test
464   public void testCompoundFilter3() throws IOException {
465     String filterString = " ColumnPrefixFilter ('realtime')AND  " +
466       "FirstKeyOnlyFilter() OR SKIP FamilyFilter(=, 'substring:hihi')";
467     FilterList filterList =
468       doTestFilter(filterString, FilterList.class);
469     ArrayList<Filter> filters = (ArrayList<Filter>) filterList.getFilters();
470 
471     assertTrue(filters.get(0) instanceof FilterList);
472     assertTrue(filters.get(1) instanceof SkipFilter);
473 
474     filterList = (FilterList) filters.get(0);
475     SkipFilter skipFilter = (SkipFilter) filters.get(1);
476 
477     filters = (ArrayList<Filter>) filterList.getFilters();
478     assertTrue(filters.get(0) instanceof ColumnPrefixFilter);
479     assertTrue(filters.get(1) instanceof FirstKeyOnlyFilter);
480 
481     ColumnPrefixFilter columnPrefixFilter = (ColumnPrefixFilter) filters.get(0);
482     byte [] columnPrefix = columnPrefixFilter.getPrefix();
483     assertEquals(new String(columnPrefix), "realtime");
484 
485     FirstKeyOnlyFilter firstKeyOnlyFilter = (FirstKeyOnlyFilter) filters.get(1);
486 
487     assertTrue(skipFilter.getFilter() instanceof FamilyFilter);
488     FamilyFilter familyFilter = (FamilyFilter) skipFilter.getFilter();
489 
490     assertEquals(CompareFilter.CompareOp.EQUAL, familyFilter.getOperator());
491     assertTrue(familyFilter.getComparator() instanceof SubstringComparator);
492     SubstringComparator substringComparator =
493       (SubstringComparator) familyFilter.getComparator();
494     assertEquals("hihi", new String(substringComparator.getValue()));
495   }
496 
497   @Test
498   public void testCompoundFilter4() throws IOException {
499     String filterString = " ColumnPrefixFilter ('realtime') OR " +
500       "FirstKeyOnlyFilter() OR SKIP FamilyFilter(=, 'substring:hihi')";
501     FilterList filterList =
502       doTestFilter(filterString, FilterList.class);
503     ArrayList<Filter> filters = (ArrayList<Filter>) filterList.getFilters();
504 
505     assertTrue(filters.get(0) instanceof ColumnPrefixFilter);
506     assertTrue(filters.get(1) instanceof FirstKeyOnlyFilter);
507     assertTrue(filters.get(2) instanceof SkipFilter);
508 
509     ColumnPrefixFilter columnPrefixFilter = (ColumnPrefixFilter) filters.get(0);
510     FirstKeyOnlyFilter firstKeyOnlyFilter = (FirstKeyOnlyFilter) filters.get(1);
511     SkipFilter skipFilter = (SkipFilter) filters.get(2);
512 
513     byte [] columnPrefix = columnPrefixFilter.getPrefix();
514     assertEquals(new String(columnPrefix), "realtime");
515 
516     assertTrue(skipFilter.getFilter() instanceof FamilyFilter);
517     FamilyFilter familyFilter = (FamilyFilter) skipFilter.getFilter();
518 
519     assertEquals(CompareFilter.CompareOp.EQUAL, familyFilter.getOperator());
520     assertTrue(familyFilter.getComparator() instanceof SubstringComparator);
521     SubstringComparator substringComparator =
522       (SubstringComparator) familyFilter.getComparator();
523     assertEquals("hihi", new String(substringComparator.getValue()));
524   }
525 
526   @Test
527   public void testCompoundFilter5() throws IOException {
528     String filterStr = "(ValueFilter(!=, 'substring:pre'))";
529     ValueFilter valueFilter = doTestFilter(filterStr, ValueFilter.class);
530     assertTrue(valueFilter.getComparator() instanceof SubstringComparator);
531 
532     filterStr = "(ValueFilter(>=,'binary:x') AND (ValueFilter(<=,'binary:y')))"
533             + " OR ValueFilter(=,'binary:ab')";
534     filter = f.parseFilterString(filterStr);
535     assertTrue(filter instanceof FilterList);
536     List<Filter> list = ((FilterList) filter).getFilters();
537     assertEquals(2, list.size());
538     assertTrue(list.get(0) instanceof FilterList);
539     assertTrue(list.get(1) instanceof ValueFilter);
540   }
541 
542   @Test
543   public void testIncorrectCompareOperator() throws IOException {
544     String filterString = "RowFilter ('>>' , 'binary:region')";
545     try {
546       doTestFilter(filterString, RowFilter.class);
547       assertTrue(false);
548     } catch (IllegalArgumentException e) {
549       System.out.println("Incorrect compare operator >>");
550     }
551   }
552 
553   @Test
554   public void testIncorrectComparatorType () throws IOException {
555     String  filterString = "RowFilter ('>=' , 'binaryoperator:region')";
556     try {
557       doTestFilter(filterString, RowFilter.class);
558       assertTrue(false);
559     } catch (IllegalArgumentException e) {
560       System.out.println("Incorrect comparator type: binaryoperator");
561     }
562 
563     filterString = "RowFilter ('>=' 'regexstring:pre*')";
564     try {
565       doTestFilter(filterString, RowFilter.class);
566       assertTrue(false);
567     } catch (IllegalArgumentException e) {
568       System.out.println("RegexStringComparator can only be used with EQUAL or NOT_EQUAL");
569     }
570 
571     filterString = "SingleColumnValueFilter" +
572       " ('family', 'qualifier', '>=', 'substring:a', 'true', 'false')')";
573     try {
574       doTestFilter(filterString, RowFilter.class);
575       assertTrue(false);
576     } catch (IllegalArgumentException e) {
577       System.out.println("SubtringComparator can only be used with EQUAL or NOT_EQUAL");
578     }
579   }
580 
581   @Test
582   public void testPrecedence1() throws IOException {
583     String filterString = " (PrefixFilter ('realtime')AND  FirstKeyOnlyFilter()" +
584       " OR KeyOnlyFilter())";
585     FilterList filterList =
586       doTestFilter(filterString, FilterList.class);
587 
588     ArrayList<Filter> filters = (ArrayList<Filter>) filterList.getFilters();
589 
590     assertTrue(filters.get(0) instanceof FilterList);
591     assertTrue(filters.get(1) instanceof KeyOnlyFilter);
592 
593     filterList = (FilterList) filters.get(0);
594     filters = (ArrayList<Filter>) filterList.getFilters();
595 
596     assertTrue(filters.get(0) instanceof PrefixFilter);
597     assertTrue(filters.get(1) instanceof FirstKeyOnlyFilter);
598 
599     PrefixFilter prefixFilter = (PrefixFilter)filters.get(0);
600     byte [] prefix = prefixFilter.getPrefix();
601     assertEquals(new String(prefix), "realtime");
602   }
603 
604   @Test
605   public void testPrecedence2() throws IOException {
606     String filterString = " PrefixFilter ('realtime')AND  SKIP FirstKeyOnlyFilter()" +
607       "OR KeyOnlyFilter()";
608     FilterList filterList =
609       doTestFilter(filterString, FilterList.class);
610     ArrayList<Filter> filters = (ArrayList<Filter>) filterList.getFilters();
611 
612     assertTrue(filters.get(0) instanceof FilterList);
613     assertTrue(filters.get(1) instanceof KeyOnlyFilter);
614 
615     filterList = (FilterList) filters.get(0);
616     filters = (ArrayList<Filter>) filterList.getFilters();
617 
618     assertTrue(filters.get(0) instanceof PrefixFilter);
619     assertTrue(filters.get(1) instanceof SkipFilter);
620 
621     PrefixFilter prefixFilter = (PrefixFilter)filters.get(0);
622     byte [] prefix = prefixFilter.getPrefix();
623     assertEquals(new String(prefix), "realtime");
624 
625     SkipFilter skipFilter = (SkipFilter)filters.get(1);
626     assertTrue(skipFilter.getFilter() instanceof FirstKeyOnlyFilter);
627   }
628 
629   @Test
630   public void testUnescapedQuote1 () throws IOException {
631     String filterString = "InclusiveStopFilter ('row''3')";
632     InclusiveStopFilter inclusiveStopFilter =
633       doTestFilter(filterString, InclusiveStopFilter.class);
634     byte [] stopRowKey = inclusiveStopFilter.getStopRowKey();
635     assertEquals(new String(stopRowKey), "row'3");
636   }
637 
638   @Test
639   public void testUnescapedQuote2 () throws IOException {
640     String filterString = "InclusiveStopFilter ('row''3''')";
641     InclusiveStopFilter inclusiveStopFilter =
642       doTestFilter(filterString, InclusiveStopFilter.class);
643     byte [] stopRowKey = inclusiveStopFilter.getStopRowKey();
644     assertEquals(new String(stopRowKey), "row'3'");
645   }
646 
647   @Test
648   public void testUnescapedQuote3 () throws IOException {
649     String filterString = "	InclusiveStopFilter ('''')";
650     InclusiveStopFilter inclusiveStopFilter =
651       doTestFilter(filterString, InclusiveStopFilter.class);
652     byte [] stopRowKey = inclusiveStopFilter.getStopRowKey();
653     assertEquals(new String(stopRowKey), "'");
654   }
655 
656   @Test
657   public void testIncorrectFilterString () throws IOException {
658     String filterString = "()";
659     byte [] filterStringAsByteArray = Bytes.toBytes(filterString);
660     try {
661       filter = f.parseFilterString(filterStringAsByteArray);
662       assertTrue(false);
663     } catch (IllegalArgumentException e) {
664       System.out.println(e.getMessage());
665     }
666   }
667 
668   @Test
669   public void testCorrectFilterString () throws IOException {
670     String filterString = "(FirstKeyOnlyFilter())";
671     FirstKeyOnlyFilter firstKeyOnlyFilter =
672       doTestFilter(filterString, FirstKeyOnlyFilter.class);
673   }
674 
675   @Test
676   public void testRegisterFilter() {
677     ParseFilter.registerFilter("MyFilter", "some.class");
678 
679     assertTrue(f.getSupportedFilters().contains("MyFilter"));
680   }
681 
682   private <T extends Filter> T doTestFilter(String filterString, Class<T> clazz) throws IOException {
683     byte [] filterStringAsByteArray = Bytes.toBytes(filterString);
684     filter = f.parseFilterString(filterStringAsByteArray);
685     assertEquals(clazz, filter.getClass());
686     return clazz.cast(filter);
687   }
688 
689 }
690