io.druid.query.timeboundary.TimeBoundaryQueryRunnerTest.java Source code

Java tutorial

Introduction

Here is the source code for io.druid.query.timeboundary.TimeBoundaryQueryRunnerTest.java

Source

/*
 * Licensed to Metamarkets Group Inc. (Metamarkets) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. Metamarkets licenses this file
 * to you 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.druid.query.timeboundary;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.common.io.CharSource;
import io.druid.granularity.QueryGranularities;
import io.druid.java.util.common.guava.Sequences;
import io.druid.query.Druids;
import io.druid.query.QueryRunner;
import io.druid.query.QueryRunnerFactory;
import io.druid.query.QueryRunnerTestHelper;
import io.druid.query.Result;
import io.druid.query.TableDataSource;
import io.druid.query.ordering.StringComparators;
import io.druid.segment.IncrementalIndexSegment;
import io.druid.segment.Segment;
import io.druid.segment.TestIndex;
import io.druid.segment.incremental.IncrementalIndex;
import io.druid.segment.incremental.IncrementalIndexSchema;
import io.druid.segment.incremental.OnheapIncrementalIndex;
import io.druid.timeline.DataSegment;
import io.druid.timeline.TimelineObjectHolder;
import io.druid.timeline.VersionedIntervalTimeline;
import io.druid.timeline.partition.NoneShardSpec;
import io.druid.timeline.partition.SingleElementPartitionChunk;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.Interval;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 */
@RunWith(Parameterized.class)
public class TimeBoundaryQueryRunnerTest {
    @Parameterized.Parameters(name = "{0}")
    public static Iterable<Object[]> constructorFeeder() throws IOException {
        return QueryRunnerTestHelper.transformToConstructionFeeder(QueryRunnerTestHelper
                .makeQueryRunners(new TimeBoundaryQueryRunnerFactory(QueryRunnerTestHelper.NOOP_QUERYWATCHER)));
    }

    private final QueryRunner runner;
    private static final QueryRunnerFactory factory = new TimeBoundaryQueryRunnerFactory(
            QueryRunnerTestHelper.NOOP_QUERYWATCHER);
    private static Segment segment0;
    private static Segment segment1;
    private static List<String> segmentIdentifiers;

    public TimeBoundaryQueryRunnerTest(QueryRunner runner) {
        this.runner = runner;
    }

    // Adapted from MultiSegmentSelectQueryTest, with modifications to make filtering meaningful
    public static final String[] V_0112 = {
            "2011-01-12T01:00:00.000Z   spot   business   preferred   bpreferred   100.000000",
            "2011-01-12T02:00:00.000Z   spot   entertainment   preferred   epreferred   100.000000",
            "2011-01-13T00:00:00.000Z   spot   automotive   preferred   apreferred   100.000000",
            "2011-01-13T01:00:00.000Z   spot   business   preferred   bpreferred   100.000000", };
    public static final String[] V_0113 = {
            "2011-01-14T00:00:00.000Z   spot   automotive   preferred   apreferred   94.874713",
            "2011-01-14T02:00:00.000Z   spot   entertainment   preferred   epreferred   110.087299",
            "2011-01-15T00:00:00.000Z   spot   automotive   preferred   apreferred   94.874713",
            "2011-01-15T01:00:00.000Z   spot   business   preferred   bpreferred   103.629399",
            "2011-01-16T00:00:00.000Z   spot   automotive   preferred   apreferred   94.874713",
            "2011-01-16T01:00:00.000Z   spot   business   preferred   bpreferred   103.629399",
            "2011-01-16T02:00:00.000Z   spot   entertainment   preferred   epreferred   110.087299",
            "2011-01-17T01:00:00.000Z   spot   business   preferred   bpreferred   103.629399",
            "2011-01-17T02:00:00.000Z   spot   entertainment   preferred   epreferred   110.087299", };

    private static IncrementalIndex newIndex(String minTimeStamp) {
        return newIndex(minTimeStamp, 10000);
    }

