/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.marketdata.manipulator; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.testng.annotations.Test; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.opengamma.core.marketdatasnapshot.YieldCurveKey; import com.opengamma.engine.ComputationTarget; import com.opengamma.engine.ComputationTargetResolver; import com.opengamma.engine.ComputationTargetSpecification; import com.opengamma.engine.depgraph.DependencyGraph; import com.opengamma.engine.depgraph.builder.TestDependencyGraphBuilder; import com.opengamma.engine.depgraph.impl.DependencyGraphImpl; import com.opengamma.engine.function.EmptyFunctionParameters; import com.opengamma.engine.function.FunctionParameters; import com.opengamma.engine.target.ComputationTargetType; import com.opengamma.engine.target.MockComputationTargetResolver; import com.opengamma.engine.test.MockFunction; import com.opengamma.engine.value.ValueProperties; import com.opengamma.engine.value.ValuePropertyNames; import com.opengamma.engine.value.ValueRequirementNames; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.id.VersionCorrection; import com.opengamma.util.money.Currency; import com.opengamma.util.test.TestGroup; @Test(groups = TestGroup.UNIT) public class MarketDataSelectionGraphManipulatorTest { private final ComputationTargetResolver.AtVersionCorrection _resolver = MockComputationTargetResolver.resolved().atVersionCorrection(VersionCorrection.LATEST); @Test(expectedExceptions = IllegalArgumentException.class) public void testNullSelectorConstructionFails() { new MarketDataSelectionGraphManipulator(null, createEmptyViewCalcManipulations()); } @Test(expectedExceptions = IllegalArgumentException.class) public void testNullViewCalcSelectorConstructionFails() { new MarketDataSelectionGraphManipulator(createYieldCurveSelector(Currency.USD, "Forward3M"), null); } @Test public void testInvocationWithEmptyGraphsGivesEmptyResults() { final MarketDataSelectionGraphManipulator manipulator = createNoOpManipulator(); final Map<DistinctMarketDataSelector, Set<ValueSpecification>> result = new HashMap<>(); manipulator.modifyDependencyGraph(new TestDependencyGraphBuilder("testGraph").buildGraph(), _resolver, result); assertEquals(result.isEmpty(), true); } @Test public void testNoOpSelectorDoesNothingToGraph() { final MarketDataSelectionGraphManipulator manipulator = createNoOpManipulator(); final DependencyGraph graph = createSimpleGraphWithMarketDataNodes(); final Set<ValueSpecification> originalOutputSpecifications = DependencyGraphImpl.getAllOutputSpecifications(graph); final Map<DistinctMarketDataSelector, Set<ValueSpecification>> result = new HashMap<>(); final DependencyGraph newGraph = manipulator.modifyDependencyGraph(graph, _resolver, result); assertEquals(result.isEmpty(), true); assertEquals(DependencyGraphImpl.getAllOutputSpecifications(newGraph), originalOutputSpecifications); } @Test public void testYieldCurveSelectorAltersGraph() { final MarketDataSelectionGraphManipulator manipulator = new MarketDataSelectionGraphManipulator(createYieldCurveSelector(Currency.USD, "Forward3M"), createEmptyViewCalcManipulations()); final DependencyGraph graph = createSimpleGraphWithMarketDataNodes(); final Set<ValueSpecification> originalOutputSpecifications = DependencyGraphImpl.getAllOutputSpecifications(graph); final Map<DistinctMarketDataSelector, Set<ValueSpecification>> result = new HashMap<>(); final DependencyGraph newGraph = manipulator.modifyDependencyGraph(graph, _resolver, result); checkNodeHasBeenAddedToGraph(newGraph, originalOutputSpecifications, result); } @Test public void testSpecificYieldCurveSelectorAltersNamedGraph() { final DistinctMarketDataSelector yieldCurveSelector = createYieldCurveSelector(Currency.USD, "Forward3M"); final Map<String, Map<DistinctMarketDataSelector, FunctionParameters>> specificManipulators = new HashMap<>(); specificManipulators.put("graph", createYieldCurveSelectorAndParams(Currency.USD, "Forward3M")); final MarketDataSelectionGraphManipulator manipulator = new MarketDataSelectionGraphManipulator(NoOpMarketDataSelector.getInstance(), specificManipulators); final DependencyGraph graph1 = createNamedDependencyGraph("graph"); final Set<ValueSpecification> originalOutputSpecifications1 = DependencyGraphImpl.getAllOutputSpecifications(graph1); final Map<DistinctMarketDataSelector, Set<ValueSpecification>> result1 = new HashMap<>(); final DependencyGraph newGraph1 = manipulator.modifyDependencyGraph(graph1, _resolver, result1); checkNodeHasBeenAddedToGraph(newGraph1, originalOutputSpecifications1, result1); assertEquals(result1.size(), 1); // Selector is the underlying, not composite assertTrue(result1.containsKey(yieldCurveSelector)); } @Test public void testSpecificYieldCurveSelectorDoesNotAlterDifferentNamedGraph() { final Map<String, Map<DistinctMarketDataSelector, FunctionParameters>> specificManipulators = new HashMap<>(); specificManipulators.put("graph-to-find", createYieldCurveSelectorAndParams(Currency.USD, "Forward3M")); final MarketDataSelectionGraphManipulator manipulator = new MarketDataSelectionGraphManipulator(NoOpMarketDataSelector.getInstance(), specificManipulators); final DependencyGraph graph = createNamedDependencyGraph("not-the-graph-you-are-looking-for"); final Set<ValueSpecification> originalOutputSpecifications2 = DependencyGraphImpl.getAllOutputSpecifications(graph); final Map<DistinctMarketDataSelector, Set<ValueSpecification>> result = new HashMap<>(); final DependencyGraph newGraph = manipulator.modifyDependencyGraph(graph, _resolver, result); assertTrue(result.isEmpty()); assertEquals(DependencyGraphImpl.getAllOutputSpecifications(newGraph), originalOutputSpecifications2); } private ImmutableMap<DistinctMarketDataSelector, FunctionParameters> createYieldCurveSelectorAndParams(Currency currency, String curveType) { return ImmutableMap.<DistinctMarketDataSelector, FunctionParameters>of(createYieldCurveSelector(currency, curveType), EmptyFunctionParameters.INSTANCE); } @Test public void testCompositeSelectorReturnsUnderlyingSelector() { final MarketDataSelector yieldCurveSelector = createYieldCurveSelector(Currency.USD, "Forward3M"); final MarketDataSelectionGraphManipulator manipulator = new MarketDataSelectionGraphManipulator(CompositeMarketDataSelector.of(yieldCurveSelector), createEmptyViewCalcManipulations()); final DependencyGraph graph = createSimpleGraphWithMarketDataNodes(); final Set<ValueSpecification> originalOutputSpecifications = DependencyGraphImpl.getAllOutputSpecifications(graph); final Map<DistinctMarketDataSelector, Set<ValueSpecification>> result = new HashMap<>(); final DependencyGraph newGraph = manipulator.modifyDependencyGraph(graph, _resolver, result); checkNodeHasBeenAddedToGraph(newGraph, originalOutputSpecifications, result); assertEquals(result.size(), 1); // Selector is the underlying, not composite assertEquals(result.containsKey(yieldCurveSelector), true); } @Test public void noSelectors() { Set<MarketDataSelector> noSelectors = Collections.emptySet(); MarketDataSelectionGraphManipulator manipulator = new MarketDataSelectionGraphManipulator(CompositeMarketDataSelector.of(noSelectors), createEmptyViewCalcManipulations()); DependencyGraph graph = createSimpleGraphWithMarketDataNodes(); Map<DistinctMarketDataSelector, Set<ValueSpecification>> result = new HashMap<>(); manipulator.modifyDependencyGraph(graph, _resolver, result); assertTrue(result.isEmpty()); } private DistinctMarketDataSelector createYieldCurveSelector(Currency currency, String curveType) { return YieldCurveSelector.of(YieldCurveKey.of(currency, curveType)); } private void checkNodeHasBeenAddedToGraph(DependencyGraph graph, Set<ValueSpecification> originalOutputSpecifications, Map<DistinctMarketDataSelector, Set<ValueSpecification>> result) { assertFalse(result.isEmpty()); ValueSpecification originalValueSpec = Iterables.getOnlyElement(originalOutputSpecifications); Set<ValueSpecification> outputSpecifications = new HashSet<>(DependencyGraphImpl.getAllOutputSpecifications(graph)); assertEquals(outputSpecifications.size(), 2); outputSpecifications.removeAll(originalOutputSpecifications); ValueSpecification additionalSpec = Iterables.getOnlyElement(outputSpecifications); assertEquals(additionalSpec.getValueName(), originalValueSpec.getValueName()); assertEquals(additionalSpec.getTargetSpecification(), originalValueSpec.getTargetSpecification()); ValueProperties expectedProps = originalValueSpec.getProperties().copy().withoutAny(ValuePropertyNames.FUNCTION).with(ValuePropertyNames.FUNCTION, "someFunctionStructureManipulator").get(); assertEquals(additionalSpec.getProperties(), expectedProps); } private DependencyGraph createSimpleGraphWithMarketDataNodes() { return createNamedDependencyGraph("testGraph"); } private DependencyGraph createNamedDependencyGraph(String name) { final TestDependencyGraphBuilder gb = new TestDependencyGraphBuilder(name); final ComputationTargetSpecification targetSpecification = new ComputationTargetSpecification(ComputationTargetType.CURRENCY, Currency.USD.getUniqueId()); final ComputationTarget target = new ComputationTarget(targetSpecification, Currency.USD); gb.addNode(new MockFunction(target)).addOutput( new ValueSpecification(ValueRequirementNames.YIELD_CURVE, targetSpecification, ValueProperties.builder().with(ValuePropertyNames.CURVE, "Forward3M") .with(ValuePropertyNames.FUNCTION, "someFunction").get())); return gb.buildGraph(); } private Map<String, Map<DistinctMarketDataSelector, FunctionParameters>> createEmptyViewCalcManipulations() { return new HashMap<>(); } private MarketDataSelectionGraphManipulator createNoOpManipulator() { return new MarketDataSelectionGraphManipulator(NoOpMarketDataSelector.getInstance(), createEmptyViewCalcManipulations()); } }