/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.depgraph.impl; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotSame; import static org.testng.Assert.assertSame; import java.util.Collections; import java.util.Iterator; import java.util.Set; import org.testng.annotations.Test; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.opengamma.engine.ComputationTargetSpecification; import com.opengamma.engine.depgraph.DependencyGraph; import com.opengamma.engine.depgraph.DependencyNode; import com.opengamma.engine.depgraph.DependencyNodeFunction; import com.opengamma.engine.depgraph.builder.TestDependencyGraphBuilder; import com.opengamma.engine.depgraph.builder.TestDependencyGraphBuilder.NodeBuilder; import com.opengamma.engine.function.EmptyFunctionParameters; import com.opengamma.engine.value.ValueProperties; import com.opengamma.engine.value.ValuePropertyNames; import com.opengamma.engine.value.ValueRequirement; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.util.test.TestGroup; /** * Tests the {@link DependencyGraphImpl} class. */ @Test(groups = TestGroup.UNIT) public class DependencyGraphImplTest { public void testEmpty() { final TestDependencyGraphBuilder builder = new TestDependencyGraphBuilder("Empty"); final DependencyGraph graph = builder.buildGraph(); assertEquals(graph.getCalculationConfigurationName(), "Empty"); assertEquals(graph.getSize(), 0); assertEquals(graph.getTerminalOutputs(), Collections.<ValueSpecification, Set<ValueRequirement>>emptyMap()); assertEquals(DependencyGraphImpl.getDependencyNodes(graph), Collections.emptySet()); assertSame(DependencyGraphImpl.removeUnnecessaryValues(graph), graph); } public void testSimple() { final TestDependencyGraphBuilder gb = new TestDependencyGraphBuilder("Small"); NodeBuilder nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification spec1 = nb.addOutput("A"); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification spec2 = nb.addOutput("B"); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); nb.addInput(spec1); nb.addInput(spec2); final ValueSpecification spec3 = nb.addOutput("C"); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification spec4 = nb.addTerminalOutput("D"); nb.addInput(spec3); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification spec5 = nb.addTerminalOutput("E"); nb.addInput(spec3); final DependencyGraph graph = gb.buildGraph(); assertEquals(graph.getCalculationConfigurationName(), "Small"); assertEquals(graph.getSize(), 5); assertEquals( graph.getTerminalOutputs(), ImmutableMap.of(spec4, Collections.singleton(new ValueRequirement("D", spec4.getTargetSpecification())), spec5, Collections.singleton(new ValueRequirement("E", spec5.getTargetSpecification())))); assertEquals(DependencyGraphImpl.getDependencyNodes(graph).size(), 5); final Iterator<DependencyNode> itr = graph.nodeIterator(); // The checks below assume a specific ordering of the iterator assertEquals(ImmutableSet.of(itr.next().getOutputValue(0), itr.next().getOutputValue(0)), ImmutableSet.of(spec1, spec2)); assertEquals(itr.next().getOutputValue(0), spec3); assertEquals(ImmutableSet.of(itr.next().getOutputValue(0), itr.next().getOutputValue(0)), ImmutableSet.of(spec4, spec5)); assertFalse(itr.hasNext()); assertSame(DependencyGraphImpl.removeUnnecessaryValues(graph), graph); } public void testRemoveUnnecessaryValues_1() { final TestDependencyGraphBuilder gb = new TestDependencyGraphBuilder("Redundant"); NodeBuilder nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification a = nb.addOutput("A"); nb.addOutput("X"); final ValueSpecification b = gb.addNode("Test", ComputationTargetSpecification.NULL).addOutput("B"); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification c = nb.addOutput("C"); final ValueSpecification y = nb.addTerminalOutput("Y"); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification d = nb.addOutput("D"); nb.addOutput("Z"); nb.addInput(a); nb.addInput(b); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification e = nb.addOutput("E"); nb.addInput(b); nb.addInput(c); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification f = nb.addTerminalOutput("F"); nb.addInput(d); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); nb.addOutput("G"); nb.addInput(d); nb.addInput(e); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); nb.addOutput("H"); nb.addInput(e); final DependencyGraph graph = gb.buildGraph(); assertEquals(graph.getRootCount(), 3); assertEquals(graph.getSize(), 8); final DependencyGraph graph2 = DependencyGraphImpl.removeUnnecessaryValues(graph); assertEquals(graph2.getRootCount(), 2); assertEquals(ImmutableSet.of(graph2.getRootNode(0).getOutputValue(0), graph2.getRootNode(1).getOutputValue(0)), ImmutableSet.of(f, y)); assertEquals(graph2.getSize(), 5); assertEquals(DependencyGraphImpl.getAllOutputSpecifications(graph2), ImmutableSet.of(a, b, d, f, y)); } public void testRemoveUnnecessaryValues_2() { final TestDependencyGraphBuilder gb = new TestDependencyGraphBuilder("Redundant"); NodeBuilder nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification a = nb.addOutput("A"); nb.addOutput("X"); final ValueSpecification b = gb.addNode("Test", ComputationTargetSpecification.NULL).addOutput("B"); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification c = nb.addOutput("C"); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification d = nb.addOutput("D"); nb.addOutput("Z"); nb.addInput(a); nb.addInput(b); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification e = nb.addOutput("E"); nb.addInput(b); nb.addInput(c); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification f = nb.addTerminalOutput("F"); nb.addInput(d); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); nb.addOutput("G"); nb.addInput(d); nb.addInput(e); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); nb.addOutput("H"); nb.addInput(e); final DependencyGraph graph = gb.buildGraph(); assertEquals(graph.getRootCount(), 3); assertEquals(graph.getSize(), 8); final DependencyGraph graph2 = DependencyGraphImpl.removeUnnecessaryValues(graph); assertEquals(graph2.getRootCount(), 1); assertEquals(ImmutableSet.of(graph2.getRootNode(0).getOutputValue(0)), ImmutableSet.of(f)); assertEquals(graph2.getSize(), 4); assertEquals(DependencyGraphImpl.getAllOutputSpecifications(graph2), ImmutableSet.of(a, b, d, f)); } public void testRemoveUnnecessaryValues_3() { final TestDependencyGraphBuilder gb = new TestDependencyGraphBuilder("Redundant"); NodeBuilder nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification a = nb.addOutput("A"); nb.addOutput("X"); final ValueSpecification b = gb.addNode("Test", ComputationTargetSpecification.NULL).addOutput("B"); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification d = nb.addOutput("D"); nb.addOutput("Z"); nb.addInput(a); nb.addInput(b); nb = gb.addNode("Test", ComputationTargetSpecification.NULL); final ValueSpecification f = nb.addTerminalOutput("F"); nb.addInput(d); final DependencyGraph graph = gb.buildGraph(); assertEquals(graph.getRootCount(), 1); assertEquals(graph.getSize(), 4); final DependencyGraph graph2 = DependencyGraphImpl.removeUnnecessaryValues(graph); assertEquals(graph2.getRootCount(), 1); assertEquals(ImmutableSet.of(graph2.getRootNode(0).getOutputValue(0)), ImmutableSet.of(f)); assertEquals(graph2.getSize(), 4); assertNotSame(graph, graph2); assertEquals(DependencyGraphImpl.getAllOutputSpecifications(graph2), ImmutableSet.of(a, b, d, f)); } public void testRemoveUnnecessaryValues_4() { // [PLAT-4922] No unnecessary values but graph gets corrupted final ValueSpecification[] v = new ValueSpecification[5]; final ValueRequirement[] r = new ValueRequirement[5]; for (int i = 0; i < v.length; i++) { v[i] = new ValueSpecification(Integer.toString(i), ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "Test").get()); r[i] = new ValueRequirement(Integer.toString(i), ComputationTargetSpecification.NULL); } final DependencyNodeFunction function = DependencyNodeFunctionImpl.of("Test", EmptyFunctionParameters.INSTANCE); final DependencyNode a = DependencyNodeImpl.of(function, ComputationTargetSpecification.NULL, new ValueSpecification[] {v[0], v[1], v[2] }, new ValueSpecification[0], new DependencyNode[0]); final DependencyNode b = DependencyNodeImpl.of(function, ComputationTargetSpecification.NULL, new ValueSpecification[] {v[3] }, new ValueSpecification[] {v[2] }, new DependencyNode[] {a }); final DependencyNode c = DependencyNodeImpl.of(function, ComputationTargetSpecification.NULL, new ValueSpecification[] {v[4] }, new ValueSpecification[] {v[1], v[3] }, new DependencyNode[] {a, b }); final DependencyGraph graphA = new DependencyGraphImpl("Test", Collections.singleton(c), 3, ImmutableMap.of(v[0], Collections.singleton(r[0]), v[4], Collections.singleton(r[4]))); final DependencyGraph graphB = DependencyGraphImpl.removeUnnecessaryValues(graphA); assertEquals(graphB, graphA); } }