// This file is part of OpenTSDB.
// Copyright (C) 2015 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.query.expression;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.modules.junit4.PowerMockRunner;
import net.opentsdb.core.DataPoint;
import net.opentsdb.core.FillPolicy;
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*", "javax.xml.*",
"ch.qos.*", "org.slf4j.*",
"com.sum.*", "org.xml.*"})
public class TestTimeSyncedIterator extends BaseTimeSyncedIteratorTest {
@Test
public void ctor() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
assertEquals(3, it.size());
assertTrue(it.hasNext());
assertEquals(0, it.getIndex());
assertEquals("0", it.getId());
assertEquals(results.get("0").getKey().getFilterTagKs(), it.getQueryTagKs());
assertTrue(results.get("0").getValue() == it.getDataPoints());
assertEquals(3, it.values().length);
assertEquals(1, it.getQueryTagKs().size());
assertEquals(FillPolicy.ZERO, it.getFillPolicy().getPolicy());
}
@Test (expected = IllegalArgumentException.class)
public void ctorNullId() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
new TimeSyncedIterator(null,
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
}
@Test (expected = IllegalArgumentException.class)
public void ctorEmptyId() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
new TimeSyncedIterator("",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
}
@Test
public void ctorNullQueryTags() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0", null,
results.get("0").getValue());
assertEquals(3, it.size());
assertTrue(it.hasNext());
assertEquals(0, it.getIndex());
assertEquals("0", it.getId());
assertNull(it.getQueryTagKs());
assertTrue(results.get("0").getValue() == it.getDataPoints());
assertEquals(3, it.values().length);
}
@Test (expected = IllegalArgumentException.class)
public void ctorNullDPs() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
new TimeSyncedIterator("0", results.get("0").getKey().getFilterTagKs(),
null);
}
@Test
public void threeSeries() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
long ts = it.nextTimestamp();
assertEquals(1431561600000L, ts);
double[] values = new double[] { 1, 4, 7 };
while (it.hasNext()) {
final DataPoint[] dps = it.next(ts);
assertEquals(3, dps.length);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(values[0]++, dps[0].toDouble(), 0.0001);
assertEquals(values[1]++, dps[1].toDouble(), 0.0001);
assertEquals(values[2]++, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
}
assertEquals(Long.MAX_VALUE, ts);
}
@Test
public void threeSeriesEmitter() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
long ts = it.nextTimestamp();
assertEquals(1431561600000L, ts);
final DataPoint[] dps = it.values();
double[] values = new double[] { 1, 4, 7 };
while (it.hasNext()) {
it.next(ts);
assertEquals(3, dps.length);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(values[0]++, dps[0].toDouble(), 0.0001);
assertEquals(values[1]++, dps[1].toDouble(), 0.0001);
assertEquals(values[2]++, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
}
assertEquals(Long.MAX_VALUE, ts);
}
@Test
public void nullASeries() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
// mimic the intersector kicking out a series
it.nullIterator(0);
long ts = it.nextTimestamp();
assertEquals(1431561600000L, ts);
final DataPoint[] dps = it.values();
double[] values = new double[] { 1, 4, 7 };
while (it.hasNext()) {
it.next(ts);
assertEquals(3, dps.length);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(0, dps[0].toDouble(), 0.0001);
assertEquals(values[1]++, dps[1].toDouble(), 0.0001);
assertEquals(values[2]++, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
}
assertEquals(Long.MAX_VALUE, ts);
}
@Test
public void nullAll() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
// mimic the intersector kicking out all series.
it.nullIterator(0);
it.nullIterator(1);
it.nullIterator(2);
assertEquals(Long.MAX_VALUE, it.nextTimestamp());
assertFalse(it.hasNext());
}
@Test
public void singleSeries() throws Exception {
threeDisjointSameE();
queryA_DD();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
long ts = it.nextTimestamp();
assertEquals(1431561600000L, ts);
double value = 1;
while (it.hasNext()) {
final DataPoint[] dps = it.next(ts);
assertEquals(1, dps.length);
assertEquals(ts, dps[0].timestamp());
assertEquals(value++, dps[0].toDouble(), 0.0001);
ts = it.nextTimestamp();
}
assertEquals(Long.MAX_VALUE, ts);
}
@Test
public void noData() throws Exception {
setDataPointStorage();
queryA_DD();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
assertEquals(0, it.values().length);
assertEquals(Long.MAX_VALUE, it.nextTimestamp());
assertFalse(it.hasNext());
}
@Test
public void threeSeriesMissing() throws Exception {
threeSameEGaps();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
it.setFillPolicy(new NumericFillPolicy(FillPolicy.NOT_A_NUMBER));
long ts = it.nextTimestamp();
assertEquals(1431561600000L, ts);
DataPoint[] dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(1, dps[0].toDouble(), 0.0001);
assertEquals(4, dps[1].toDouble(), 0.0001);
assertTrue(Double.isNaN(dps[2].toDouble()));
ts = it.nextTimestamp();
dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertTrue(Double.isNaN(dps[0].toDouble()));
assertEquals(5, dps[1].toDouble(), 0.0001);
assertEquals(8, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(3, dps[0].toDouble(), 0.0001);
assertTrue(Double.isNaN(dps[1].toDouble()));
assertEquals(9, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
}
@Test
public void threeSeriesMissingFillZero() throws Exception {
threeSameEGaps();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
it.setFillPolicy(new NumericFillPolicy(FillPolicy.ZERO));
long ts = it.nextTimestamp();
assertEquals(1431561600000L, ts);
DataPoint[] dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(1, dps[0].toDouble(), 0.0001);
assertEquals(4, dps[1].toDouble(), 0.0001);
assertEquals(0, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(0, dps[0].toDouble(), 0.0001);
assertEquals(5, dps[1].toDouble(), 0.0001);
assertEquals(8, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(3, dps[0].toDouble(), 0.0001);
assertEquals(0, dps[1].toDouble(), 0.0001);
assertEquals(9, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
}
@Test
public void threeSeriesMissingNull() throws Exception {
threeSameEGaps();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
it.setFillPolicy(new NumericFillPolicy(FillPolicy.NULL));
long ts = it.nextTimestamp();
assertEquals(1431561600000L, ts);
DataPoint[] dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(1, dps[0].toDouble(), 0.0001);
assertEquals(4, dps[1].toDouble(), 0.0001);
assertTrue(Double.isNaN(dps[2].toDouble()));
ts = it.nextTimestamp();
dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertTrue(Double.isNaN(dps[0].toDouble()));
assertEquals(5, dps[1].toDouble(), 0.0001);
assertEquals(8, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(3, dps[0].toDouble(), 0.0001);
assertTrue(Double.isNaN(dps[1].toDouble()));
assertEquals(9, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
}
@Test
public void threeSeriesMissingScalar() throws Exception {
threeSameEGaps();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
it.setFillPolicy(new NumericFillPolicy(FillPolicy.SCALAR, 42));
long ts = it.nextTimestamp();
assertEquals(1431561600000L, ts);
DataPoint[] dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(1, dps[0].toDouble(), 0.0001);
assertEquals(4, dps[1].toDouble(), 0.0001);
assertEquals(42, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(42, dps[0].toDouble(), 0.0001);
assertEquals(5, dps[1].toDouble(), 0.0001);
assertEquals(8, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
dps = it.next(ts);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(3, dps[0].toDouble(), 0.0001);
assertEquals(42, dps[1].toDouble(), 0.0001);
assertEquals(9, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
}
@Test
public void failToNextTS() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
long ts = it.nextTimestamp();
assertEquals(1431561600000L, ts);
int i = 0;
boolean broke = false;
while (it.hasNext()) {
// in this case the caller fails to advance the TS so we keep getting the
// same data points over and over again.
it.next(ts);
++i;
if (i > 100) {
broke = true;
break;
}
}
if (!broke) {
fail("Expected to iterate over 100 times");
}
}
@Test
public void nextTimestampDoesntAdvance() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
assertEquals(1431561600000L, it.nextTimestamp());
assertEquals(1431561600000L, it.nextTimestamp());
assertEquals(1431561600000L, it.nextTimestamp());
assertEquals(1431561600000L, it.nextTimestamp());
assertEquals(1431561600000L, it.nextTimestamp());
assertEquals(1431561600000L, it.nextTimestamp());
assertEquals(1431561600000L, it.nextTimestamp());
}
@Test
public void nextExceptionNoException() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
it.next(it.nextTimestamp());
it.next(it.nextTimestamp());
it.next(it.nextTimestamp());
it.next(it.nextTimestamp());
assertEquals(Long.MAX_VALUE, it.nextTimestamp());
}
@Test
public void getCopy() throws Exception {
threeDisjointSameE();
queryAB_Dstar();
final TimeSyncedIterator it = new TimeSyncedIterator("0",
results.get("0").getKey().getFilterTagKs(),
results.get("0").getValue());
final ITimeSyncedIterator copy = it.getCopy();
assertTrue(copy != it);
long ts = it.nextTimestamp();
assertEquals(1431561600000L, ts);
double[] values = new double[] { 1, 4, 7 };
while (it.hasNext()) {
final DataPoint[] dps = it.next(ts);
assertEquals(3, dps.length);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(values[0]++, dps[0].toDouble(), 0.0001);
assertEquals(values[1]++, dps[1].toDouble(), 0.0001);
assertEquals(values[2]++, dps[2].toDouble(), 0.0001);
ts = it.nextTimestamp();
}
assertEquals(Long.MAX_VALUE, ts);
ts = copy.nextTimestamp();
assertEquals(1431561600000L, ts);
values = new double[] { 1, 4, 7 };
while (copy.hasNext()) {
final DataPoint[] dps = copy.next(ts);
assertEquals(3, dps.length);
assertEquals(ts, dps[0].timestamp());
assertEquals(ts, dps[1].timestamp());
assertEquals(ts, dps[2].timestamp());
assertEquals(values[0]++, dps[0].toDouble(), 0.0001);
assertEquals(values[1]++, dps[1].toDouble(), 0.0001);
assertEquals(values[2]++, dps[2].toDouble(), 0.0001);
ts = copy.nextTimestamp();
}
assertEquals(Long.MAX_VALUE, ts);
}
}