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    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.hbtop;
19  
20  import static org.hamcrest.CoreMatchers.is;
21  import static org.hamcrest.CoreMatchers.notNullValue;
22  import static org.hamcrest.CoreMatchers.nullValue;
23  import static org.junit.Assert.assertThat;
24  
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.Collections;
28  import java.util.List;
29  import org.apache.hadoop.hbase.hbtop.field.Field;
30  import org.apache.hadoop.hbase.hbtop.field.Size;
31  import org.apache.hadoop.hbase.testclassification.SmallTests;
32  import org.junit.Test;
33  import org.junit.experimental.categories.Category;
34  
35  @Category(SmallTests.class)
36  public class TestRecordFilter {
37  
38    @Test
39    public void testParseAndBuilder() {
40      testParseAndBuilder("REGION=region1", false,
41        RecordFilter.newBuilder(Field.REGION).equal("region1"));
42  
43      testParseAndBuilder("REGION=", false,
44        RecordFilter.newBuilder(Field.REGION).equal(""));
45  
46      testParseAndBuilder("!REGION=region1", false,
47        RecordFilter.newBuilder(Field.REGION).notEqual("region1"));
48  
49      testParseAndBuilder("REGION==region2", true,
50        RecordFilter.newBuilder(Field.REGION, true).doubleEquals("region2"));
51  
52      testParseAndBuilder("!REGION==region2", true,
53        RecordFilter.newBuilder(Field.REGION, true).notDoubleEquals("region2"));
54  
55      testParseAndBuilder("#REQ/S>100", false,
56        RecordFilter.newBuilder(Field.REQUEST_COUNT_PER_SECOND).greater(100L));
57  
58      testParseAndBuilder("!#REQ/S>100", false,
59        RecordFilter.newBuilder(Field.REQUEST_COUNT_PER_SECOND).notGreater(100L));
60  
61      testParseAndBuilder("SF>=50MB", true,
62        RecordFilter.newBuilder(Field.STORE_FILE_SIZE, true).greaterOrEqual("50MB"));
63  
64      testParseAndBuilder("!SF>=50MB", true,
65        RecordFilter.newBuilder(Field.STORE_FILE_SIZE, true).notGreaterOrEqual("50MB"));
66  
67      testParseAndBuilder("#REQ/S<20", false,
68        RecordFilter.newBuilder(Field.REQUEST_COUNT_PER_SECOND).less(20L));
69  
70      testParseAndBuilder("!#REQ/S<20", false,
71        RecordFilter.newBuilder(Field.REQUEST_COUNT_PER_SECOND).notLess(20L));
72  
73      testParseAndBuilder("%COMP<=50%", true,
74        RecordFilter.newBuilder(Field.COMPACTION_PROGRESS, true).lessOrEqual("50%"));
75  
76      testParseAndBuilder("!%COMP<=50%", true,
77        RecordFilter.newBuilder(Field.COMPACTION_PROGRESS, true).notLessOrEqual("50%"));
78    }
79  
80    private void testParseAndBuilder(String filterString, boolean ignoreCase, RecordFilter expected) {
81      RecordFilter actual = RecordFilter.parse(filterString, ignoreCase);
82      assertThat(expected, is(actual));
83    }
84  
85    @Test
86    public void testParseFailure() {
87      RecordFilter filter = RecordFilter.parse("REGIO=region1", false);
88      assertThat(filter, is(nullValue()));
89  
90      filter = RecordFilter.parse("", false);
91      assertThat(filter, is(nullValue()));
92  
93      filter = RecordFilter.parse("#REQ/S==aaa", false);
94      assertThat(filter, is(nullValue()));
95  
96      filter = RecordFilter.parse("SF>=50", false);
97      assertThat(filter, is(nullValue()));
98    }
99  
100   @Test
101   public void testToString() {
102     testToString("REGION=region1");
103     testToString("!REGION=region1");
104     testToString("REGION==region2");
105     testToString("!REGION==region2");
106     testToString("#REQ/S>100");
107     testToString("!#REQ/S>100");
108     testToString("SF>=50.0MB");
109     testToString("!SF>=50.0MB");
110     testToString("#REQ/S<20");
111     testToString("!#REQ/S<20");
112     testToString("%COMP<=50.00%");
113     testToString("!%COMP<=50.00%");
114   }
115 
116   private void testToString(String filterString) {
117     RecordFilter filter = RecordFilter.parse(filterString, false);
118     assertThat(filter, is(notNullValue()));
119     assertThat(filterString, is(filter.toString()));
120   }
121 
122   @Test
123   public void testFilters() {
124     List<Record> records = createTestRecords();
125 
126     testFilter(records, "REGION=region", false,
127       "region1", "region2", "region3", "region4", "region5");
128     testFilter(records, "!REGION=region", false);
129     testFilter(records, "REGION=Region", false);
130 
131     testFilter(records, "REGION==region", false);
132     testFilter(records, "REGION==region1", false, "region1");
133     testFilter(records, "!REGION==region1", false, "region2", "region3", "region4", "region5");
134 
135     testFilter(records, "#REQ/S==100", false, "region1");
136     testFilter(records, "#REQ/S>100", false, "region2", "region5");
137     testFilter(records, "SF>=100MB", false, "region1", "region2", "region4", "region5");
138     testFilter(records, "!#SF>=10", false, "region1", "region4");
139     testFilter(records, "LOCALITY<0.5", false, "region5");
140     testFilter(records, "%COMP<=50%", false, "region2", "region3", "region4", "region5");
141 
142     testFilters(records, Arrays.asList("SF>=100MB", "#REQ/S>100"), false,
143       "region2", "region5");
144     testFilters(records, Arrays.asList("%COMP<=50%", "!#SF>=10"), false, "region4");
145     testFilters(records, Arrays.asList("!REGION==region1", "LOCALITY<0.5", "#REQ/S>100"), false,
146       "region5");
147   }
148 
149   @Test
150   public void testFiltersIgnoreCase() {
151     List<Record> records = createTestRecords();
152 
153     testFilter(records, "REGION=Region", true,
154       "region1", "region2", "region3", "region4", "region5");
155     testFilter(records, "REGION=REGION", true,
156       "region1", "region2", "region3", "region4", "region5");
157   }
158 
159   private List<Record> createTestRecords() {
160     List<Record> ret = new ArrayList<>();
161     ret.add(createTestRecord("region1", 100L, new Size(100, Size.Unit.MEGABYTE), 2, 1.0f, 80f));
162     ret.add(createTestRecord("region2", 120L, new Size(100, Size.Unit.GIGABYTE), 10, 0.5f, 20f));
163     ret.add(createTestRecord("region3", 50L, new Size(500, Size.Unit.KILOBYTE), 15, 0.8f, 50f));
164     ret.add(createTestRecord("region4", 90L, new Size(10, Size.Unit.TERABYTE), 5, 0.9f, 30f));
165     ret.add(createTestRecord("region5", 200L, new Size(1, Size.Unit.PETABYTE), 13, 0.1f, 40f));
166     return ret;
167   }
168 
169   private Record createTestRecord(String region, long requestCountPerSecond,
170     Size storeFileSize, int numStoreFiles, float locality, float compactionProgress) {
171     Record.Builder builder = Record.builder();
172     builder.put(Field.REGION, region);
173     builder.put(Field.REQUEST_COUNT_PER_SECOND, requestCountPerSecond);
174     builder.put(Field.STORE_FILE_SIZE, storeFileSize);
175     builder.put(Field.NUM_STORE_FILES, numStoreFiles);
176     builder.put(Field.LOCALITY, locality);
177     builder.put(Field.COMPACTION_PROGRESS, compactionProgress);
178     return builder.build();
179   }
180 
181   private void testFilter(List<Record> records, String filterString, boolean ignoreCase,
182     String... expectedRegions) {
183     testFilters(records, Collections.singletonList(filterString), ignoreCase, expectedRegions);
184   }
185 
186   private void testFilters(List<Record> records, List<String> filterStrings, boolean ignoreCase,
187     String... expectedRegions) {
188 
189     List<String> actual = new ArrayList<>();
190     for (Record record : records) {
191       boolean filter = false;
192       for (String filterString : filterStrings) {
193         if (!RecordFilter.parse(filterString, ignoreCase).execute(record)) {
194           filter = true;
195         }
196       }
197       if (!filter) {
198         actual.add(record.get(Field.REGION).asString());
199       }
200     }
201 
202     assertThat(actual.size(), is(expectedRegions.length));
203     for (int i = 0; i < actual.size(); i++) {
204       String actualRegion = actual.get(i);
205       String expectedRegion = expectedRegions[i];
206       assertThat(actualRegion, is(expectedRegion));
207     }
208   }
209 }