Home | History | Annotate | Download | only in stats
      1 /*
      2  * Copyright 2016-17, OpenCensus Authors
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package io.opencensus.stats;
     18 
     19 import static com.google.common.truth.Truth.assertThat;
     20 import static org.junit.Assert.fail;
     21 
     22 import com.google.common.collect.ImmutableMap;
     23 import com.google.common.testing.EqualsTester;
     24 import io.opencensus.common.Duration;
     25 import io.opencensus.common.Function;
     26 import io.opencensus.common.Functions;
     27 import io.opencensus.common.Timestamp;
     28 import io.opencensus.stats.Aggregation.Count;
     29 import io.opencensus.stats.Aggregation.Distribution;
     30 import io.opencensus.stats.Aggregation.LastValue;
     31 import io.opencensus.stats.Aggregation.Mean;
     32 import io.opencensus.stats.Aggregation.Sum;
     33 import io.opencensus.stats.AggregationData.CountData;
     34 import io.opencensus.stats.AggregationData.DistributionData;
     35 import io.opencensus.stats.AggregationData.LastValueDataDouble;
     36 import io.opencensus.stats.AggregationData.LastValueDataLong;
     37 import io.opencensus.stats.AggregationData.SumDataDouble;
     38 import io.opencensus.stats.AggregationData.SumDataLong;
     39 import io.opencensus.stats.View.AggregationWindow;
     40 import io.opencensus.stats.View.AggregationWindow.Cumulative;
     41 import io.opencensus.stats.View.AggregationWindow.Interval;
     42 import io.opencensus.stats.ViewData.AggregationWindowData;
     43 import io.opencensus.stats.ViewData.AggregationWindowData.CumulativeData;
     44 import io.opencensus.stats.ViewData.AggregationWindowData.IntervalData;
     45 import io.opencensus.tags.TagKey;
     46 import io.opencensus.tags.TagValue;
     47 import java.util.Arrays;
     48 import java.util.Collections;
     49 import java.util.List;
     50 import java.util.Map;
     51 import org.junit.Rule;
     52 import org.junit.Test;
     53 import org.junit.rules.ExpectedException;
     54 import org.junit.runner.RunWith;
     55 import org.junit.runners.JUnit4;
     56 
     57 /** Tests for class {@link ViewData}. */
     58 @RunWith(JUnit4.class)
     59 public final class ViewDataTest {
     60 
     61   @Rule public ExpectedException thrown = ExpectedException.none();
     62 
     63   @Test
     64   public void testCumulativeViewData() {
     65     View view = View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, CUMULATIVE);
     66     Timestamp start = Timestamp.fromMillis(1000);
     67     Timestamp end = Timestamp.fromMillis(2000);
     68     AggregationWindowData windowData = CumulativeData.create(start, end);
     69     ViewData viewData = ViewData.create(view, ENTRIES, windowData);
     70     assertThat(viewData.getView()).isEqualTo(view);
     71     assertThat(viewData.getAggregationMap()).isEqualTo(ENTRIES);
     72     assertThat(viewData.getWindowData()).isEqualTo(windowData);
     73   }
     74 
     75   @Test
     76   public void testIntervalViewData() {
     77     View view =
     78         View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, INTERVAL_HOUR);
     79     Timestamp end = Timestamp.fromMillis(2000);
     80     AggregationWindowData windowData = IntervalData.create(end);
     81     ViewData viewData = ViewData.create(view, ENTRIES, windowData);
     82     assertThat(viewData.getView()).isEqualTo(view);
     83     assertThat(viewData.getAggregationMap()).isEqualTo(ENTRIES);
     84     assertThat(viewData.getWindowData()).isEqualTo(windowData);
     85   }
     86 
     87   @Test
     88   public void testViewDataEquals() {
     89     View cumulativeView =
     90         View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, CUMULATIVE);
     91     View intervalView =
     92         View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, INTERVAL_HOUR);
     93 
     94     new EqualsTester()
     95         .addEqualityGroup(
     96             ViewData.create(
     97                 cumulativeView,
     98                 ENTRIES,
     99                 CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000))),
    100             ViewData.create(
    101                 cumulativeView,
    102                 ENTRIES,
    103                 CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000))))
    104         .addEqualityGroup(
    105             ViewData.create(
    106                 cumulativeView,
    107                 ENTRIES,
    108                 CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(3000))))
    109         .addEqualityGroup(
    110             ViewData.create(intervalView, ENTRIES, IntervalData.create(Timestamp.fromMillis(2000))),
    111             ViewData.create(intervalView, ENTRIES, IntervalData.create(Timestamp.fromMillis(2000))))
    112         .addEqualityGroup(
    113             ViewData.create(
    114                 intervalView,
    115                 Collections.<List<TagValue>, AggregationData>emptyMap(),
    116                 IntervalData.create(Timestamp.fromMillis(2000))))
    117         .testEquals();
    118   }
    119 
    120   @Test
    121   public void testAggregationWindowDataMatch() {
    122     final Timestamp start = Timestamp.fromMillis(1000);
    123     final Timestamp end = Timestamp.fromMillis(2000);
    124     final AggregationWindowData windowData1 = CumulativeData.create(start, end);
    125     final AggregationWindowData windowData2 = IntervalData.create(end);
    126     windowData1.match(
    127         new Function<CumulativeData, Void>() {
    128           @Override
    129           public Void apply(CumulativeData windowData) {
    130             assertThat(windowData.getStart()).isEqualTo(start);
    131             assertThat(windowData.getEnd()).isEqualTo(end);
    132             return null;
    133           }
    134         },
    135         new Function<IntervalData, Void>() {
    136           @Override
    137           public Void apply(IntervalData windowData) {
    138             fail("CumulativeData expected.");
    139             return null;
    140           }
    141         },
    142         Functions.<Void>throwIllegalArgumentException());
    143     windowData2.match(
    144         new Function<CumulativeData, Void>() {
    145           @Override
    146           public Void apply(CumulativeData windowData) {
    147             fail("IntervalData expected.");
    148             return null;
    149           }
    150         },
    151         new Function<IntervalData, Void>() {
    152           @Override
    153           public Void apply(IntervalData windowData) {
    154             assertThat(windowData.getEnd()).isEqualTo(end);
    155             return null;
    156           }
    157         },
    158         Functions.<Void>throwIllegalArgumentException());
    159   }
    160 
    161   @Test
    162   public void preventWindowAndAggregationWindowDataMismatch() {
    163     CumulativeData cumulativeData =
    164         CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000));
    165     thrown.expect(IllegalArgumentException.class);
    166     thrown.expectMessage(
    167         "AggregationWindow and AggregationWindowData types mismatch. "
    168             + "AggregationWindow: "
    169             + INTERVAL_HOUR.getClass().getSimpleName()
    170             + " AggregationWindowData: "
    171             + cumulativeData.getClass().getSimpleName());
    172     ViewData.create(
    173         View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, INTERVAL_HOUR),
    174         ENTRIES,
    175         cumulativeData);
    176   }
    177 
    178   @Test
    179   public void preventWindowAndAggregationWindowDataMismatch2() {
    180     thrown.expect(IllegalArgumentException.class);
    181     thrown.expectMessage("AggregationWindow and AggregationWindowData types mismatch. ");
    182     ViewData.create(
    183         View.create(NAME, DESCRIPTION, MEASURE_DOUBLE, DISTRIBUTION, TAG_KEYS, CUMULATIVE),
    184         ENTRIES,
    185         IntervalData.create(Timestamp.fromMillis(1000)));
    186   }
    187 
    188   @Test
    189   public void preventStartTimeLaterThanEndTime() {
    190     thrown.expect(IllegalArgumentException.class);
    191     CumulativeData.create(Timestamp.fromMillis(3000), Timestamp.fromMillis(2000));
    192   }
    193 
    194   @Test
    195   public void preventAggregationAndAggregationDataMismatch_SumDouble_SumLong() {
    196     aggregationAndAggregationDataMismatch(
    197         createView(Sum.create(), MEASURE_DOUBLE),
    198         ImmutableMap.<List<TagValue>, AggregationData>of(
    199             Arrays.asList(V1, V2), SumDataLong.create(100)));
    200   }
    201 
    202   @Test
    203   public void preventAggregationAndAggregationDataMismatch_SumLong_SumDouble() {
    204     aggregationAndAggregationDataMismatch(
    205         createView(Sum.create(), MEASURE_LONG),
    206         ImmutableMap.<List<TagValue>, AggregationData>of(
    207             Arrays.asList(V1, V2), SumDataDouble.create(100)));
    208   }
    209 
    210   @Test
    211   public void preventAggregationAndAggregationDataMismatch_Count_Distribution() {
    212     aggregationAndAggregationDataMismatch(createView(Count.create()), ENTRIES);
    213   }
    214 
    215   @Test
    216   public void preventAggregationAndAggregationDataMismatch_Mean_Distribution() {
    217     aggregationAndAggregationDataMismatch(createView(Mean.create()), ENTRIES);
    218   }
    219 
    220   @Test
    221   public void preventAggregationAndAggregationDataMismatch_Distribution_Count() {
    222     aggregationAndAggregationDataMismatch(
    223         createView(DISTRIBUTION), ImmutableMap.of(Arrays.asList(V10, V20), CountData.create(100)));
    224   }
    225 
    226   @Test
    227   public void preventAggregationAndAggregationDataMismatch_LastValueDouble_LastValueLong() {
    228     aggregationAndAggregationDataMismatch(
    229         createView(LastValue.create(), MEASURE_DOUBLE),
    230         ImmutableMap.<List<TagValue>, AggregationData>of(
    231             Arrays.asList(V1, V2), LastValueDataLong.create(100)));
    232   }
    233 
    234   @Test
    235   public void preventAggregationAndAggregationDataMismatch_LastValueLong_LastValueDouble() {
    236     aggregationAndAggregationDataMismatch(
    237         createView(LastValue.create(), MEASURE_LONG),
    238         ImmutableMap.<List<TagValue>, AggregationData>of(
    239             Arrays.asList(V1, V2), LastValueDataDouble.create(100)));
    240   }
    241 
    242   private static View createView(Aggregation aggregation) {
    243     return createView(aggregation, MEASURE_DOUBLE);
    244   }
    245 
    246   private static View createView(Aggregation aggregation, Measure measure) {
    247     return View.create(NAME, DESCRIPTION, measure, aggregation, TAG_KEYS, CUMULATIVE);
    248   }
    249 
    250   private void aggregationAndAggregationDataMismatch(
    251       View view, Map<List<TagValue>, ? extends AggregationData> entries) {
    252     CumulativeData cumulativeData =
    253         CumulativeData.create(Timestamp.fromMillis(1000), Timestamp.fromMillis(2000));
    254     Aggregation aggregation = view.getAggregation();
    255     AggregationData aggregationData = entries.values().iterator().next();
    256     thrown.expect(IllegalArgumentException.class);
    257     thrown.expectMessage(
    258         "Aggregation and AggregationData types mismatch. "
    259             + "Aggregation: "
    260             + aggregation.getClass().getSimpleName()
    261             + " AggregationData: "
    262             + aggregationData.getClass().getSimpleName());
    263     ViewData.create(view, entries, cumulativeData);
    264   }
    265 
    266   // tag keys
    267   private static final TagKey K1 = TagKey.create("k1");
    268   private static final TagKey K2 = TagKey.create("k2");
    269   private static final List<TagKey> TAG_KEYS = Arrays.asList(K1, K2);
    270 
    271   // tag values
    272   private static final TagValue V1 = TagValue.create("v1");
    273   private static final TagValue V2 = TagValue.create("v2");
    274   private static final TagValue V10 = TagValue.create("v10");
    275   private static final TagValue V20 = TagValue.create("v20");
    276 
    277   private static final AggregationWindow CUMULATIVE = Cumulative.create();
    278   private static final AggregationWindow INTERVAL_HOUR = Interval.create(Duration.create(3600, 0));
    279 
    280   private static final BucketBoundaries BUCKET_BOUNDARIES =
    281       BucketBoundaries.create(Arrays.asList(10.0, 20.0, 30.0, 40.0));
    282 
    283   private static final Aggregation DISTRIBUTION = Distribution.create(BUCKET_BOUNDARIES);
    284 
    285   private static final ImmutableMap<List<TagValue>, DistributionData> ENTRIES =
    286       ImmutableMap.of(
    287           Arrays.asList(V1, V2),
    288           DistributionData.create(1, 1, 1, 1, 0, Arrays.asList(0L, 1L, 0L)),
    289           Arrays.asList(V10, V20),
    290           DistributionData.create(-5, 6, -20, 5, 100.1, Arrays.asList(5L, 0L, 1L)));
    291 
    292   // name
    293   private static final View.Name NAME = View.Name.create("test-view");
    294   // description
    295   private static final String DESCRIPTION = "test-view-descriptor description";
    296   // measure
    297   private static final Measure MEASURE_DOUBLE =
    298       Measure.MeasureDouble.create("measure1", "measure description", "1");
    299   private static final Measure MEASURE_LONG =
    300       Measure.MeasureLong.create("measure2", "measure description", "1");
    301 }
    302