package com.spotify.heroic.aggregation;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.spotify.heroic.common.DateRange;
import com.spotify.heroic.common.Series;
import com.spotify.heroic.metric.Point;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class GroupingAggregationTest {
@Mock
DateRange range;
@Mock
Map<String, String> key1;
@Mock
Map<String, String> key2;
@Test
public void testChainedSessions() {
final GroupingAggregation g1 =
new GroupInstance(Optional.of(ImmutableList.of("site", "host")),
EmptyInstance.INSTANCE);
final GroupingAggregation g2 =
new GroupInstance(Optional.of(ImmutableList.of("site")), EmptyInstance.INSTANCE);
final ChainInstance chain = new ChainInstance(ImmutableList.of(g1, g2));
final Set<Series> series = new HashSet<>();
final Series s1 = Series.of("foo", ImmutableMap.of("site", "sto", "host", "a"));
final Series s2 = Series.of("foo", ImmutableMap.of("site", "sto", "host", "b"));
final Series s3 = Series.of("foo", ImmutableMap.of("site", "lon", "host", "b"));
final Series s4 = Series.of("foo", ImmutableMap.of("host", "c"));
series.add(s1);
series.add(s2);
series.add(s3);
series.add(s4);
final AggregationSession session = chain.session(new DateRange(0, 10000));
session.updatePoints(s4.getTags(), ImmutableSet.of(s4),
ImmutableList.of(new Point(4, 4.0)));
session.updatePoints(s3.getTags(), ImmutableSet.of(s3),
ImmutableList.of(new Point(3, 3.0)));
session.updatePoints(s2.getTags(), ImmutableSet.of(s2),
ImmutableList.of(new Point(2, 2.0)));
session.updatePoints(s1.getTags(), ImmutableSet.of(s1),
ImmutableList.of(new Point(1, 1.0)));
final List<AggregationOutput> result = session.result().getResult();
assertEquals(3, result.size());
final Set<Map<String, String>> expected =
result.stream().map(AggregationOutput::getKey).collect(Collectors.toSet());
for (final AggregationOutput data : result) {
if (data.getKey().equals(ImmutableMap.of("site", "lon"))) {
assertEquals(ImmutableList.of(new Point(3, 3.0)), data.getMetrics().getData());
expected.remove(ImmutableMap.of("site", "lon"));
continue;
}
if (data.getKey().equals(ImmutableMap.of("site", "sto"))) {
assertEquals(ImmutableList.of(new Point(1, 1.0), new Point(2, 2.0)),
data.getMetrics().getData());
expected.remove(ImmutableMap.of("site", "sto"));
continue;
}
if (data.getKey().equals(ImmutableMap.of())) {
assertEquals(ImmutableList.of(new Point(4, 4.0)), data.getMetrics().getData());
expected.remove(ImmutableMap.of());
continue;
}
Assert.fail("unexpected group: " + data.getKey());
}
}
/**
* Checks that the distribute aggregation for Grouping aggregations are composed out of the
* distributed aggregation for the child clause.
*/
@Test
public void testDistributedAggregation() {
final AggregationInstance distributed = mock(AggregationInstance.class);
final AggregationInstance next = mock(AggregationInstance.class);
final AggregationInstance each = mock(AggregationInstance.class);
final Optional<List<String>> of = Optional.empty();
final SimpleGroup g = spy(new SimpleGroup(of, each));
doReturn(distributed).when(each).distributed();
doReturn(next).when(g).newInstance(of, distributed);
assertEquals(next, g.distributed());
verify(each).distributed();
verify(g).newInstance(of, distributed);
}
public static class SimpleGroup extends GroupingAggregation {
public SimpleGroup(final Optional<List<String>> of, final AggregationInstance each) {
super(of, each);
}
protected Map<String, String> key(Map<String, String> input) {
return input;
}
@Override
protected AggregationInstance newInstance(
Optional<List<String>> of, AggregationInstance each
) {
return new SimpleGroup(of, each);
}
}
}