From 11da77388a3653896dffd9b3434d2a7f517ae7d3 Mon Sep 17 00:00:00 2001 From: Tanguy Leroux Date: Thu, 20 Apr 2017 10:16:51 +0200 Subject: Add parsing methods for Percentiles aggregations (#24183) --- .../percentiles/AbstractPercentilesTestCase.java | 84 ++++++++++++++++++++++ .../InternalPercentilesRanksTestCase.java | 82 ++------------------- .../percentiles/InternalPercentilesTestCase.java | 44 ++++-------- .../hdr/InternalHDRPercentilesRanksTests.java | 14 ++-- .../hdr/InternalHDRPercentilesTests.java | 6 ++ .../InternalTDigestPercentilesRanksTests.java | 18 ++--- .../tdigest/InternalTDigestPercentilesTests.java | 6 ++ 7 files changed, 133 insertions(+), 121 deletions(-) create mode 100644 core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/AbstractPercentilesTestCase.java (limited to 'core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles') diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/AbstractPercentilesTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/AbstractPercentilesTestCase.java new file mode 100644 index 0000000000..0859a51117 --- /dev/null +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/AbstractPercentilesTestCase.java @@ -0,0 +1,84 @@ +/* + * 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.metrics.percentiles; + +import com.carrotsearch.randomizedtesting.annotations.Repeat; +import org.elasticsearch.common.xcontent.XContentType; +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.Iterator; +import java.util.List; +import java.util.Map; + +public abstract class AbstractPercentilesTestCase> + extends InternalAggregationTestCase { + + private double[] percents; + private boolean keyed; + private DocValueFormat docValueFormat; + + @Before + public void init() { + percents = randomPercents(); + keyed = randomBoolean(); + docValueFormat = randomNumericDocValueFormat(); + } + + @Override + protected T createTestInstance(String name, List pipelineAggregators, Map metaData) { + int numValues = randomInt(100); + double[] values = new double[numValues]; + for (int i = 0; i < numValues; ++i) { + values[i] = randomDouble(); + } + return createTestInstance(name, pipelineAggregators, metaData, keyed, docValueFormat, percents, values); + } + + protected abstract T createTestInstance(String name, List pipelineAggregators, Map metaData, + boolean keyed, DocValueFormat format, double[] percents, double[] values); + + protected abstract Class implementationClass(); + + @Repeat(iterations = 1000) + public void testPercentilesIterators() throws IOException { + final T aggregation = createTestInstance(); + final Iterable parsedAggregation = parse(aggregation, randomFrom(XContentType.values()), randomBoolean(), false); + + Iterator it = aggregation.iterator(); + Iterator parsedIt = parsedAggregation.iterator(); + while (it.hasNext()) { + assertEquals(it.next(), parsedIt.next()); + } + } + + private static double[] randomPercents() { + List randomCdfValues = randomSubsetOf(randomIntBetween(1, 7), 0.01d, 0.05d, 0.25d, 0.50d, 0.75d, 0.95d, 0.99d); + double[] percents = new double[randomCdfValues.size()]; + for (int i = 0; i < randomCdfValues.size(); i++) { + percents[i] = randomCdfValues.get(i); + } + return percents; + } +} diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/InternalPercentilesRanksTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/InternalPercentilesRanksTestCase.java index be7d55e544..f45b7cce51 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/InternalPercentilesRanksTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/InternalPercentilesRanksTestCase.java @@ -19,92 +19,24 @@ package org.elasticsearch.search.aggregations.metrics.percentiles; -import org.elasticsearch.common.bytes.BytesReference; -import org.elasticsearch.common.xcontent.ToXContent; -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.rest.action.search.RestSearchAction; -import org.elasticsearch.search.DocValueFormat; -import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.InternalAggregation; -import org.elasticsearch.search.aggregations.InternalAggregationTestCase; import org.elasticsearch.search.aggregations.ParsedAggregation; -import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; -import java.io.IOException; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import static java.util.Collections.singletonMap; -import static org.elasticsearch.common.xcontent.XContentHelper.toXContent; - -public abstract class InternalPercentilesRanksTestCase extends InternalAggregationTestCase { - - @Override - protected final T createTestInstance(String name, List pipelineAggregators, Map metaData) { - final boolean keyed = randomBoolean(); - final DocValueFormat format = randomFrom(DocValueFormat.RAW, new DocValueFormat.Decimal("###.##")); - List randomCdfValues = randomSubsetOf(randomIntBetween(1, 5), 0.01d, 0.05d, 0.25d, 0.50d, 0.75d, 0.95d, 0.99d); - double[] cdfValues = new double[randomCdfValues.size()]; - for (int i = 0; i < randomCdfValues.size(); i++) { - cdfValues[i] = randomCdfValues.get(i); - } - return createTestInstance(name, pipelineAggregators, metaData, cdfValues, keyed, format); - } - - protected abstract T createTestInstance(String name, List aggregators, Map metadata, - double[] cdfValues, boolean keyed, DocValueFormat format); +public abstract class InternalPercentilesRanksTestCase + extends AbstractPercentilesTestCase { @Override protected final void assertFromXContent(T aggregation, ParsedAggregation parsedAggregation) { - assertTrue(aggregation instanceof PercentileRanks); - PercentileRanks percentileRanks = (PercentileRanks) aggregation; - assertTrue(parsedAggregation instanceof PercentileRanks); PercentileRanks parsedPercentileRanks = (PercentileRanks) parsedAggregation; - for (Percentile percentile : percentileRanks) { + for (Percentile percentile : aggregation) { Double value = percentile.getValue(); - assertEquals(percentileRanks.percent(value), parsedPercentileRanks.percent(value), 0); - assertEquals(percentileRanks.percentAsString(value), parsedPercentileRanks.percentAsString(value)); + assertEquals(aggregation.percent(value), parsedPercentileRanks.percent(value), 0); + assertEquals(aggregation.percentAsString(value), parsedPercentileRanks.percentAsString(value)); } - Class parsedClass = parsedParsedPercentileRanksClass(); - assertNotNull(parsedClass); - assertTrue(parsedClass.isInstance(parsedAggregation)); + Class parsedClass = implementationClass(); + assertTrue(parsedClass != null && parsedClass.isInstance(parsedAggregation)); } - - public void testPercentilesRanksIterators() throws IOException { - final T aggregation = createTestInstance(); - - final ToXContent.Params params = new ToXContent.MapParams(singletonMap(RestSearchAction.TYPED_KEYS_PARAM, "true")); - final XContentType xContentType = randomFrom(XContentType.values()); - final BytesReference originalBytes = toXContent(aggregation, xContentType, params, randomBoolean()); - - Aggregation parsedAggregation; - try (XContentParser parser = xContentType.xContent().createParser(xContentRegistry(), originalBytes)) { - assertEquals(XContentParser.Token.START_OBJECT, parser.nextToken()); - assertEquals(XContentParser.Token.FIELD_NAME, parser.nextToken()); - - String currentName = parser.currentName(); - int i = currentName.indexOf(InternalAggregation.TYPED_KEYS_DELIMITER); - String aggType = currentName.substring(0, i); - String aggName = currentName.substring(i + 1); - - parsedAggregation = parser.namedObject(Aggregation.class, aggType, aggName); - - assertEquals(XContentParser.Token.END_OBJECT, parser.currentToken()); - assertEquals(XContentParser.Token.END_OBJECT, parser.nextToken()); - assertNull(parser.nextToken()); - } - - final Iterator it = ((PercentileRanks) aggregation).iterator(); - final Iterator parsedIt = ((PercentileRanks) parsedAggregation).iterator(); - while (it.hasNext()) { - assertEquals(it.next(), parsedIt.next()); - } - } - - protected abstract Class parsedParsedPercentileRanksClass(); } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/InternalPercentilesTestCase.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/InternalPercentilesTestCase.java index 0cfa07538e..404c033f11 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/InternalPercentilesTestCase.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/InternalPercentilesTestCase.java @@ -19,43 +19,23 @@ package org.elasticsearch.search.aggregations.metrics.percentiles; -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 org.elasticsearch.search.aggregations.ParsedAggregation; -import java.util.List; -import java.util.Map; - -public abstract class InternalPercentilesTestCase extends InternalAggregationTestCase { - - private double[] percents; - - @Before - public void init() { - percents = randomPercents(); - } +public abstract class InternalPercentilesTestCase extends AbstractPercentilesTestCase { @Override - protected T createTestInstance(String name, List pipelineAggregators, Map metaData) { - int numValues = randomInt(100); - double[] values = new double[numValues]; - for (int i = 0; i < numValues; ++i) { - values[i] = randomDouble(); + protected final void assertFromXContent(T aggregation, ParsedAggregation parsedAggregation) { + assertTrue(parsedAggregation instanceof Percentiles); + Percentiles parsedPercentiles = (Percentiles) parsedAggregation; + + for (Percentile percentile : aggregation) { + Double percent = percentile.getPercent(); + assertEquals(aggregation.percentile(percent), parsedPercentiles.percentile(percent), 0); + assertEquals(aggregation.percentileAsString(percent), parsedPercentiles.percentileAsString(percent)); } - return createTestInstance(name, pipelineAggregators, metaData, randomBoolean(), DocValueFormat.RAW, percents, values); - } - - protected abstract T createTestInstance(String name, List pipelineAggregators, Map metaData, - boolean keyed, DocValueFormat format, double[] percents, double[] values); - private static double[] randomPercents() { - List randomCdfValues = randomSubsetOf(randomIntBetween(1, 7), 0.01d, 0.05d, 0.25d, 0.50d, 0.75d, 0.95d, 0.99d); - double[] percents = new double[randomCdfValues.size()]; - for (int i = 0; i < randomCdfValues.size(); i++) { - percents[i] = randomCdfValues.get(i); - } - return percents; + Class parsedClass = implementationClass(); + assertTrue(parsedClass != null && parsedClass.isInstance(parsedAggregation)); } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/InternalHDRPercentilesRanksTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/InternalHDRPercentilesRanksTests.java index a3fe4d62d1..d9379edefe 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/InternalHDRPercentilesRanksTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/InternalHDRPercentilesRanksTests.java @@ -23,9 +23,10 @@ import org.HdrHistogram.DoubleHistogram; import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.aggregations.metrics.percentiles.InternalPercentilesRanksTestCase; -import org.elasticsearch.search.aggregations.metrics.percentiles.ParsedPercentileRanks; +import org.elasticsearch.search.aggregations.metrics.percentiles.ParsedPercentiles; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -33,9 +34,12 @@ public class InternalHDRPercentilesRanksTests extends InternalPercentilesRanksTe @Override protected InternalHDRPercentileRanks createTestInstance(String name, List aggregators, Map metadata, - double[] cdfValues, boolean keyed, DocValueFormat format) { - DoubleHistogram state = new DoubleHistogram(3); - return new InternalHDRPercentileRanks(name, cdfValues, state, keyed, format, aggregators, metadata); + boolean keyed, DocValueFormat format, double[] percents, double[] values) { + + final DoubleHistogram state = new DoubleHistogram(3); + Arrays.stream(values).forEach(state::recordValue); + + return new InternalHDRPercentileRanks(name, percents, state, keyed, format, aggregators, metadata); } @Override @@ -54,7 +58,7 @@ public class InternalHDRPercentilesRanksTests extends InternalPercentilesRanksTe } @Override - protected Class parsedParsedPercentileRanksClass() { + protected Class implementationClass() { return ParsedHDRPercentileRanks.class; } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/InternalHDRPercentilesTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/InternalHDRPercentilesTests.java index bff026d5cf..5a24e0dfbf 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/InternalHDRPercentilesTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/hdr/InternalHDRPercentilesTests.java @@ -23,6 +23,7 @@ import org.HdrHistogram.DoubleHistogram; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.aggregations.metrics.percentiles.InternalPercentilesTestCase; +import org.elasticsearch.search.aggregations.metrics.percentiles.ParsedPercentiles; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import java.util.Arrays; @@ -57,4 +58,9 @@ public class InternalHDRPercentilesTests extends InternalPercentilesTestCase instanceReader() { return InternalHDRPercentiles::new; } + + @Override + protected Class implementationClass() { + return ParsedHDRPercentiles.class; + } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/tdigest/InternalTDigestPercentilesRanksTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/tdigest/InternalTDigestPercentilesRanksTests.java index 30d416763c..f8698fda2c 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/tdigest/InternalTDigestPercentilesRanksTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/tdigest/InternalTDigestPercentilesRanksTests.java @@ -22,9 +22,10 @@ package org.elasticsearch.search.aggregations.metrics.percentiles.tdigest; import org.elasticsearch.common.io.stream.Writeable.Reader; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.aggregations.metrics.percentiles.InternalPercentilesRanksTestCase; -import org.elasticsearch.search.aggregations.metrics.percentiles.ParsedPercentileRanks; +import org.elasticsearch.search.aggregations.metrics.percentiles.ParsedPercentiles; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -33,13 +34,12 @@ public class InternalTDigestPercentilesRanksTests extends InternalPercentilesRan @Override protected InternalTDigestPercentileRanks createTestInstance(String name, List aggregators, Map metadata, - double[] cdfValues, boolean keyed, DocValueFormat format) { - TDigestState state = new TDigestState(100); - int numValues = randomInt(100); - for (int i = 0; i < numValues; ++i) { - state.add(randomDouble()); - } - return new InternalTDigestPercentileRanks(name, cdfValues, state, keyed, format, aggregators, metadata); + boolean keyed, DocValueFormat format, double[] percents, double[] values) { + final TDigestState state = new TDigestState(100); + Arrays.stream(values).forEach(state::add); + + assertEquals(state.centroidCount(), values.length); + return new InternalTDigestPercentileRanks(name, percents, state, keyed, format, aggregators, metadata); } @Override @@ -71,7 +71,7 @@ public class InternalTDigestPercentilesRanksTests extends InternalPercentilesRan } @Override - protected Class parsedParsedPercentileRanksClass() { + protected Class implementationClass() { return ParsedTDigestPercentileRanks.class; } } diff --git a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/tdigest/InternalTDigestPercentilesTests.java b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/tdigest/InternalTDigestPercentilesTests.java index f2db4a4853..867469592e 100644 --- a/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/tdigest/InternalTDigestPercentilesTests.java +++ b/core/src/test/java/org/elasticsearch/search/aggregations/metrics/percentiles/tdigest/InternalTDigestPercentilesTests.java @@ -22,6 +22,7 @@ package org.elasticsearch.search.aggregations.metrics.percentiles.tdigest; import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.search.DocValueFormat; import org.elasticsearch.search.aggregations.metrics.percentiles.InternalPercentilesTestCase; +import org.elasticsearch.search.aggregations.metrics.percentiles.ParsedPercentiles; import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator; import java.util.Arrays; @@ -64,4 +65,9 @@ public class InternalTDigestPercentilesTests extends InternalPercentilesTestCase protected Writeable.Reader instanceReader() { return InternalTDigestPercentiles::new; } + + @Override + protected Class implementationClass() { + return ParsedTDigestPercentiles.class; + } } -- cgit v1.2.3