aboutsummaryrefslogtreecommitdiff
path: root/impl_core/src/test/java/io/opencensus/implcore/stats/MutableAggregationTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'impl_core/src/test/java/io/opencensus/implcore/stats/MutableAggregationTest.java')
-rw-r--r--impl_core/src/test/java/io/opencensus/implcore/stats/MutableAggregationTest.java339
1 files changed, 339 insertions, 0 deletions
diff --git a/impl_core/src/test/java/io/opencensus/implcore/stats/MutableAggregationTest.java b/impl_core/src/test/java/io/opencensus/implcore/stats/MutableAggregationTest.java
new file mode 100644
index 00000000..a6139e53
--- /dev/null
+++ b/impl_core/src/test/java/io/opencensus/implcore/stats/MutableAggregationTest.java
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2017, OpenCensus Authors
+ *
+ * Licensed 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 io.opencensus.implcore.stats;
+
+import static com.google.common.truth.Truth.assertThat;
+import static io.opencensus.implcore.stats.StatsTestUtil.assertAggregationDataEquals;
+
+import com.google.common.collect.ImmutableList;
+import io.opencensus.common.Timestamp;
+import io.opencensus.implcore.stats.MutableAggregation.MutableCount;
+import io.opencensus.implcore.stats.MutableAggregation.MutableDistribution;
+import io.opencensus.implcore.stats.MutableAggregation.MutableLastValueDouble;
+import io.opencensus.implcore.stats.MutableAggregation.MutableLastValueLong;
+import io.opencensus.implcore.stats.MutableAggregation.MutableMean;
+import io.opencensus.implcore.stats.MutableAggregation.MutableSumDouble;
+import io.opencensus.implcore.stats.MutableAggregation.MutableSumLong;
+import io.opencensus.metrics.export.Distribution;
+import io.opencensus.metrics.export.Distribution.Bucket;
+import io.opencensus.metrics.export.Distribution.BucketOptions;
+import io.opencensus.metrics.export.Point;
+import io.opencensus.metrics.export.Value;
+import io.opencensus.stats.AggregationData;
+import io.opencensus.stats.AggregationData.CountData;
+import io.opencensus.stats.AggregationData.DistributionData;
+import io.opencensus.stats.AggregationData.DistributionData.Exemplar;
+import io.opencensus.stats.AggregationData.LastValueDataDouble;
+import io.opencensus.stats.AggregationData.LastValueDataLong;
+import io.opencensus.stats.AggregationData.MeanData;
+import io.opencensus.stats.AggregationData.SumDataDouble;
+import io.opencensus.stats.AggregationData.SumDataLong;
+import io.opencensus.stats.BucketBoundaries;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Unit tests for {@link io.opencensus.implcore.stats.MutableAggregation}. */
+@RunWith(JUnit4.class)
+public class MutableAggregationTest {
+
+ @Rule public ExpectedException thrown = ExpectedException.none();
+
+ private static final double TOLERANCE = 1e-6;
+ private static final BucketBoundaries BUCKET_BOUNDARIES =
+ BucketBoundaries.create(Arrays.asList(-10.0, 0.0, 10.0));
+ private static final BucketBoundaries BUCKET_BOUNDARIES_EMPTY =
+ BucketBoundaries.create(Collections.<Double>emptyList());
+ private static final Timestamp TIMESTAMP = Timestamp.create(60, 0);
+
+ @Test
+ public void testCreateEmpty() {
+ assertThat(MutableSumDouble.create().getSum()).isWithin(TOLERANCE).of(0);
+ assertThat(MutableSumLong.create().getSum()).isWithin(TOLERANCE).of(0);
+ assertThat(MutableCount.create().getCount()).isEqualTo(0);
+ assertThat(MutableMean.create().getMean()).isWithin(TOLERANCE).of(0);
+ assertThat(MutableLastValueDouble.create().getLastValue()).isNaN();
+ assertThat(MutableLastValueLong.create().getLastValue()).isNaN();
+
+ BucketBoundaries bucketBoundaries = BucketBoundaries.create(Arrays.asList(0.1, 2.2, 33.3));
+ MutableDistribution mutableDistribution = MutableDistribution.create(bucketBoundaries);
+ assertThat(mutableDistribution.getMean()).isWithin(TOLERANCE).of(0);
+ assertThat(mutableDistribution.getCount()).isEqualTo(0);
+ assertThat(mutableDistribution.getMin()).isPositiveInfinity();
+ assertThat(mutableDistribution.getMax()).isNegativeInfinity();
+ assertThat(mutableDistribution.getSumOfSquaredDeviations()).isWithin(TOLERANCE).of(0);
+ assertThat(mutableDistribution.getBucketCounts()).isEqualTo(new long[4]);
+ assertThat(mutableDistribution.getExemplars()).isEqualTo(new Exemplar[4]);
+
+ MutableDistribution mutableDistributionNoHistogram =
+ MutableDistribution.create(BUCKET_BOUNDARIES_EMPTY);
+ assertThat(mutableDistributionNoHistogram.getExemplars()).isNull();
+ }
+
+ @Test
+ public void testNullBucketBoundaries() {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("bucketBoundaries should not be null.");
+ MutableDistribution.create(null);
+ }
+
+ @Test
+ public void testNoBoundaries() {
+ List<Double> buckets = Arrays.asList();
+ MutableDistribution noBoundaries = MutableDistribution.create(BucketBoundaries.create(buckets));
+ assertThat(noBoundaries.getBucketCounts().length).isEqualTo(1);
+ assertThat(noBoundaries.getBucketCounts()[0]).isEqualTo(0);
+ }
+
+ @Test
+ public void testAdd() {
+ List<MutableAggregation> aggregations =
+ Arrays.asList(
+ MutableSumDouble.create(),
+ MutableSumLong.create(),
+ MutableCount.create(),
+ MutableMean.create(),
+ MutableDistribution.create(BUCKET_BOUNDARIES),
+ MutableLastValueDouble.create(),
+ MutableLastValueLong.create());
+
+ List<Double> values = Arrays.asList(-1.0, 1.0, -5.0, 20.0, 5.0);
+
+ for (double value : values) {
+ for (MutableAggregation aggregation : aggregations) {
+ aggregation.add(value, Collections.<String, String>emptyMap(), TIMESTAMP);
+ }
+ }
+
+ assertAggregationDataEquals(
+ aggregations.get(0).toAggregationData(),
+ AggregationData.SumDataDouble.create(20.0),
+ TOLERANCE);
+ assertAggregationDataEquals(
+ aggregations.get(1).toAggregationData(), AggregationData.SumDataLong.create(20), TOLERANCE);
+ assertAggregationDataEquals(
+ aggregations.get(2).toAggregationData(), AggregationData.CountData.create(5), TOLERANCE);
+ assertAggregationDataEquals(
+ aggregations.get(3).toAggregationData(),
+ AggregationData.MeanData.create(4.0, 5),
+ TOLERANCE);
+ assertAggregationDataEquals(
+ aggregations.get(4).toAggregationData(),
+ AggregationData.DistributionData.create(
+ 4.0, 5, -5.0, 20.0, 372, Arrays.asList(0L, 2L, 2L, 1L)),
+ TOLERANCE);
+ assertAggregationDataEquals(
+ aggregations.get(5).toAggregationData(),
+ AggregationData.LastValueDataDouble.create(5.0),
+ TOLERANCE);
+ assertAggregationDataEquals(
+ aggregations.get(6).toAggregationData(),
+ AggregationData.LastValueDataLong.create(5),
+ TOLERANCE);
+ }
+
+ @Test
+ public void testAdd_DistributionWithExemplarAttachments() {
+ MutableDistribution mutableDistribution = MutableDistribution.create(BUCKET_BOUNDARIES);
+ MutableDistribution mutableDistributionNoHistogram =
+ MutableDistribution.create(BUCKET_BOUNDARIES_EMPTY);
+ List<Double> values = Arrays.asList(-1.0, 1.0, -5.0, 20.0, 5.0);
+ List<Map<String, String>> attachmentsList =
+ ImmutableList.<Map<String, String>>of(
+ Collections.<String, String>singletonMap("k1", "v1"),
+ Collections.<String, String>singletonMap("k2", "v2"),
+ Collections.<String, String>singletonMap("k3", "v3"),
+ Collections.<String, String>singletonMap("k4", "v4"),
+ Collections.<String, String>singletonMap("k5", "v5"));
+ List<Timestamp> timestamps =
+ Arrays.asList(
+ Timestamp.fromMillis(500),
+ Timestamp.fromMillis(1000),
+ Timestamp.fromMillis(2000),
+ Timestamp.fromMillis(3000),
+ Timestamp.fromMillis(4000));
+ for (int i = 0; i < values.size(); i++) {
+ mutableDistribution.add(values.get(i), attachmentsList.get(i), timestamps.get(i));
+ mutableDistributionNoHistogram.add(values.get(i), attachmentsList.get(i), timestamps.get(i));
+ }
+
+ // Each bucket can only have up to one exemplar. If there are more than one exemplars in a
+ // bucket, only the last one will be kept.
+ List<Exemplar> expected =
+ Arrays.<Exemplar>asList(
+ null,
+ Exemplar.create(values.get(2), timestamps.get(2), attachmentsList.get(2)),
+ Exemplar.create(values.get(4), timestamps.get(4), attachmentsList.get(4)),
+ Exemplar.create(values.get(3), timestamps.get(3), attachmentsList.get(3)));
+ assertThat(mutableDistribution.getExemplars())
+ .asList()
+ .containsExactlyElementsIn(expected)
+ .inOrder();
+ assertThat(mutableDistributionNoHistogram.getExemplars()).isNull();
+ }
+
+ @Test
+ public void testCombine_SumCountMean() {
+ // combine() for Mutable Sum, Count and Mean will pick up fractional stats
+ List<MutableAggregation> aggregations1 =
+ Arrays.asList(
+ MutableSumDouble.create(),
+ MutableSumLong.create(),
+ MutableCount.create(),
+ MutableMean.create());
+ List<MutableAggregation> aggregations2 =
+ Arrays.asList(
+ MutableSumDouble.create(),
+ MutableSumLong.create(),
+ MutableCount.create(),
+ MutableMean.create());
+
+ for (double val : Arrays.asList(-1.0, -5.0)) {
+ for (MutableAggregation aggregation : aggregations1) {
+ aggregation.add(val, Collections.<String, String>emptyMap(), TIMESTAMP);
+ }
+ }
+ for (double val : Arrays.asList(10.0, 50.0)) {
+ for (MutableAggregation aggregation : aggregations2) {
+ aggregation.add(val, Collections.<String, String>emptyMap(), TIMESTAMP);
+ }
+ }
+
+ List<MutableAggregation> combined =
+ Arrays.asList(
+ MutableSumDouble.create(),
+ MutableSumLong.create(),
+ MutableCount.create(),
+ MutableMean.create());
+ double fraction1 = 1.0;
+ double fraction2 = 0.6;
+ for (int i = 0; i < combined.size(); i++) {
+ combined.get(i).combine(aggregations1.get(i), fraction1);
+ combined.get(i).combine(aggregations2.get(i), fraction2);
+ }
+
+ assertThat(((MutableSumDouble) combined.get(0)).getSum()).isWithin(TOLERANCE).of(30);
+ assertThat(((MutableSumLong) combined.get(1)).getSum()).isWithin(TOLERANCE).of(30);
+ assertThat(((MutableCount) combined.get(2)).getCount()).isEqualTo(3);
+ assertThat(((MutableMean) combined.get(3)).getMean()).isWithin(TOLERANCE).of(10);
+ }
+
+ @Test
+ public void testCombine_Distribution() {
+ // combine() for Mutable Distribution will ignore fractional stats
+ MutableDistribution distribution1 = MutableDistribution.create(BUCKET_BOUNDARIES);
+ MutableDistribution distribution2 = MutableDistribution.create(BUCKET_BOUNDARIES);
+ MutableDistribution distribution3 = MutableDistribution.create(BUCKET_BOUNDARIES);
+
+ for (double val : Arrays.asList(5.0, -5.0)) {
+ distribution1.add(val, Collections.<String, String>emptyMap(), TIMESTAMP);
+ }
+ for (double val : Arrays.asList(10.0, 20.0)) {
+ distribution2.add(val, Collections.<String, String>emptyMap(), TIMESTAMP);
+ }
+ for (double val : Arrays.asList(-10.0, 15.0, -15.0, -20.0)) {
+ distribution3.add(val, Collections.<String, String>emptyMap(), TIMESTAMP);
+ }
+
+ MutableDistribution combined = MutableDistribution.create(BUCKET_BOUNDARIES);
+ combined.combine(distribution1, 1.0); // distribution1 will be combined
+ combined.combine(distribution2, 0.6); // distribution2 will be ignored
+ verifyMutableDistribution(combined, 0, 2, -5, 5, 50.0, new long[] {0, 1, 1, 0}, TOLERANCE);
+
+ combined.combine(distribution2, 1.0); // distribution2 will be combined
+ verifyMutableDistribution(combined, 7.5, 4, -5, 20, 325.0, new long[] {0, 1, 1, 2}, TOLERANCE);
+
+ combined.combine(distribution3, 1.0); // distribution3 will be combined
+ verifyMutableDistribution(combined, 0, 8, -20, 20, 1500.0, new long[] {2, 2, 1, 3}, TOLERANCE);
+ }
+
+ @Test
+ public void mutableAggregation_ToAggregationData() {
+ assertThat(MutableSumDouble.create().toAggregationData()).isEqualTo(SumDataDouble.create(0));
+ assertThat(MutableSumLong.create().toAggregationData()).isEqualTo(SumDataLong.create(0));
+ assertThat(MutableCount.create().toAggregationData()).isEqualTo(CountData.create(0));
+ assertThat(MutableMean.create().toAggregationData()).isEqualTo(MeanData.create(0, 0));
+ assertThat(MutableDistribution.create(BUCKET_BOUNDARIES).toAggregationData())
+ .isEqualTo(
+ DistributionData.create(
+ 0,
+ 0,
+ Double.POSITIVE_INFINITY,
+ Double.NEGATIVE_INFINITY,
+ 0,
+ Arrays.asList(0L, 0L, 0L, 0L)));
+ assertThat(MutableLastValueDouble.create().toAggregationData())
+ .isEqualTo(LastValueDataDouble.create(Double.NaN));
+ assertThat(MutableLastValueLong.create().toAggregationData())
+ .isEqualTo(LastValueDataLong.create(0));
+ }
+
+ @Test
+ public void mutableAggregation_ToPoint() {
+ assertThat(MutableSumDouble.create().toPoint(TIMESTAMP))
+ .isEqualTo(Point.create(Value.doubleValue(0), TIMESTAMP));
+ assertThat(MutableSumLong.create().toPoint(TIMESTAMP))
+ .isEqualTo(Point.create(Value.longValue(0), TIMESTAMP));
+ assertThat(MutableCount.create().toPoint(TIMESTAMP))
+ .isEqualTo(Point.create(Value.longValue(0), TIMESTAMP));
+ assertThat(MutableMean.create().toPoint(TIMESTAMP))
+ .isEqualTo(Point.create(Value.doubleValue(0), TIMESTAMP));
+
+ thrown.expect(IllegalArgumentException.class);
+ thrown.expectMessage("bucket boundary should be > 0");
+ assertThat(MutableDistribution.create(BUCKET_BOUNDARIES).toPoint(TIMESTAMP))
+ .isEqualTo(
+ Point.create(
+ Value.distributionValue(
+ Distribution.create(
+ 0,
+ 0,
+ 0,
+ BucketOptions.explicitOptions(BUCKET_BOUNDARIES.getBoundaries()),
+ Arrays.asList(
+ Bucket.create(0),
+ Bucket.create(0),
+ Bucket.create(0),
+ Bucket.create(0)))),
+ TIMESTAMP));
+ }
+
+ private static void verifyMutableDistribution(
+ MutableDistribution mutableDistribution,
+ double mean,
+ long count,
+ double min,
+ double max,
+ double sumOfSquaredDeviations,
+ long[] bucketCounts,
+ double tolerance) {
+ assertThat(mutableDistribution.getMean()).isWithin(tolerance).of(mean);
+ assertThat(mutableDistribution.getCount()).isEqualTo(count);
+ assertThat(mutableDistribution.getMin()).isWithin(tolerance).of(min);
+ assertThat(mutableDistribution.getMax()).isWithin(tolerance).of(max);
+ assertThat(mutableDistribution.getSumOfSquaredDeviations())
+ .isWithin(tolerance)
+ .of(sumOfSquaredDeviations);
+ assertThat(mutableDistribution.getBucketCounts()).isEqualTo(bucketCounts);
+ }
+}