[TEST] Add test for Aggregations#fromXContent (#24524)
AggregationsTests#testFromXContent verifies that parsing of aggregations works by combining multiple aggs at the same level, and also adding sub-aggregations to multi bucket and single bucket aggs, up to a maximum depth of 5.
This commit is contained in:
parent
1959fd6a1a
commit
c5bdbecc64
|
@ -128,7 +128,6 @@ public class Aggregations implements Iterable<Aggregation>, ToXContent {
|
|||
return builder;
|
||||
}
|
||||
|
||||
//TODO add tests for this method
|
||||
public static Aggregations fromXContent(XContentParser parser) throws IOException {
|
||||
final List<Aggregation> aggregations = new ArrayList<>();
|
||||
XContentParser.Token token;
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.search.aggregations;
|
||||
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
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.bucket.InternalSingleBucketAggregationTestCase;
|
||||
import org.elasticsearch.search.aggregations.bucket.histogram.InternalDateHistogramTests;
|
||||
import org.elasticsearch.search.aggregations.bucket.histogram.InternalHistogramTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.InternalExtendedStatsTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.InternalMaxTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.InternalStatsBucketTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.InternalStatsTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvgTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.cardinality.InternalCardinalityTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.geobounds.InternalGeoBoundsTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.geocentroid.InternalGeoCentroidTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.min.InternalMinTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.percentiles.hdr.InternalHDRPercentilesRanksTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.percentiles.hdr.InternalHDRPercentilesTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.percentiles.tdigest.InternalTDigestPercentilesRanksTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.percentiles.tdigest.InternalTDigestPercentilesTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.sum.InternalSumTests;
|
||||
import org.elasticsearch.search.aggregations.metrics.valuecount.InternalValueCountTests;
|
||||
import org.elasticsearch.search.aggregations.pipeline.InternalSimpleValueTests;
|
||||
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.InternalBucketMetricValueTests;
|
||||
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.percentile.InternalPercentilesBucketTests;
|
||||
import org.elasticsearch.search.aggregations.pipeline.bucketmetrics.stats.extended.InternalExtendedStatsBucketTests;
|
||||
import org.elasticsearch.search.aggregations.pipeline.derivative.InternalDerivativeTests;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.hamcrest.ElasticsearchAssertions;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
|
||||
/**
|
||||
* This class tests that aggregations parsing works properly. It checks that we can parse
|
||||
* different aggregations and adds sub-aggregations where applicable.
|
||||
*
|
||||
*/
|
||||
public class AggregationsTests extends ESTestCase {
|
||||
|
||||
private static final List<InternalAggregationTestCase> aggsTests = getAggsTests();
|
||||
|
||||
private static List<InternalAggregationTestCase> getAggsTests() {
|
||||
List<InternalAggregationTestCase> aggsTests = new ArrayList<>();
|
||||
aggsTests.add(new InternalCardinalityTests());
|
||||
aggsTests.add(new InternalTDigestPercentilesTests());
|
||||
aggsTests.add(new InternalTDigestPercentilesRanksTests());
|
||||
aggsTests.add(new InternalHDRPercentilesTests());
|
||||
aggsTests.add(new InternalHDRPercentilesRanksTests());
|
||||
aggsTests.add(new InternalPercentilesBucketTests());
|
||||
aggsTests.add(new InternalMinTests());
|
||||
aggsTests.add(new InternalMaxTests());
|
||||
aggsTests.add(new InternalAvgTests());
|
||||
aggsTests.add(new InternalSumTests());
|
||||
aggsTests.add(new InternalValueCountTests());
|
||||
aggsTests.add(new InternalSimpleValueTests());
|
||||
aggsTests.add(new InternalDerivativeTests());
|
||||
aggsTests.add(new InternalBucketMetricValueTests());
|
||||
aggsTests.add(new InternalStatsTests());
|
||||
aggsTests.add(new InternalStatsBucketTests());
|
||||
aggsTests.add(new InternalExtendedStatsTests());
|
||||
aggsTests.add(new InternalExtendedStatsBucketTests());
|
||||
aggsTests.add(new InternalGeoBoundsTests());
|
||||
aggsTests.add(new InternalGeoCentroidTests());
|
||||
aggsTests.add(new InternalHistogramTests());
|
||||
aggsTests.add(new InternalDateHistogramTests());
|
||||
return Collections.unmodifiableList(aggsTests);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NamedXContentRegistry xContentRegistry() {
|
||||
return new NamedXContentRegistry(InternalAggregationTestCase.getNamedXContents());
|
||||
}
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
for (InternalAggregationTestCase aggsTest : aggsTests) {
|
||||
aggsTest.setUp();
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() throws Exception {
|
||||
for (InternalAggregationTestCase aggsTest : aggsTests) {
|
||||
aggsTest.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
public void testFromXContent() 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)) {
|
||||
assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||
assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken());
|
||||
assertEquals(Aggregations.AGGREGATIONS_FIELD, parser.currentName());
|
||||
assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||
Aggregations parsedAggregations = Aggregations.fromXContent(parser);
|
||||
BytesReference parsedBytes = XContentHelper.toXContent(parsedAggregations, xContentType, randomBoolean());
|
||||
ElasticsearchAssertions.assertToXContentEquivalent(originalBytes, parsedBytes, xContentType);
|
||||
}
|
||||
}
|
||||
|
||||
private static InternalAggregations createTestInstance() {
|
||||
return createTestInstance(0, 5);
|
||||
}
|
||||
|
||||
private static InternalAggregations createTestInstance(final int currentDepth, final int maxDepth) {
|
||||
int numAggs = randomIntBetween(1, 5);
|
||||
List<InternalAggregation> aggs = new ArrayList<>(numAggs);
|
||||
for (int i = 0; i < numAggs; i++) {
|
||||
InternalAggregationTestCase testCase = randomFrom(aggsTests);
|
||||
if (testCase instanceof InternalMultiBucketAggregationTestCase && currentDepth < maxDepth) {
|
||||
InternalMultiBucketAggregationTestCase multiBucketAggTestCase = (InternalMultiBucketAggregationTestCase) testCase;
|
||||
multiBucketAggTestCase.subAggregationsSupplier = () -> createTestInstance(currentDepth + 1, maxDepth);
|
||||
}
|
||||
if (testCase instanceof InternalSingleBucketAggregationTestCase && currentDepth < maxDepth) {
|
||||
InternalSingleBucketAggregationTestCase singleBucketAggTestCase = (InternalSingleBucketAggregationTestCase) testCase;
|
||||
singleBucketAggTestCase.subAggregationsSupplier = () -> createTestInstance(currentDepth + 1, maxDepth);
|
||||
}
|
||||
aggs.add(testCase.createTestInstance());
|
||||
}
|
||||
return new InternalAggregations(aggs);
|
||||
}
|
||||
}
|
|
@ -21,36 +21,42 @@ package org.elasticsearch.search.aggregations;
|
|||
|
||||
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
|
||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
||||
public abstract class InternalMultiBucketAggregationTestCase<T extends InternalAggregation & MultiBucketsAggregation>
|
||||
extends InternalAggregationTestCase<T> {
|
||||
|
||||
private boolean hasSubAggregations;
|
||||
Supplier<InternalAggregations> subAggregationsSupplier;
|
||||
|
||||
@Before
|
||||
public void initHasSubAggregations() {
|
||||
hasSubAggregations = randomBoolean();
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
if (randomBoolean()) {
|
||||
subAggregationsSupplier = () -> InternalAggregations.EMPTY;
|
||||
} else {
|
||||
subAggregationsSupplier = () -> {
|
||||
final int numAggregations = randomIntBetween(1, 3);
|
||||
List<InternalAggregation> aggs = new ArrayList<>();
|
||||
for (int i = 0; i < numAggregations; i++) {
|
||||
aggs.add(createTestInstance(randomAlphaOfLength(5), emptyList(), emptyMap(), InternalAggregations.EMPTY));
|
||||
}
|
||||
return new InternalAggregations(aggs);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final T createTestInstance(String name, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
|
||||
List<InternalAggregation> internal = new ArrayList<>();
|
||||
if (hasSubAggregations) {
|
||||
final int numAggregations = randomIntBetween(1, 3);
|
||||
for (int i = 0; i <numAggregations; i++) {
|
||||
internal.add(createTestInstance(randomAlphaOfLength(5), pipelineAggregators, emptyMap(), InternalAggregations.EMPTY));
|
||||
}
|
||||
}
|
||||
return createTestInstance(name, pipelineAggregators, metaData, new InternalAggregations(internal));
|
||||
return createTestInstance(name, pipelineAggregators, metaData, subAggregationsSupplier.get());
|
||||
}
|
||||
|
||||
protected abstract T createTestInstance(String name, List<PipelineAggregator> pipelineAggregators,
|
||||
|
|
|
@ -29,31 +29,43 @@ import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
||||
public abstract class InternalSingleBucketAggregationTestCase<T extends InternalSingleBucketAggregation>
|
||||
extends InternalAggregationTestCase<T> {
|
||||
|
||||
private final boolean hasInternalMax = randomBoolean();
|
||||
private final boolean hasInternalMin = randomBoolean();
|
||||
|
||||
public Supplier<InternalAggregations> subAggregationsSupplier;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
subAggregationsSupplier = () -> {
|
||||
List<InternalAggregation> aggs = new ArrayList<>();
|
||||
if (hasInternalMax) {
|
||||
aggs.add(new InternalMax("max", randomDouble(), randomNumericDocValueFormat(), emptyList(), emptyMap()));
|
||||
}
|
||||
if (hasInternalMin) {
|
||||
aggs.add(new InternalMin("min", randomDouble(), randomNumericDocValueFormat(), emptyList(), emptyMap()));
|
||||
}
|
||||
return new InternalAggregations(aggs);
|
||||
};
|
||||
}
|
||||
|
||||
protected abstract T createTestInstance(String name, long docCount, InternalAggregations aggregations,
|
||||
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData);
|
||||
protected abstract void extraAssertReduced(T reduced, List<T> inputs);
|
||||
|
||||
@Override
|
||||
protected final T createTestInstance(String name, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
|
||||
List<InternalAggregation> internal = new ArrayList<>();
|
||||
if (hasInternalMax) {
|
||||
internal.add(new InternalMax("max", randomDouble(), randomNumericDocValueFormat(), emptyList(), emptyMap()));
|
||||
}
|
||||
if (hasInternalMin) {
|
||||
internal.add(new InternalMin("min", randomDouble(), randomNumericDocValueFormat(), emptyList(), emptyMap()));
|
||||
}
|
||||
// we shouldn't use the full long range here since we sum doc count on reduce, and don't want to overflow the long range there
|
||||
long docCount = between(0, Integer.MAX_VALUE);
|
||||
return createTestInstance(name, docCount, new InternalAggregations(internal), pipelineAggregators, metaData);
|
||||
return createTestInstance(name, docCount, subAggregationsSupplier.get(), pipelineAggregators, metaData);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.elasticsearch.search.aggregations.InternalMultiBucketAggregationTestC
|
|||
import org.elasticsearch.search.aggregations.ParsedMultiBucketAggregation;
|
||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -42,8 +41,9 @@ public class InternalDateHistogramTests extends InternalMultiBucketAggregationTe
|
|||
private boolean keyed;
|
||||
private DocValueFormat format;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
keyed = randomBoolean();
|
||||
format = randomNumericDocValueFormat();
|
||||
}
|
||||
|
|
|
@ -22,12 +22,10 @@ package org.elasticsearch.search.aggregations.bucket.histogram;
|
|||
import org.apache.lucene.util.TestUtil;
|
||||
import org.elasticsearch.common.io.stream.Writeable.Reader;
|
||||
import org.elasticsearch.search.DocValueFormat;
|
||||
import org.elasticsearch.search.aggregations.InternalAggregationTestCase;
|
||||
import org.elasticsearch.search.aggregations.InternalAggregations;
|
||||
import org.elasticsearch.search.aggregations.InternalMultiBucketAggregationTestCase;
|
||||
import org.elasticsearch.search.aggregations.ParsedMultiBucketAggregation;
|
||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -39,8 +37,9 @@ public class InternalHistogramTests extends InternalMultiBucketAggregationTestCa
|
|||
private boolean keyed;
|
||||
private DocValueFormat format;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
@Override
|
||||
public void setUp() throws Exception{
|
||||
super.setUp();
|
||||
keyed = randomBoolean();
|
||||
format = randomNumericDocValueFormat();
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public class InternalMaxTests extends InternalAggregationTestCase<InternalMax> {
|
|||
|
||||
@Override
|
||||
protected InternalMax createTestInstance(String name, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
|
||||
double value = frequently() ? randomDouble() : randomFrom(new Double[] { Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY });
|
||||
double value = frequently() ? randomDouble() : randomFrom(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
|
||||
DocValueFormat formatter = randomNumericDocValueFormat();
|
||||
return new InternalMax(name, value, formatter, pipelineAggregators, metaData);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.elasticsearch.search.aggregations.InternalAggregationTestCase;
|
|||
import org.elasticsearch.search.aggregations.ParsedAggregation;
|
||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -38,12 +37,22 @@ public class InternalCardinalityTests extends InternalAggregationTestCase<Intern
|
|||
private static List<HyperLogLogPlusPlus> algos;
|
||||
private static int p;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
algos = new ArrayList<>();
|
||||
p = randomIntBetween(HyperLogLogPlusPlus.MIN_PRECISION, HyperLogLogPlusPlus.MAX_PRECISION);
|
||||
}
|
||||
|
||||
@After //we force @After to have it run before ESTestCase#after otherwise it fails
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
Releasables.close(algos);
|
||||
algos.clear();
|
||||
algos = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InternalCardinality createTestInstance(String name,
|
||||
List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
|
||||
|
@ -82,11 +91,4 @@ public class InternalCardinalityTests extends InternalAggregationTestCase<Intern
|
|||
assertEquals(aggregation.getValue(), parsed.getValue(), Double.MIN_VALUE);
|
||||
assertEquals(aggregation.getValueAsString(), parsed.getValueAsString());
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() {
|
||||
Releasables.close(algos);
|
||||
algos.clear();
|
||||
algos = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public class InternalGeoCentroidTests extends InternalAggregationTestCase<Intern
|
|||
if (count == 0) {
|
||||
centroid = null;
|
||||
}
|
||||
return new InternalGeoCentroid("_name", centroid, count, Collections.emptyList(), Collections.emptyMap());
|
||||
return new InternalGeoCentroid(name, centroid, count, Collections.emptyList(), Collections.emptyMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,7 +23,6 @@ import org.elasticsearch.search.DocValueFormat;
|
|||
import org.elasticsearch.search.aggregations.InternalAggregation;
|
||||
import org.elasticsearch.search.aggregations.InternalAggregationTestCase;
|
||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
@ -38,8 +37,9 @@ public abstract class AbstractPercentilesTestCase<T extends InternalAggregation
|
|||
private boolean keyed;
|
||||
private DocValueFormat docValueFormat;
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
percents = randomPercents(false);
|
||||
keyed = randomBoolean();
|
||||
docValueFormat = randomNumericDocValueFormat();
|
||||
|
|
Loading…
Reference in New Issue