/*
* Copyright 2016-17, 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.stats;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;
import com.google.common.collect.ImmutableMap;
import com.google.common.testing.EqualsTester;
import io.opencensus.common.Duration;
import io.opencensus.common.Function;
import io.opencensus.common.Functions;
import io.opencensus.common.Timestamp;
import io.opencensus.stats.Aggregation.Count;
import io.opencensus.stats.Aggregation.Distribution;
import io.opencensus.stats.Aggregation.LastValue;
import io.opencensus.stats.Aggregation.Mean;
import io.opencensus.stats.Aggregation.Sum;
import io.opencensus.stats.AggregationData.CountData;
import io.opencensus.stats.AggregationData.DistributionData;
import io.opencensus.stats.AggregationData.LastValueDataDouble;
import io.opencensus.stats.AggregationData.LastValueDataLong;
import io.opencensus.stats.AggregationData.SumDataDouble;
import io.opencensus.stats.AggregationData.SumDataLong;
import io.opencensus.stats.View.AggregationWindow;
import io.opencensus.stats.View.AggregationWindow.Cumulative;
import io.opencensus.stats.View.AggregationWindow.Interval;
import io.opencensus.stats.ViewData.AggregationWindowData;
import io.opencensus.stats.ViewData.AggregationWindowData.CumulativeData;
import io.opencensus.stats.ViewData.AggregationWindowData.IntervalData;
import io.opencensus.tags.TagKey;
import io.opencensus.tags.TagValue;
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;
/** Tests for class {@link ViewData}. */
@RunWith(JUnit4.class)
public final class ViewDataTest {
@Rule public ExpectedException thrown = ExpectedException.none();
@Test
public void testCumulativeViewData() {
View view = View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, CUMULATIVE);
Timestamp start = Timestamp.fromMillis(1000);
Timestamp end = Timestamp.fromMillis(2000);
AggregationWindowData windowData = CumulativeData.create(start, end);
ViewData viewData = ViewData.create(view, ENTRIES, windowData);
assertThat(viewData.getView()).isEqualTo(view);
assertThat(viewData.getAggregationMap()).isEqualTo(ENTRIES);
assertThat(viewData.getWindowData()).isEqualTo(windowData);
}
@Test
public void testIntervalViewData() {
View view =
View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, INTERVAL_HOUR);
Timestamp end = Timestamp.fromMillis(2000);
AggregationWindowData windowData = IntervalData.create(end);
ViewData viewData = ViewData.create(view, ENTRIES, windowData);
assertThat(viewData.getView()).isEqualTo(view);
assertThat(viewData.getAggregationMap()).isEqualTo(ENTRIES);
assertThat(viewData.getWindowData()).isEqualTo(windowData);
}
@Test
public void testViewDataEquals() {
View cumulativeView =
View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, CUMULATIVE);
View intervalView =
View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, INTERVAL_HOUR);
new EqualsTester()
.addEqualityGroup(
ViewData.create(
cumulativeView,
ENTRIES,
CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000))),
ViewData.create(
cumulativeView,
ENTRIES,
CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000))))
.addEqualityGroup(
ViewData.create(
cumulativeView,
ENTRIES,
CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(3000))))
.addEqualityGroup(
ViewData.create(intervalView, ENTRIES, IntervalData.create(Timestamp.fromMillis(2000))),
ViewData.create(intervalView, ENTRIES, IntervalData.create(Timestamp.fromMillis(2000))))
.addEqualityGroup(
ViewData.create(
intervalView,
Collections.<List<TagValue>, AggregationData>emptyMap(),
IntervalData.create(Timestamp.fromMillis(2000))))
.testEquals();
}
@Test
public void testAggregationWindowDataMatch() {
final Timestamp start = Timestamp.fromMillis(1000);
final Timestamp end = Timestamp.fromMillis(2000);
final AggregationWindowData windowData1 = CumulativeData.create(start, end);
final AggregationWindowData windowData2 = IntervalData.create(end);
windowData1.match(
new Function<CumulativeData, Void>() {
@Override
public Void apply(CumulativeData windowData) {
assertThat(windowData.getStart()).isEqualTo(start);
assertThat(windowData.getEnd()).isEqualTo(end);
return null;
}
},
new Function<IntervalData, Void>() {
@Override
public Void apply(IntervalData windowData) {
fail("CumulativeData expected.");
return null;
}
},
Functions.<Void>throwIllegalArgumentException());
windowData2.match(
new Function<CumulativeData, Void>() {
@Override
public Void apply(CumulativeData windowData) {
fail("IntervalData expected.");
return null;
}
},
new Function<IntervalData, Void>() {
@Override
public Void apply(IntervalData windowData) {
assertThat(windowData.getEnd()).isEqualTo(end);
return null;
}
},
Functions.<Void>throwIllegalArgumentException());
}
@Test
public void preventWindowAndAggregationWindowDataMismatch() {
CumulativeData cumulativeData =
CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000));
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage(
"AggregationWindow and AggregationWindowData types mismatch. "
+ "AggregationWindow: "
+ INTERVAL_HOUR.getClass().getSimpleName()
+ " AggregationWindowData: "
+ cumulativeData.getClass().getSimpleName());
ViewData.create(
View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, INTERVAL_HOUR),
ENTRIES,
cumulativeData);
}
@Test
public void preventWindowAndAggregationWindowDataMismatch2() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("AggregationWindow and AggregationWindowData types mismatch. ");
ViewData.create(
View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, CUMULATIVE),
ENTRIES,
IntervalData.create(Timestamp.fromMillis(1000)));
}
@Test
public void preventStartTimeLaterThanEndTime() {
thrown.expect(IllegalArgumentException.class);
CumulativeData.create(Timestamp.fromMillis(3000), Timestamp.fromMillis(2000));
}
@Test
public void preventAggregationAndAggregationDataMismatch_SumDouble_SumLong() {
aggregationAndAggregationDataMismatch(
createView(Sum.create(), MEASURE_DOUBLE),
ImmutableMap.<List<TagValue>, AggregationData>of(
Arrays.asList(V1, V2), SumDataLong.create(100)));
}
@Test
public void preventAggregationAndAggregationDataMismatch_SumLong_SumDouble() {
aggregationAndAggregationDataMismatch(
createView(Sum.create(), MEASURE_LONG),
ImmutableMap.<List<TagValue>, AggregationData>of(
Arrays.asList(V1, V2), SumDataDouble.create(100)));
}
@Test
public void preventAggregationAndAggregationDataMismatch_Count_Distribution() {
aggregationAndAggregationDataMismatch(createView(Count.create()), ENTRIES);
}
@Test
public void preventAggregationAndAggregationDataMismatch_Mean_Distribution() {
aggregationAndAggregationDataMismatch(createView(Mean.create()), ENTRIES);
}
@Test
public void preventAggregationAndAggregationDataMismatch_Distribution_Count() {
aggregationAndAggregationDataMismatch(
createView(DISTRIBUTION), ImmutableMap.of(Arrays.asList(V10, V20), CountData.create(100)));
}
@Test
public void preventAggregationAndAggregationDataMismatch_LastValueDouble_LastValueLong() {
aggregationAndAggregationDataMismatch(
createView(LastValue.create(), MEASURE_DOUBLE),
ImmutableMap.<List<TagValue>, AggregationData>of(
Arrays.asList(V1, V2), LastValueDataLong.create(100)));
}
@Test
public void preventAggregationAndAggregationDataMismatch_LastValueLong_LastValueDouble() {
aggregationAndAggregationDataMismatch(
createView(LastValue.create(), MEASURE_LONG),
ImmutableMap.<List<TagValue>, AggregationData>of(
Arrays.asList(V1, V2), LastValueDataDouble.create(100)));
}
private static View createView(Aggregation aggregation) {
return createView(aggregation, MEASURE_DOUBLE);
}
private static View createView(Aggregation aggregation, Measure measure) {
return View.create(NAME, DESCRIPTION, measure, aggregation, TAG_KEYS, CUMULATIVE);
}
private void aggregationAndAggregationDataMismatch(
View view, Map<List<TagValue>, ? extends AggregationData> entries) {
CumulativeData cumulativeData =
CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000));
Aggregation aggregation = view.getAggregation();
AggregationData aggregationData = entries.values().iterator().next();
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage(
"Aggregation and AggregationData types mismatch. "
+ "Aggregation: "
+ aggregation.getClass().getSimpleName()
+ " AggregationData: "
+ aggregationData.getClass().getSimpleName());
ViewData.create(view, entries, cumulativeData);
}
// tag keys
private static final TagKey K1 = TagKey.create("k1");
private static final TagKey K2 = TagKey.create("k2");
private static final List<TagKey> TAG_KEYS = Arrays.asList(K1, K2);
// tag values
private static final TagValue V1 = TagValue.create("v1");
private static final TagValue V2 = TagValue.create("v2");
private static final TagValue V10 = TagValue.create("v10");
private static final TagValue V20 = TagValue.create("v20");
private static final AggregationWindow CUMULATIVE = Cumulative.create();
private static final AggregationWindow INTERVAL_HOUR = Interval.create(Duration.create(3600, 0));
private static final BucketBoundaries BUCKET_BOUNDARIES =
BucketBoundaries.create(Arrays.asList(10.0, 20.0, 30.0, 40.0));
private static final Aggregation DISTRIBUTION = Distribution.create(BUCKET_BOUNDARIES);
private static final ImmutableMap<List<TagValue>, DistributionData> ENTRIES =
ImmutableMap.of(
Arrays.asList(V1, V2),
DistributionData.create(1, 1, 1, 1, 0, Arrays.asList(0L, 1L, 0L)),
Arrays.asList(V10, V20),
DistributionData.create(-5, 6, -20, 5, 100.1, Arrays.asList(5L, 0L, 1L)));
// name
private static final View.Name NAME = View.Name.create("test-view");
// description
private static final String DESCRIPTION = "test-view-descriptor description";
// measure
private static final Measure MEASURE_DOUBLE =
Measure.MeasureDouble.create("measure1", "measure description", "1");
private static final Measure MEASURE_LONG =
Measure.MeasureLong.create("measure2", "measure description", "1");
}