    private static IncrementalIndex newIndex(String minTimeStamp, int maxRowCount) {
        final IncrementalIndexSchema schema = new IncrementalIndexSchema.Builder()
                .withMinTimestamp(new DateTime(minTimeStamp).getMillis())
                .withQueryGranularity(QueryGranularities.HOUR).withMetrics(TestIndex.METRIC_AGGS).build();
        return new OnheapIncrementalIndex(schema, true, maxRowCount);
    }

    private static String makeIdentifier(IncrementalIndex index, String version) {
        return makeIdentifier(index.getInterval(), version);
    }

    private static String makeIdentifier(Interval interval, String version) {
        return DataSegment.makeDataSegmentIdentifier(QueryRunnerTestHelper.dataSource, interval.getStart(),
                interval.getEnd(), version, new NoneShardSpec());
    }

    private QueryRunner getCustomRunner() throws IOException {
        CharSource v_0112 = CharSource.wrap(StringUtils.join(V_0112, "\n"));
        CharSource v_0113 = CharSource.wrap(StringUtils.join(V_0113, "\n"));

        IncrementalIndex index0 = TestIndex.loadIncrementalIndex(newIndex("2011-01-12T00:00:00.000Z"), v_0112);
        IncrementalIndex index1 = TestIndex.loadIncrementalIndex(newIndex("2011-01-14T00:00:00.000Z"), v_0113);

        segment0 = new IncrementalIndexSegment(index0, makeIdentifier(index0, "v1"));
        segment1 = new IncrementalIndexSegment(index1, makeIdentifier(index1, "v1"));

        VersionedIntervalTimeline<String, Segment> timeline = new VersionedIntervalTimeline(
                StringComparators.LEXICOGRAPHIC);
        timeline.add(index0.getInterval(), "v1", new SingleElementPartitionChunk(segment0));
        timeline.add(index1.getInterval(), "v1", new SingleElementPartitionChunk(segment1));

        segmentIdentifiers = Lists.newArrayList();
        for (TimelineObjectHolder<String, ?> holder : timeline.lookup(new Interval("2011-01-12/2011-01-17"))) {
            segmentIdentifiers.add(makeIdentifier(holder.getInterval(), holder.getVersion()));
        }

        return QueryRunnerTestHelper.makeFilteringQueryRunner(timeline, factory);
    }

    @Test
    @SuppressWarnings("unchecked")
    public void testFilteredTimeBoundaryQuery() throws IOException {
        QueryRunner customRunner = getCustomRunner();
        TimeBoundaryQuery timeBoundaryQuery = Druids.newTimeBoundaryQueryBuilder().dataSource("testing")
                .filters("quality", "automotive").build();
        Assert.assertTrue(timeBoundaryQuery.hasFilters());
        HashMap<String, Object> context = new HashMap<String, Object>();
        Iterable<Result<TimeBoundaryResultValue>> results = Sequences.toList(
                customRunner.run(timeBoundaryQuery, context),
                Lists.<Result<TimeBoundaryResultValue>>newArrayList());

        Assert.assertTrue(Iterables.size(results) > 0);

        TimeBoundaryResultValue val = results.iterator().next().getValue();
        DateTime minTime = val.getMinTime();
        DateTime maxTime = val.getMaxTime();

        Assert.assertEquals(new DateTime("2011-01-13T00:00:00.000Z"), minTime);
        Assert.assertEquals(new DateTime("2011-01-16T00:00:00.000Z"), maxTime);
    }

    @Test
    @SuppressWarnings("unchecked")
    public void testFilteredTimeBoundaryQueryNoMatches() throws IOException {
        QueryRunner customRunner = getCustomRunner();
        TimeBoundaryQuery timeBoundaryQuery = Druids.newTimeBoundaryQueryBuilder().dataSource("testing")
                .filters("quality", "foobar") // foobar dimension does not exist
                .build();
        Assert.assertTrue(timeBoundaryQuery.hasFilters());
        HashMap<String, Object> context = new HashMap<String, Object>();
        Iterable<Result<TimeBoundaryResultValue>> results = Sequences.toList(
                customRunner.run(timeBoundaryQuery, context),
                Lists.<Result<TimeBoundaryResultValue>>newArrayList());

        Assert.assertTrue(Iterables.size(results) == 0);
    }

