/* * Copyright 2014-2016 Netflix, Inc. * * 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 com.netflix.spectator.atlas.impl; import com.netflix.spectator.api.DefaultRegistry; import com.netflix.spectator.api.Measurement; import com.netflix.spectator.api.Registry; import com.netflix.spectator.api.Tag; import nl.jqno.equalsverifier.EqualsVerifier; import nl.jqno.equalsverifier.Warning; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @RunWith(JUnit4.class) public class DataExprTest { private final Registry registry = new DefaultRegistry(); private DataExpr parse(String expr) { DataExpr de = Parser.parseDataExpr(expr); Assert.assertEquals(expr, de.toString()); return de; } private List<TagsValuePair> data(String name, double... vs) { List<Measurement> ms = new ArrayList<>(); for (int i = 0; i < vs.length; ++i) { String pos = String.format("%03d", i); String value = String.format("%f", vs[i]); ms.add(new Measurement(registry.createId(name, "i", pos, "v", value), 0L, vs[i])); } return ms.stream().map(this::newTagsValuePair).collect(Collectors.toList()); } private TagsValuePair newTagsValuePair(Measurement m) { Map<String, String> tags = new HashMap<>(); for (Tag t : m.id().tags()) { tags.put(t.key(), t.value()); } tags.put("name", m.id().name()); return new TagsValuePair(tags, m.value()); } @Test public void sumEmpty() { DataExpr expr = parse(":true,:sum"); Assert.assertFalse(expr.eval(Collections.emptyList()).iterator().hasNext()); } @Test public void minEmpty() { DataExpr expr = parse(":true,:min"); Assert.assertFalse(expr.eval(Collections.emptyList()).iterator().hasNext()); } @Test public void maxEmpty() { DataExpr expr = parse(":true,:max"); Assert.assertFalse(expr.eval(Collections.emptyList()).iterator().hasNext()); } @Test public void countEmpty() { DataExpr expr = parse(":true,:count"); Assert.assertFalse(expr.eval(Collections.emptyList()).iterator().hasNext()); } private void aggrData(String aggr, double expected) { DataExpr expr = parse("name,foo,:eq," + aggr); List<TagsValuePair> ms = data("foo", 1.0, 2.0, 3.0, 1.0); ms.addAll(data("bar", 42.0)); Map<String, String> expectedTags = new HashMap<>(); expectedTags.put("name", "foo"); Iterable<TagsValuePair> vs = expr.eval(ms); int count = 0; for (TagsValuePair v : vs) { ++count; Assert.assertEquals(expectedTags, v.tags()); Assert.assertEquals(expected, v.value(), 1e-12); } Assert.assertEquals(1, count); } @Test public void sumData() { aggrData(":sum", 7.0); } @Test public void minData() { aggrData(":min", 1.0); } @Test public void maxData() { aggrData(":max", 3.0); } @Test public void countData() { aggrData(":count", 4.0); } @Test public void groupByNameData() { aggrData(":sum,(,name,),:by", 7.0); } private void groupingData(String aggr) { DataExpr expr = parse("name,foo,:eq,:sum," + aggr); List<TagsValuePair> ms = data("foo", 1.0, 2.0, 3.0, 1.0); ms.addAll(data("bar", 42.0)); Iterable<TagsValuePair> vs = expr.eval(ms); int count = 0; for (TagsValuePair v : vs) { ++count; Assert.assertEquals(2, v.tags().size()); Assert.assertEquals("foo", v.tags().get("name")); double tv = Double.parseDouble(v.tags().get("v")); Assert.assertEquals((tv < 2.0) ? 2.0 : tv, v.value(), 1e-12); } Assert.assertEquals(3, count); } @Test public void groupByValueData() { groupingData("(,v,),:by"); } @Test public void groupByUnknownData() { DataExpr expr = parse("name,foo,:eq,:sum,(,a,v,),:by"); List<TagsValuePair> ms = data("foo", 1.0, 2.0, 3.0, 1.0); ms.addAll(data("bar", 42.0)); Iterable<TagsValuePair> vs = expr.eval(ms); Assert.assertFalse(vs.iterator().hasNext()); } @Test public void rollupKeepData() { groupingData("(,v,name,),:rollup-keep"); } @Test public void rollupKeepUnknownData() { groupingData("(,a,v,name,),:rollup-keep"); } @Test public void rollupDropData() { groupingData("(,i,),:rollup-drop"); } @Test public void allData() { DataExpr expr = parse("name,foo,:eq,:all"); List<TagsValuePair> ms = data("foo", 1.0, 2.0, 3.0, 1.0); ms.addAll(data("bar", 42.0)); Iterable<TagsValuePair> vs = expr.eval(ms); Assert.assertEquals(4, StreamSupport.stream(vs.spliterator(), false).count()); } @Test public void notData() { DataExpr expr = parse("name,foo,:eq,:not,:all"); List<TagsValuePair> ms = data("foo", 1.0, 2.0, 3.0, 1.0); ms.addAll(data("bar", 42.0)); Iterable<TagsValuePair> vs = expr.eval(ms); Assert.assertEquals(1, StreamSupport.stream(vs.spliterator(), false).count()); } @Test public void inWithGroupBy() { // https://github.com/Netflix/spectator/issues/391 parse("statistic,(,totalAmount,totalTime,),:in,name,jvm.gc.pause,:eq,:and,:sum,(,nf.asg,nf.node,),:by"); } @Test public void allEqualsContract() { EqualsVerifier .forClass(DataExpr.All.class) .suppress(Warning.NULL_FIELDS) .verify(); } @Test public void sumEqualsContract() { EqualsVerifier .forClass(DataExpr.Sum.class) .suppress(Warning.NULL_FIELDS) .verify(); } @Test public void minEqualsContract() { EqualsVerifier .forClass(DataExpr.Min.class) .suppress(Warning.NULL_FIELDS) .verify(); } @Test public void maxEqualsContract() { EqualsVerifier .forClass(DataExpr.Max.class) .suppress(Warning.NULL_FIELDS) .verify(); } @Test public void countEqualsContract() { EqualsVerifier .forClass(DataExpr.Count.class) .suppress(Warning.NULL_FIELDS) .verify(); } @Test public void byEqualsContract() { EqualsVerifier .forClass(DataExpr.GroupBy.class) .suppress(Warning.NULL_FIELDS) .verify(); } @Test public void dropEqualsContract() { EqualsVerifier .forClass(DataExpr.DropRollup.class) .suppress(Warning.NULL_FIELDS) .verify(); } @Test public void keepEqualsContract() { EqualsVerifier .forClass(DataExpr.KeepRollup.class) .suppress(Warning.NULL_FIELDS) .verify(); } }