package com.linkedin.thirdeye.rootcause;
import com.linkedin.thirdeye.rootcause.impl.LinearAggregationPipeline;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import org.testng.Assert;
import org.testng.annotations.Test;
public class RCAFrameworkTest {
private static final String INPUT = RCAFramework.INPUT;
private static final String OUTPUT = RCAFramework.OUTPUT;
static class DummyPipeline extends Pipeline {
public DummyPipeline(String name, Set<String> inputs) {
super(name, inputs);
}
@Override
public PipelineResult run(PipelineContext context) {
return new PipelineResult(context, Collections.<Entity>emptySet());
}
}
@Test
public void testLinearAggregationPipeline() {
LinearAggregationPipeline agg = new LinearAggregationPipeline("", Collections.<String>emptySet(), -1);
Entity e1 = new Entity("e:one", 1.0);
Entity e2 = new Entity("e:two", 2.1);
Entity e3 = new Entity("e:three", 3.2);
Entity e4 = new Entity("e:four", 4.0);
Set<Entity> scores1 = new HashSet<>();
scores1.add(e1);
scores1.add(e2);
scores1.add(e3);
Set<Entity> scores2 = new HashSet<>();
scores2.add(e2);
scores2.add(e3);
scores2.add(e4);
Map<String, Set<Entity>> inputs = new HashMap<>();
inputs.put("p1", scores1);
inputs.put("p2", scores2);
PipelineContext context = new PipelineContext(inputs);
List<Entity> entities = new ArrayList<>(agg.run(context).getEntities());
Collections.sort(entities, Entity.HIGHEST_SCORE_FIRST);
Assert.assertEquals(entities.size(), 4);
Assert.assertEquals(entities.get(0).getUrn(), e3.getUrn());
Assert.assertEquals(entities.get(0).getScore(), 6.4);
Assert.assertEquals(entities.get(1).getUrn(), e2.getUrn());
Assert.assertEquals(entities.get(1).getScore(), 4.2);
Assert.assertEquals(entities.get(2).getUrn(), e4.getUrn());
Assert.assertEquals(entities.get(2).getScore(), 4.0);
Assert.assertEquals(entities.get(3).getUrn(), e1.getUrn());
Assert.assertEquals(entities.get(3).getScore(), 1.0);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testInvalidDAGInputPipeline() {
Collection<Pipeline> pipelines = new ArrayList<>();
pipelines.add(makePipeline(INPUT));
pipelines.add(makePipeline(OUTPUT, INPUT));
new RCAFramework(pipelines, Executors.newSingleThreadExecutor());
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testInvalidDAGNoOutput() {
Collection<Pipeline> pipelines = new ArrayList<>();
pipelines.add(makePipeline("a", INPUT));
new RCAFramework(pipelines, Executors.newSingleThreadExecutor());
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testInvalidDAGNoPath() {
Collection<Pipeline> pipelines = new ArrayList<>();
pipelines.add(makePipeline("a", INPUT));
pipelines.add(makePipeline(OUTPUT, "a", "b"));
new RCAFramework(pipelines, Executors.newSingleThreadExecutor());
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testInvalidDAGDuplicateName() {
Collection<Pipeline> pipelines = new ArrayList<>();
pipelines.add(makePipeline("a"));
pipelines.add(makePipeline("a", INPUT));
pipelines.add(makePipeline(OUTPUT, INPUT, "a"));
new RCAFramework(pipelines, Executors.newSingleThreadExecutor());
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testInvalidDAGCyclicDependency() {
Collection<Pipeline> pipelines = new ArrayList<>();
pipelines.add(makePipeline("a", INPUT, "b"));
pipelines.add(makePipeline("b", INPUT, "a"));
pipelines.add(makePipeline(OUTPUT, "a", "b"));
new RCAFramework(pipelines, Executors.newSingleThreadExecutor());
}
@Test
public void testValidDAG() {
Collection<Pipeline> pipelines = new ArrayList<>();
pipelines.add(makePipeline("none"));
pipelines.add(makePipeline("a", INPUT));
pipelines.add(makePipeline("b", INPUT, "a"));
pipelines.add(makePipeline(OUTPUT, INPUT, "a", "b", "none"));
new RCAFramework(pipelines, Executors.newSingleThreadExecutor());
}
static DummyPipeline makePipeline(String name, String... inputs) {
return new DummyPipeline(name, new HashSet<>(Arrays.asList(inputs)));
}
}