    @Test
    @SuppressWarnings("unchecked")
    public void testTimeBoundary() {
        TimeBoundaryQuery timeBoundaryQuery = Druids.newTimeBoundaryQueryBuilder().dataSource("testing").build();
        Assert.assertFalse(timeBoundaryQuery.hasFilters());
        HashMap<String, Object> context = new HashMap<String, Object>();
        Iterable<Result<TimeBoundaryResultValue>> results = Sequences.toList(runner.run(timeBoundaryQuery, context),
                Lists.<Result<TimeBoundaryResultValue>>newArrayList());
        TimeBoundaryResultValue val = results.iterator().next().getValue();
        DateTime minTime = val.getMinTime();
        DateTime maxTime = val.getMaxTime();

        Assert.assertEquals(new DateTime("2011-01-12T00:00:00.000Z"), minTime);
        Assert.assertEquals(new DateTime("2011-04-15T00:00:00.000Z"), maxTime);
    }

    @Test
    @SuppressWarnings("unchecked")
    public void testTimeBoundaryMax() {
        TimeBoundaryQuery timeBoundaryQuery = Druids.newTimeBoundaryQueryBuilder().dataSource("testing")
                .bound(TimeBoundaryQuery.MAX_TIME).build();
        Map<String, Object> context = new MapMaker().makeMap();
        context.put(Result.MISSING_SEGMENTS_KEY, Lists.newArrayList());
        Iterable<Result<TimeBoundaryResultValue>> results = Sequences.toList(runner.run(timeBoundaryQuery, context),
                Lists.<Result<TimeBoundaryResultValue>>newArrayList());
        TimeBoundaryResultValue val = results.iterator().next().getValue();
        DateTime minTime = val.getMinTime();
        DateTime maxTime = val.getMaxTime();

        Assert.assertNull(minTime);
        Assert.assertEquals(new DateTime("2011-04-15T00:00:00.000Z"), maxTime);
    }

    @Test
    @SuppressWarnings("unchecked")
    public void testTimeBoundaryMin() {
        TimeBoundaryQuery timeBoundaryQuery = Druids.newTimeBoundaryQueryBuilder().dataSource("testing")
                .bound(TimeBoundaryQuery.MIN_TIME).build();
        Map<String, Object> context = new MapMaker().makeMap();
        context.put(Result.MISSING_SEGMENTS_KEY, Lists.newArrayList());
        Iterable<Result<TimeBoundaryResultValue>> results = Sequences.toList(runner.run(timeBoundaryQuery, context),
                Lists.<Result<TimeBoundaryResultValue>>newArrayList());
        TimeBoundaryResultValue val = results.iterator().next().getValue();
        DateTime minTime = val.getMinTime();
        DateTime maxTime = val.getMaxTime();

        Assert.assertEquals(new DateTime("2011-01-12T00:00:00.000Z"), minTime);
        Assert.assertNull(maxTime);
    }

    @Test
    public void testMergeResults() throws Exception {
        List<Result<TimeBoundaryResultValue>> results = Arrays.asList(
                new Result<>(new DateTime(),
                        new TimeBoundaryResultValue(
                                ImmutableMap.of("maxTime", "2012-01-01", "minTime", "2011-01-01"))),
                new Result<>(new DateTime(), new TimeBoundaryResultValue(
                        ImmutableMap.of("maxTime", "2012-02-01", "minTime", "2011-01-01"))));

        TimeBoundaryQuery query = new TimeBoundaryQuery(new TableDataSource("test"), null, null, null, null);
        Iterable<Result<TimeBoundaryResultValue>> actual = query.mergeResults(results);

        Assert.assertTrue(actual.iterator().next().getValue().getMaxTime().equals(new DateTime("2012-02-01")));
    }

    @Test
    public void testMergeResultsEmptyResults() throws Exception {
        List<Result<TimeBoundaryResultValue>> results = Lists.newArrayList();

        TimeBoundaryQuery query = new TimeBoundaryQuery(new TableDataSource("test"), null, null, null, null);
        Iterable<Result<TimeBoundaryResultValue>> actual = query.mergeResults(results);

        Assert.assertFalse(actual.iterator().hasNext());
    }
}