Skip to content

Commit fafdbea

Browse files
committed
[Test] Use a common testing class for all XContent filtering tests (#25491)
We have two ways to filter XContent: - The first method is to parse the XContent as a map and use XContentMapValues.filter(). This method filters the content of the map using an automaton. It is used for source filtering, both at search and indexing time. It performs well but can generate a lot of objects and garbage collections when large XContent are filtered. It also returns empty objects (see f2710c1) when all the sub fields have been filtered out and handle dots in field names as if they were sub fields. - The second method is to parse the XContent and copy the XContentParser structure to a XContentBuilder initialized with includes/excludes filters. This method uses the Jackson streaming filter feature. It is used by the Response Filtering ('filter_path') feature. It does not generate a lot of objects, and does not return empty objects and also does not handle dots in field names explicitely. Both methods have similar goals but different tests. This commit changes the current XContentBuilder test class so that it becomes a more generic testing class and we can now ensure that filtering methods generate the same results. It also removes some tests from the XContentMapValuesTests class that should be in XContentParserTests.
1 parent 9cfcc73 commit fafdbea

File tree

8 files changed

+550
-427
lines changed

8 files changed

+550
-427
lines changed

core/src/test/java/org/elasticsearch/common/xcontent/XContentParserTests.java

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@
2626

2727
import java.io.IOException;
2828
import java.util.Arrays;
29+
import java.util.Collections;
2930
import java.util.List;
3031
import java.util.Map;
3132

33+
import static java.util.Collections.emptyMap;
34+
import static java.util.Collections.singletonMap;
3235
import static org.hamcrest.Matchers.contains;
3336
import static org.hamcrest.Matchers.containsString;
3437
import static org.hamcrest.Matchers.equalTo;
@@ -130,4 +133,84 @@ public void testReadBooleans() throws IOException {
130133
assertTrue(parser.booleanValue());
131134
}
132135
}
136+
137+
public void testEmptyList() throws IOException {
138+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
139+
.startArray("some_array")
140+
.endArray().endObject();
141+
142+
try (XContentParser parser = createParser(JsonXContent.jsonXContent, builder.string())) {
143+
assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken());
144+
assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken());
145+
assertEquals("some_array", parser.currentName());
146+
if (random().nextBoolean()) {
147+
// sometimes read the start array token, sometimes not
148+
assertEquals(XContentParser.Token.START_ARRAY, parser.nextToken());
149+
}
150+
assertEquals(Collections.emptyList(), parser.list());
151+
}
152+
}
153+
154+
public void testSimpleList() throws IOException {
155+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
156+
.startArray("some_array")
157+
.value(1)
158+
.value(3)
159+
.value(0)
160+
.endArray().endObject();
161+
162+
try (XContentParser parser = createParser(JsonXContent.jsonXContent, builder.string())) {
163+
assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken());
164+
assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken());
165+
assertEquals("some_array", parser.currentName());
166+
if (random().nextBoolean()) {
167+
// sometimes read the start array token, sometimes not
168+
assertEquals(XContentParser.Token.START_ARRAY, parser.nextToken());
169+
}
170+
assertEquals(Arrays.asList(1, 3, 0), parser.list());
171+
}
172+
}
173+
174+
public void testNestedList() throws IOException {
175+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
176+
.startArray("some_array")
177+
.startArray().endArray()
178+
.startArray().value(1).value(3).endArray()
179+
.startArray().value(2).endArray()
180+
.endArray().endObject();
181+
182+
try (XContentParser parser = createParser(JsonXContent.jsonXContent, builder.string())) {
183+
assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken());
184+
assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken());
185+
assertEquals("some_array", parser.currentName());
186+
if (random().nextBoolean()) {
187+
// sometimes read the start array token, sometimes not
188+
assertEquals(XContentParser.Token.START_ARRAY, parser.nextToken());
189+
}
190+
assertEquals(
191+
Arrays.asList(Collections.<Integer>emptyList(), Arrays.asList(1, 3), Arrays.asList(2)),
192+
parser.list());
193+
}
194+
}
195+
196+
public void testNestedMapInList() throws IOException {
197+
XContentBuilder builder = XContentFactory.jsonBuilder().startObject()
198+
.startArray("some_array")
199+
.startObject().field("foo", "bar").endObject()
200+
.startObject().endObject()
201+
.endArray().endObject();
202+
203+
try (XContentParser parser = createParser(JsonXContent.jsonXContent, builder.string())) {
204+
assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken());
205+
assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken());
206+
assertEquals("some_array", parser.currentName());
207+
if (random().nextBoolean()) {
208+
// sometimes read the start array token, sometimes not
209+
assertEquals(XContentParser.Token.START_ARRAY, parser.nextToken());
210+
}
211+
assertEquals(
212+
Arrays.asList(singletonMap("foo", "bar"), emptyMap()),
213+
parser.list());
214+
}
215+
}
133216
}

0 commit comments

Comments
 (0)