Skip to content

Commit

Permalink
[Test] Add unit tests for Range aggregations
Browse files Browse the repository at this point in the history
Related to elastic#22278
  • Loading branch information
tlrx committed May 9, 2017
1 parent 4283908 commit 1492d6a
Show file tree
Hide file tree
Showing 5 changed files with 339 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class InternalRange<B extends InternalRange.Bucket, R extends InternalRange<B, R>> extends InternalMultiBucketAggregation<R, B>
implements Range {
Expand Down Expand Up @@ -172,6 +173,27 @@ protected String generateKey(double from, double to, DocValueFormat formatter) {
@Override
public void writeTo(StreamOutput out) throws IOException {
}

@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || getClass() != other.getClass()) {
return false;
}
Bucket that = (Bucket) other;
return Objects.equals(from, that.from)
&& Objects.equals(to, that.to)
&& Objects.equals(docCount, that.docCount)
&& Objects.equals(aggregations, that.aggregations)
&& Objects.equals(key, that.key);
}

@Override
public int hashCode() {
return Objects.hash(getClass(), from, to, docCount, aggregations, key);
}
}

public static class Factory<B extends Bucket, R extends InternalRange<B, R>> {
Expand Down Expand Up @@ -245,8 +267,8 @@ protected void doWriteTo(StreamOutput out) throws IOException {
out.writeVInt(ranges.size());
for (B bucket : ranges) {
out.writeOptionalString(((Bucket) bucket).key);
out.writeDouble(((Bucket) bucket).from);
out.writeDouble(((Bucket) bucket).to);
out.writeDouble(bucket.from);
out.writeDouble(bucket.to);
out.writeVLong(((Bucket) bucket).docCount);
bucket.aggregations.writeTo(out);
}
Expand Down Expand Up @@ -317,4 +339,16 @@ public XContentBuilder doXContentBody(XContentBuilder builder, Params params) th
return builder;
}

@Override
protected int doHashCode() {
return Objects.hash(ranges, format, keyed);
}

@Override
protected boolean doEquals(Object obj) {
InternalRange<?,?> that = (InternalRange<?,?>) obj;
return Objects.equals(ranges, that.ranges)
&& Objects.equals(format, that.format)
&& Objects.equals(keyed, that.keyed);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* 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.bucket.range;

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.util.List;
import java.util.Map;
import java.util.TreeMap;

public abstract class InternalRangeTestCase<T extends InternalAggregation & Range> extends InternalAggregationTestCase<T> {

private boolean keyed;

@Override
@Before
public void setUp() throws Exception {
super.setUp();
keyed = randomBoolean();
}

@Override
protected T createTestInstance(String name, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData) {
return createTestInstance(name, pipelineAggregators, metaData, keyed);
}

protected abstract T createTestInstance(String name,
List<PipelineAggregator> pipelineAggregators,
Map<String, Object> metaData,
boolean keyed);
@Override
protected void assertReduced(T reduced, List<T> inputs) {
final Map<String, Long> expectedCounts = new TreeMap<>();
for (T input : inputs) {
for (Range.Bucket bucket : input.getBuckets()) {
expectedCounts.compute(bucket.getKeyAsString(),
(key, oldValue) -> (oldValue == null ? 0 : oldValue) + bucket.getDocCount());

}
}
final Map<String, Long> actualCounts = new TreeMap<>();
for (Range.Bucket bucket : reduced.getBuckets()) {
actualCounts.compute(bucket.getKeyAsString(),
(key, oldValue) -> (oldValue == null ? 0 : oldValue) + bucket.getDocCount());
}
assertEquals(expectedCounts, actualCounts);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* 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.bucket.range;

import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.junit.Before;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class InternalRangeTests extends InternalRangeTestCase<InternalRange> {

private DocValueFormat format;
private List<Tuple<Double, Double>> ranges;

@Override
@Before
public void setUp() throws Exception {
super.setUp();
format = randomNumericDocValueFormat();

final int interval = randomFrom(1, 5, 10, 25, 50, 100);
final int numRanges = randomIntBetween(1, 10);

List<Tuple<Double, Double>> listOfRanges = new ArrayList<>(numRanges);
for (int i = 0; i < numRanges; i++) {
double from = i * interval;
double to = from + interval;
listOfRanges.add(Tuple.tuple(from, to));
}
ranges = Collections.unmodifiableList(listOfRanges);
}

@Override
protected InternalRange createTestInstance(String name, List<PipelineAggregator> pipelineAggregators, Map<String, Object> metaData,
boolean keyed) {
final List<InternalRange.Bucket> buckets = new ArrayList<>();
for (int i = 0; i < ranges.size(); ++i) {
Tuple<Double, Double> range = ranges.get(i);
int docCount = randomIntBetween(0, 1000);
double from = range.v1();
double to = range.v2();
buckets.add( new InternalRange.Bucket("range_" + i, from, to, docCount, InternalAggregations.EMPTY, keyed, format));
}
return new InternalRange<>(name, buckets, format, keyed, pipelineAggregators, Collections.emptyMap());
}

@Override
protected Writeable.Reader<InternalRange> instanceReader() {
return InternalRange::new;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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.bucket.range.date;

import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.search.DocValueFormat;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.bucket.range.InternalRangeTestCase;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Before;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

public class InternalDateRangeTests extends InternalRangeTestCase<InternalDateRange> {

private DocValueFormat format;
private List<Tuple<Double, Double>> dateRanges;

@Override
@Before
public void setUp() throws Exception {
super.setUp();
format = randomNumericDocValueFormat();

Function<DateTime, DateTime> interval = randomFrom(dateTime -> dateTime.plusSeconds(1), dateTime -> dateTime.plusMinutes(1),
dateTime -> dateTime.plusHours(1), dateTime -> dateTime.plusDays(1), dateTime -> dateTime.plusMonths(1), dateTime ->
dateTime.plusYears(1));

final int numRanges = randomIntBetween(1, 10);
final List<Tuple<Double, Double>> listOfRanges = new ArrayList<>(numRanges);

DateTime date = new DateTime(DateTimeZone.UTC);
for (int i = 0; i < numRanges; i++) {
double from = date.getMillis();
date = interval.apply(date);
double to = date.getMillis();
listOfRanges.add(Tuple.tuple(from, to));
}
dateRanges = Collections.unmodifiableList(listOfRanges);
}

@Override
protected InternalDateRange createTestInstance(String name,
List<PipelineAggregator> pipelineAggregators,
Map<String, Object> metaData,
boolean keyed) {
final List<InternalDateRange.Bucket> buckets = new ArrayList<>();
for (int i = 0; i < dateRanges.size(); ++i) {
Tuple<Double, Double> range = dateRanges.get(i);
int docCount = randomIntBetween(0, 1000);
double from = range.v1();
double to = range.v2();
buckets.add( new InternalDateRange.Bucket("range_" + i, from, to, docCount, InternalAggregations.EMPTY, keyed, format));
}
return new InternalDateRange(name, buckets, format, keyed, pipelineAggregators, metaData);
}

@Override
protected Writeable.Reader<InternalDateRange> instanceReader() {
return InternalDateRange::new;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* 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.bucket.range.geodistance;

import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.search.aggregations.InternalAggregations;
import org.elasticsearch.search.aggregations.bucket.range.InternalRangeTestCase;
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
import org.junit.Before;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class InternalGeoDistanceTests extends InternalRangeTestCase<InternalGeoDistance> {

private List<Tuple<Double, Double>> geoDistanceRanges;

@Override
@Before
public void setUp() throws Exception {
super.setUp();

final int interval = randomFrom(1, 5, 10, 25, 50, 100);
final int numRanges = randomIntBetween(1, 10);

List<Tuple<Double, Double>> listOfRanges = new ArrayList<>(numRanges);
for (int i = 0; i < numRanges; i++) {
double from = i * interval;
double to = from + interval;
listOfRanges.add(Tuple.tuple(from, to));
}
geoDistanceRanges = Collections.unmodifiableList(listOfRanges);
}
@Override
protected Writeable.Reader<InternalGeoDistance> instanceReader() {
return InternalGeoDistance::new;
}

@Override
protected InternalGeoDistance createTestInstance(String name,
List<PipelineAggregator> pipelineAggregators,
Map<String, Object> metaData,
boolean keyed) {
final List<InternalGeoDistance.Bucket> buckets = new ArrayList<>();
for (int i = 0; i < geoDistanceRanges.size(); ++i) {
Tuple<Double, Double> range = geoDistanceRanges.get(i);
int docCount = randomIntBetween(0, 1000);
double from = range.v1();
double to = range.v2();
buckets.add(new InternalGeoDistance.Bucket("range_" + i, from, to, docCount, InternalAggregations.EMPTY, keyed));
}
return new InternalGeoDistance(name, buckets, keyed, pipelineAggregators, metaData);
}
}

0 comments on commit 1492d6a

Please sign in to comment.