summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorChristoph Büscher <christoph@elastic.co>2017-06-27 17:02:15 +0200
committerGitHub <noreply@github.com>2017-06-27 17:02:15 +0200
commitc55dc23270b5969d009f0c1caea9780ab4f22a44 (patch)
tree6682398d4b3b109eeab6e821e38dba5ee584068c /core
parent11fcfaae6850b37b514f688c290d6fc18b400d00 (diff)
Tests: Add parsing test for AggregationsTests (#25396)
We already have these tests in InternalAggregationTestCase to check random insertions into the response xContent so that we don't fail on future changes in the response format. This change adds the same to AggregationsTests and runs on a whole aggregations tree. Unfortunately we need to exclude many places in the xContent from random insertion, but I added a long comment trying to explaine those.
Diffstat (limited to 'core')
-rw-r--r--core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java50
1 files changed, 49 insertions, 1 deletions
diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java
index e92601aca0..f7a5b2f7f3 100644
--- a/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java
+++ b/core/src/test/java/org/elasticsearch/search/aggregations/AggregationsTests.java
@@ -23,12 +23,14 @@ import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.ToXContent;
+import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.action.search.RestSearchAction;
+import org.elasticsearch.search.aggregations.Aggregation.CommonFields;
import org.elasticsearch.search.aggregations.bucket.adjacency.InternalAdjacencyMatrixTests;
import org.elasticsearch.search.aggregations.bucket.filter.InternalFilterTests;
import org.elasticsearch.search.aggregations.bucket.filters.InternalFiltersTests;
@@ -82,9 +84,11 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
import static java.util.Collections.singletonMap;
+import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
/**
* This class tests that aggregations parsing works properly. It checks that we can parse
@@ -175,11 +179,55 @@ public class AggregationsTests extends ESTestCase {
}
public void testFromXContent() throws IOException {
+ parseAndAssert(false);
+ }
+
+ public void testFromXContentWithRandomFields() throws IOException {
+ parseAndAssert(true);
+ }
+
+ /**
+ * Test that parsing works for a randomly created Aggregations object with a
+ * randomized aggregation tree. The test randomly chooses an
+ * {@link XContentType}, randomizes the order of the {@link XContent} fields
+ * and randomly sets the `humanReadable` flag when rendering the
+ * {@link XContent}.
+ *
+ * @param addRandomFields
+ * if set, this will also add random {@link XContent} fields to
+ * tests that the parsers are lenient to future additions to rest
+ * responses
+ */
+ private void parseAndAssert(boolean addRandomFields) throws IOException {
XContentType xContentType = randomFrom(XContentType.values());
final ToXContent.Params params = new ToXContent.MapParams(singletonMap(RestSearchAction.TYPED_KEYS_PARAM, "true"));
Aggregations aggregations = createTestInstance();
BytesReference originalBytes = toShuffledXContent(aggregations, xContentType, params, randomBoolean());
- try (XContentParser parser = createParser(xContentType.xContent(), originalBytes)) {
+ BytesReference mutated;
+ if (addRandomFields) {
+ /*
+ * - don't insert into the root object because it should only contain the named aggregations to test
+ *
+ * - don't insert into the "meta" object, because we pass on everything we find there
+ *
+ * - we don't want to directly insert anything random into "buckets" objects, they are used with
+ * "keyed" aggregations and contain named bucket objects. Any new named object on this level should
+ * also be a bucket and be parsed as such.
+ *
+ * - we cannot insert randomly into VALUE or VALUES objects e.g. in Percentiles, the keys need to be numeric there
+ *
+ * - we cannot insert into ExtendedMatrixStats "covariance" or "correlation" fields, their syntax is strict
+ */
+ Predicate<String> excludes = path -> (path.isEmpty() || path.endsWith("aggregations")
+ || path.endsWith(Aggregation.CommonFields.META.getPreferredName())
+ || path.endsWith(Aggregation.CommonFields.BUCKETS.getPreferredName())
+ || path.endsWith(CommonFields.VALUES.getPreferredName()) || path.endsWith("covariance") || path.endsWith("correlation")
+ || path.contains(CommonFields.VALUE.getPreferredName()));
+ mutated = insertRandomFields(xContentType, originalBytes, excludes, random());
+ } else {
+ mutated = originalBytes;
+ }
+ try (XContentParser parser = createParser(xContentType.xContent(), mutated)) {
assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken());
assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken());
assertEquals(Aggregations.AGGREGATIONS_FIELD, parser.currentName());