1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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 }