// This file is part of OpenTSDB.
// Copyright (C) 2010-2016 The OpenTSDB Authors.
//
// This program is free software: you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 2.1 of the License, or (at your
// option) any later version. This program is distributed in the hope that it
// will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
// General Public License for more details. You should have received a copy
// of the GNU Lesser General Public License along with this program. If not,
// see <http://www.gnu.org/licenses/>.
package net.opentsdb.tsd;
import static org.junit.Assert.assertTrue;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import net.opentsdb.core.FillPolicy;
import net.opentsdb.core.TSDB;
import net.opentsdb.core.TSQuery;
import net.opentsdb.query.expression.NumericFillPolicy;
import net.opentsdb.query.expression.BaseTimeSyncedIteratorTest;
import net.opentsdb.query.expression.VariableIterator.SetOperator;
import net.opentsdb.query.filter.TagVFilter;
import net.opentsdb.query.pojo.Downsampler;
import net.opentsdb.query.pojo.Expression;
import net.opentsdb.query.pojo.Filter;
import net.opentsdb.query.pojo.Join;
import net.opentsdb.query.pojo.Metric;
import net.opentsdb.query.pojo.Output;
import net.opentsdb.query.pojo.Query;
import net.opentsdb.query.pojo.Timespan;
import net.opentsdb.storage.MockBase;
import net.opentsdb.utils.Config;
import net.opentsdb.utils.DateTime;
import net.opentsdb.utils.JSON;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.stumbleupon.async.Deferred;
import com.stumbleupon.async.DeferredGroupException;
@RunWith(PowerMockRunner.class)
@PrepareForTest({TSDB.class, Config.class, HttpQuery.class,
Deferred.class, TSQuery.class, DateTime.class, DeferredGroupException.class })
public class TestQueryExecutor extends BaseTimeSyncedIteratorTest {
private Timespan time;
private List<TagVFilter> tags;
private List<Filter> filters;
private List<Metric> metrics;
private List<Expression> expressions;
private List<Output> outputs;
private Join intersection;
@Before
public void setup() {
intersection = Join.Builder().setOperator(SetOperator.INTERSECTION).build();
time = Timespan.Builder().setStart("1431561600")
.setAggregator("sum").build();
tags = Arrays.asList(new TagVFilter.Builder().setFilter("*").setGroupBy(true)
.setTagk("D").setType("wildcard").build());
filters = Arrays.asList(Filter.Builder().setId("f1")
.setTags(tags).build());
final Metric metric1 = Metric.Builder().setMetric("A").setId("a")
.setFilter("f1").build();
final Metric metric2 = Metric.Builder().setMetric("B").setId("b")
.setFilter("f1").build();
metrics = Arrays.asList(metric1, metric2);
expressions = Arrays.asList(Expression.Builder().setId("e")
.setExpression("a + b").setJoin(intersection).build());
outputs = Arrays.asList(Output.Builder().setId("e").setAlias("A plus B")
.build());
}
@Test
public void oneExpressionWithOutputAlias() throws Exception {
oneExtraSameE();
final String json = JSON.serializeToString(getDefaultQueryBuilder().build());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"alias\":\"A plus B\""));
assertTrue(response.contains("\"dps\":[[1431561600000,12.0,18.0]"));
assertTrue(response.contains("[1431561660000,14.0,20.0]"));
assertTrue(response.contains("[1431561720000,16.0,22.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
}
@Test
public void oneExpressionDefaultOutput() throws Exception {
oneExtraSameE();
final Query q = Query.Builder().setExpressions(expressions)
.setFilters(filters).setMetrics(metrics).setName("q1")
.setTime(time).build();
final String json = JSON.serializeToString(q);
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"id\":\"e\""));
assertTrue(response.contains("\"dps\":[[1431561600000,12.0,18.0]"));
assertTrue(response.contains("[1431561660000,14.0,20.0]"));
assertTrue(response.contains("[1431561720000,16.0,22.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
// TODO - more asserts once we settle on names
}
@Test
public void oneExpressionOutputAndBAlso() throws Exception {
oneExtraSameE();
outputs = new ArrayList<Output>(3);
outputs.add(Output.Builder().setId("e").setAlias("A plus B").build());
outputs.add(Output.Builder().setId("a").build());
outputs.add(Output.Builder().setId("b").build());
final String json = JSON.serializeToString(getDefaultQueryBuilder().build());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"alias\":\"A plus B\""));
assertTrue(response.contains("\"dps\":[[1431561600000,12.0,18.0]"));
assertTrue(response.contains("[1431561660000,14.0,20.0]"));
assertTrue(response.contains("[1431561720000,16.0,22.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
assertTrue(response.contains("\"id\":\"a\""));
assertTrue(response.contains("\"dps\":[[1431561600000,1.0,4.0]"));
assertTrue(response.contains("\"metrics\":[\"A\"]"));
assertTrue(response.contains("\"id\":\"b\""));
assertTrue(response.contains("\"dps\":[[1431561600000,11.0,14.0,17.0]"));
assertTrue(response.contains("\"metrics\":[\"B\"]"));
}
@Test
public void oneExpressionDefaultFill() throws Exception {
threeSameEGaps();
String json = JSON.serializeToString(getDefaultQueryBuilder());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"alias\":\"A plus B\""));
assertTrue(response.contains("\"dps\":[[1431561600000,1.0,4.0,0.0]"));
assertTrue(response.contains("[1431561660000,0.0,20.0,8.0]"));
assertTrue(response.contains("[1431561720000,16.0,0.0,28.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
assertTrue(response.contains("\"index\":3"));
}
@Test
public void oneExpressionDownsamplingMissingTimestampNoFill() throws Exception {
threeSameEGaps();
final Downsampler downsampler = Downsampler.Builder()
.setAggregator("sum")
.setInterval("1m")
.build();
time = Timespan.Builder().setStart("1431561600")
.setAggregator("sum")
.setDownsampler(downsampler).build();
String json = JSON.serializeToString(getDefaultQueryBuilder());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"alias\":\"A plus B\""));
assertTrue(response.contains("\"dps\":[[1431561600000,1.0,4.0,0.0]"));
assertTrue(response.contains("[1431561660000,0.0,20.0,8.0]"));
assertTrue(response.contains("[1431561720000,16.0,0.0,28.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
assertTrue(response.contains("\"index\":3"));
}
// @Test
// public void oneExpressionDownsamplingMissingTimestampZeroFill() throws Exception {
// threeSameEGaps();
// final Downsampler downsampler = Downsampler.Builder()
// .setAggregator("sum")
// .setInterval("1m")
// .setFillPolicy(new NumericFillPolicy(FillPolicy.ZERO))
// .build();
// time = Timespan.Builder().setStart("1431561540")
// .setEnd("1431561780")
// .setAggregator("sum")
// .setDownsampler(downsampler).build();
// String json = JSON.serializeToString(getDefaultQueryBuilder());
// final QueryRpc rpc = new QueryRpc();
// final HttpQuery query = NettyMocks.postQuery(tsdb,
// "/api/query/exp", json);
// query.getQueryBaseRoute(); // to the correct serializer
// NettyMocks.mockChannelFuture(query);
//
// rpc.execute(tsdb, query);
// final String response =
// query.response().getContent().toString(Charset.forName("UTF-8"));
// assertTrue(response.contains("\"alias\":\"A plus B\""));
// assertTrue(response.contains("\"dps\":[[1431561540000,0.0,0.0,0.0]"));
// assertTrue(response.contains("[1431561600000,1.0,4.0,0.0]"));
// assertTrue(response.contains("[1431561660000,0.0,20.0,8.0]"));
// assertTrue(response.contains("[1431561720000,16.0,0.0,28.0]"));
// assertTrue(response.contains("[1431561780000,0.0,0.0,0.0]"));
// assertTrue(response.contains("\"firstTimestamp\":1431561540000"));
// assertTrue(response.contains("\"index\":1"));
// assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
// assertTrue(response.contains("\"index\":2"));
// assertTrue(response.contains("\"index\":3"));
// }
@Test
public void oneExpressionNoFilter() throws Exception {
oneExtraSameE();
final Metric metric1 = Metric.Builder().setMetric("A").setId("a")
.build();
final Metric metric2 = Metric.Builder().setMetric("B").setId("b")
.build();
metrics = Arrays.asList(metric1, metric2);
final String json = JSON.serializeToString(getDefaultQueryBuilder().build());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
System.out.println(response);
assertTrue(response.contains("\"alias\":\"A plus B\""));
assertTrue(response.contains("\"dps\":[[1431561600000,47.0]"));
assertTrue(response.contains("[1431561660000,52.0]"));
assertTrue(response.contains("[1431561720000,57.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":1"));
}
@Test
public void twoExpressionsDefaultOutput() throws Exception {
oneExtraSameE();
expressions = Arrays.asList(
Expression.Builder().setId("e").setExpression("a + b")
.setJoin(intersection).build(),
Expression.Builder().setId("e2").setExpression("a * b")
.setJoin(intersection).build());
final Query q = Query.Builder().setExpressions(expressions)
.setFilters(filters).setMetrics(metrics).setName("q1")
.setTime(time).build();
final String json = JSON.serializeToString(q);
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"id\":\"e\""));
assertTrue(response.contains("\"dps\":[[1431561600000,12.0,18.0]"));
assertTrue(response.contains("[1431561660000,14.0,20.0]"));
assertTrue(response.contains("[1431561720000,16.0,22.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
assertTrue(response.contains("\"id\":\"e2\""));
assertTrue(response.contains("\"dps\":[[1431561600000,11.0,56.0]"));
assertTrue(response.contains("[1431561660000,24.0,75.0]"));
assertTrue(response.contains("[1431561720000,39.0,96.0]"));
}
@Test
public void twoExpressionsOneWithoutResultsDefaultOutput() throws Exception {
oneExtraSameE();
final Metric metric1 = Metric.Builder().setMetric("A").setId("a")
.setFilter("f1").setAggregator("sum").build();
final Metric metric2 = Metric.Builder().setMetric("B").setId("b")
.setFilter("f1").setAggregator("sum").build();
final Metric metric3 = Metric.Builder().setMetric("D").setId("d")
.setFilter("f1").setAggregator("sum").build();
final Metric metric4 = Metric.Builder().setMetric("F").setId("f")
.setFilter("f1").setAggregator("sum").build();
metrics = Arrays.asList(metric1, metric2, metric3, metric4);
expressions = Arrays.asList(
Expression.Builder().setId("e").setExpression("a + b")
.setJoin(intersection).build(),
Expression.Builder().setId("x").setExpression("d + f")
.setJoin(intersection).build());
final Query q = Query.Builder().setExpressions(expressions)
.setFilters(filters).setMetrics(metrics).setName("q1")
.setTime(time).build();
String json = JSON.serializeToString(q);
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"id\":\"e\""));
assertTrue(response.contains("\"dps\":[[1431561600000,12.0,18.0]"));
assertTrue(response.contains("[1431561660000,14.0,20.0]"));
assertTrue(response.contains("[1431561720000,16.0,22.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
assertTrue(response.contains("\"id\":\"x\""));
assertTrue(response.contains("\"dps\":[]"));
assertTrue(response.contains("\"firstTimestamp\":0"));
assertTrue(response.contains("\"series\":0"));
}
@Test
public void multiExpressionsOneOutput() throws Exception {
oneExtraSameE();
expressions = Arrays.asList(
Expression.Builder().setId("e").setExpression("a + b").setJoin(intersection).build(),
Expression.Builder().setId("e2").setExpression("e * 2").setJoin(intersection).build(),
Expression.Builder().setId("e3").setExpression("e * 2").setJoin(intersection).build(),
Expression.Builder().setId("e4").setExpression("e2 + e3").setJoin(intersection).build());
final String json = JSON.serializeToString(getDefaultQueryBuilder());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("[1431561660000,14.0,20.0]"));
assertTrue(response.contains("[1431561720000,16.0,22.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
}
@Test
public void nestedExpressionsOneLevelDefaultOutput() throws Exception {
oneExtraSameE();
expressions = Arrays.asList(
Expression.Builder().setId("e").setExpression("a + b")
.setJoin(intersection).build(),
Expression.Builder().setId("e2").setExpression("e * 2")
.setJoin(intersection).build());
final Query q = Query.Builder().setExpressions(expressions)
.setFilters(filters).setMetrics(metrics).setName("q1")
.setTime(time).build();
final String json = JSON.serializeToString(q);
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"id\":\"e\""));
assertTrue(response.contains("\"dps\":[[1431561600000,12.0,18.0]"));
assertTrue(response.contains("[1431561660000,14.0,20.0]"));
assertTrue(response.contains("[1431561720000,16.0,22.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
assertTrue(response.contains("\"id\":\"e2\""));
assertTrue(response.contains("\"dps\":[[1431561600000,24.0,36.0]"));
assertTrue(response.contains("[1431561660000,28.0,40.0]"));
assertTrue(response.contains("[1431561720000,32.0,44.0]"));
}
@Test
public void nestedExpressionsTwoLevelsDefaultOutput() throws Exception {
oneExtraSameE();
expressions = Arrays.asList(
Expression.Builder().setId("e").setExpression("a + b").setJoin(intersection).build(),
Expression.Builder().setId("e2").setExpression("e * 2").setJoin(intersection).build(),
Expression.Builder().setId("e3").setExpression("e * 2").setJoin(intersection).build(),
Expression.Builder().setId("e4").setExpression("e2 + e3").setJoin(intersection).build());
final Query q = Query.Builder().setExpressions(expressions)
.setFilters(filters).setMetrics(metrics).setName("q1")
.setTime(time).build();
final String json = JSON.serializeToString(q);
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"id\":\"e\""));
assertTrue(response.contains("\"dps\":[[1431561600000,12.0,18.0]"));
assertTrue(response.contains("[1431561660000,14.0,20.0]"));
assertTrue(response.contains("[1431561720000,16.0,22.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
assertTrue(response.contains("\"id\":\"e2\""));
assertTrue(response.contains("\"dps\":[[1431561600000,24.0,36.0]"));
assertTrue(response.contains("[1431561660000,28.0,40.0]"));
assertTrue(response.contains("[1431561720000,32.0,44.0]"));
assertTrue(response.contains("\"id\":\"e3\""));
assertTrue(response.contains("\"id\":\"e4\""));
assertTrue(response.contains("\"dps\":[[1431561600000,48.0,72.0]"));
assertTrue(response.contains("[1431561660000,56.0,80.0]"));
assertTrue(response.contains("[1431561720000,64.0,88.0]"));
}
@Test
public void nestedExpressionsTwoLevelsDefaultOutputOrdering() throws Exception {
oneExtraSameE();
expressions = Arrays.asList(
Expression.Builder().setId("e2").setExpression("e * 2").setJoin(intersection).build(),
Expression.Builder().setId("e4").setExpression("e2 + e3").setJoin(intersection).build(),
Expression.Builder().setId("e3").setExpression("e * 2").setJoin(intersection).build(),
Expression.Builder().setId("e").setExpression("a + b").setJoin(intersection).build()
);
final Query q = Query.Builder().setExpressions(expressions)
.setFilters(filters).setMetrics(metrics).setName("q1")
.setTime(time).build();
final String json = JSON.serializeToString(q);
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"id\":\"e\""));
assertTrue(response.contains("\"dps\":[[1431561600000,12.0,18.0]"));
assertTrue(response.contains("[1431561660000,14.0,20.0]"));
assertTrue(response.contains("[1431561720000,16.0,22.0]"));
assertTrue(response.contains("\"firstTimestamp\":1431561600000"));
assertTrue(response.contains("\"index\":1"));
assertTrue(response.contains("\"metrics\":[\"A\",\"B\"]"));
assertTrue(response.contains("\"index\":2"));
assertTrue(response.contains("\"id\":\"e2\""));
assertTrue(response.contains("\"dps\":[[1431561600000,24.0,36.0]"));
assertTrue(response.contains("[1431561660000,28.0,40.0]"));
assertTrue(response.contains("[1431561720000,32.0,44.0]"));
assertTrue(response.contains("\"id\":\"e3\""));
assertTrue(response.contains("\"id\":\"e4\""));
assertTrue(response.contains("\"dps\":[[1431561600000,48.0,72.0]"));
assertTrue(response.contains("[1431561660000,56.0,80.0]"));
assertTrue(response.contains("[1431561720000,64.0,88.0]"));
}
@Test
public void emptyResultSet() throws Exception {
setDataPointStorage();
String json = JSON.serializeToString(getDefaultQueryBuilder());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"dps\":[]"));
assertTrue(response.contains("\"firstTimestamp\":0"));
assertTrue(response.contains("\"series\":0"));
}
@Test
public void scannerException() throws Exception {
oneExtraSameE();
storage.throwException(MockBase.stringToBytes(
"00000B5553E58000000D00000F00000E00000E"),
new RuntimeException("Boo!"), true);
final String json = JSON.serializeToString(getDefaultQueryBuilder().build());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"code\":400"));
assertTrue(response.contains("\"message\":\"Boo!\""));
}
@Test
public void nsunMetric() throws Exception {
oneExtraSameE();
final Metric metric1 = Metric.Builder().setMetric("A").setId("a")
.setFilter("f1").setAggregator("sum").build();
final Metric metric2 = Metric.Builder().setMetric(NSUN_METRIC).setId("b")
.setFilter("f1").setAggregator("sum").build();
metrics = Arrays.asList(metric1, metric2);
final String json = JSON.serializeToString(getDefaultQueryBuilder().build());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"code\":400"));
assertTrue(response.contains("\"message\":\"No such name for '" +
NSUN_METRIC + "'"));
}
@Test
public void selfReferencingExpression() throws Exception {
oneExtraSameE();
expressions = Arrays.asList(
Expression.Builder().setId("e").setExpression("a + b").build(),
Expression.Builder().setId("e2").setExpression("e * 2").build(),
Expression.Builder().setId("e3").setExpression("e * 2").build(),
Expression.Builder().setId("e4").setExpression("e2 + e4").build());
final Query q = Query.Builder().setExpressions(expressions)
.setFilters(filters).setMetrics(metrics).setName("q1")
.setTime(time).build();
final String json = JSON.serializeToString(q);
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"code\":400"));
assertTrue(response.contains("\"message\":\"Self referencing"));
}
@Test
public void circularReferenceExpression() throws Exception {
oneExtraSameE();
expressions = Arrays.asList(
Expression.Builder().setId("e").setExpression("a + e4").build(),
Expression.Builder().setId("e2").setExpression("e * 2").build(),
Expression.Builder().setId("e3").setExpression("e * 2").build(),
Expression.Builder().setId("e4").setExpression("e2 + e3").build());
final Query q = Query.Builder().setExpressions(expressions)
.setFilters(filters).setMetrics(metrics).setName("q1")
.setTime(time).build();
final String json = JSON.serializeToString(q);
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"code\":400"));
assertTrue(response.contains("\"message\":\"Circular reference found:"));
}
@Test
public void noIntersectionsFound() throws Exception {
threeDifE();
String json = JSON.serializeToString(getDefaultQueryBuilder());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"code\":400"));
assertTrue(response.contains("\"message\":\"No intersections found"));
}
@Test
public void noIntersectionsFoundNestedExpression() throws Exception {
oneExtraSameE();
final Metric metric1 = Metric.Builder().setMetric("A").setId("a")
.setFilter("f1").setAggregator("sum").build();
final Metric metric2 = Metric.Builder().setMetric("B").setId("b")
.setFilter("f1").setAggregator("sum").build();
final Metric metric3 = Metric.Builder().setMetric("D").setId("d")
.setFilter("f1").setAggregator("sum").build();
metrics = Arrays.asList(metric1, metric2, metric3);
expressions = Arrays.asList(
Expression.Builder().setId("e").setExpression("a + b").setJoin(intersection).build(),
Expression.Builder().setId("x").setExpression("d + e").setJoin(intersection).build());
final Query q = Query.Builder().setExpressions(expressions)
.setFilters(filters).setMetrics(metrics).setName("q1")
.setTime(time).build();
String json = JSON.serializeToString(q);
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"code\":400"));
assertTrue(response.contains("\"message\":\"No intersections found"));
}
@Test
public void noIntersectionsFoundOneMetricEmpty() throws Exception {
oneExtraSameE();
final Metric metric1 = Metric.Builder().setMetric("A").setId("a")
.setFilter("f1").setAggregator("sum").build();
final Metric metric2 = Metric.Builder().setMetric("D").setId("b")
.setFilter("f1").setAggregator("sum").build();
metrics = Arrays.asList(metric1, metric2);
String json = JSON.serializeToString(getDefaultQueryBuilder());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
final String response =
query.response().getContent().toString(Charset.forName("UTF-8"));
assertTrue(response.contains("\"code\":400"));
assertTrue(response.contains("\"message\":\"No intersections found"));
}
@Test (expected = IllegalArgumentException.class)
public void notEnoughMetrics() throws Exception {
oneExtraSameE();
expressions = Arrays.asList(
Expression.Builder().setId("e").setExpression("a + b + c").build());
String json = JSON.serializeToString(getDefaultQueryBuilder());
final QueryRpc rpc = new QueryRpc();
final HttpQuery query = NettyMocks.postQuery(tsdb,
"/api/query/exp", json);
query.getQueryBaseRoute(); // to the correct serializer
NettyMocks.mockChannelFuture(query);
rpc.execute(tsdb, query);
}
protected Query.Builder getDefaultQueryBuilder() {
return Query.Builder().setExpressions(expressions).setFilters(filters)
.setMetrics(metrics).setName("q1").setTime(time).setOutputs(outputs);
}
}