/**
* Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.engine.depgraph.ambiguity;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import org.testng.annotations.Test;
import org.threeten.bp.Instant;
import com.opengamma.core.position.Portfolio;
import com.opengamma.core.position.PositionSource;
import com.opengamma.core.position.impl.MockPositionSource;
import com.opengamma.core.position.impl.SimplePortfolio;
import com.opengamma.core.security.SecuritySource;
import com.opengamma.core.value.MarketDataRequirementNames;
import com.opengamma.engine.ComputationTarget;
import com.opengamma.engine.ComputationTargetResolver;
import com.opengamma.engine.ComputationTargetSpecification;
import com.opengamma.engine.DefaultComputationTargetResolver;
import com.opengamma.engine.InMemorySecuritySource;
import com.opengamma.engine.function.CachingFunctionRepositoryCompiler;
import com.opengamma.engine.function.CompiledFunctionService;
import com.opengamma.engine.function.FunctionCompilationContext;
import com.opengamma.engine.function.FunctionRepositoryCompiler;
import com.opengamma.engine.function.InMemoryFunctionRepository;
import com.opengamma.engine.function.resolver.DefaultFunctionResolver;
import com.opengamma.engine.function.resolver.FunctionResolver;
import com.opengamma.engine.marketdata.availability.DefaultMarketDataAvailabilityProvider;
import com.opengamma.engine.marketdata.availability.MarketDataAvailabilityProvider;
import com.opengamma.engine.marketdata.availability.OptimisticMarketDataAvailabilityFilter;
import com.opengamma.engine.test.MockFunction;
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.engine.view.ViewCalculationConfiguration;
import com.opengamma.engine.view.ViewDefinition;
import com.opengamma.id.UniqueId;
import com.opengamma.id.VersionCorrection;
import com.opengamma.livedata.UserPrincipal;
import com.opengamma.util.test.TestGroup;
import com.opengamma.util.test.TestLifecycle;
/**
* Tests the {@link SimpleRequirementAmbiguityChecker} class.
*/
@Test(groups = TestGroup.UNIT)
public class SimpleRequirementAmbiguityCheckerTest {
private MockFunction mockFunctionX() {
final MockFunction function = new MockFunction("X", ComputationTarget.NULL);
function.addRequirement(new ValueRequirement(MarketDataRequirementNames.MARKET_VALUE, ComputationTargetSpecification.NULL));
function.addResult(new ValueSpecification("X", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "X").get()), 42d);
return function;
}
private MockFunction mockFunctionA1() {
final MockFunction function = new MockFunction("A1", ComputationTarget.NULL);
function.addRequirement(new ValueRequirement("X", ComputationTargetSpecification.NULL));
function.addResult(new ValueSpecification("A", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "A1").get()), 42d);
return function;
}
private MockFunction mockFunctionA2() {
final MockFunction function = new MockFunction("A2", ComputationTarget.NULL);
function.addRequirement(new ValueRequirement("X", ComputationTargetSpecification.NULL));
function.addResult(new ValueSpecification("A", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "A2").get()), 42d);
return function;
}
private MockFunction mockFunctionY() {
final MockFunction function = new MockFunction("Y", ComputationTarget.NULL);
function.addRequirement(new ValueRequirement("A", ComputationTargetSpecification.NULL));
function.addResult(new ValueSpecification("Y", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "Y").get()), 42d);
return function;
}
private MockFunction mockFunctionZ1() {
final MockFunction function = new MockFunction("Z1", ComputationTarget.NULL) {
@Override
public Set<ValueRequirement> getAdditionalRequirements(final FunctionCompilationContext context, final ComputationTarget target, final Set<ValueSpecification> inputs,
final Set<ValueSpecification> outputs) {
return Collections.singleton(new ValueRequirement("X", ComputationTargetSpecification.NULL));
}
};
function.addRequirement(new ValueRequirement("A", ComputationTargetSpecification.NULL));
function.addResult(new ValueSpecification("Z", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "Z1").get()), 42d);
return function;
}
private MockFunction mockFunctionZ2() {
final MockFunction function = new MockFunction("Z2", ComputationTarget.NULL) {
@Override
public Set<ValueRequirement> getAdditionalRequirements(final FunctionCompilationContext context, final ComputationTarget target, final Set<ValueSpecification> inputs,
final Set<ValueSpecification> outputs) {
return Collections.singleton(new ValueRequirement("A", ComputationTargetSpecification.NULL));
}
};
function.addRequirement(new ValueRequirement("X", ComputationTargetSpecification.NULL));
function.addResult(new ValueSpecification("Z", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "Z2").get()), 42d);
return function;
}
private Portfolio portfolio() {
final SimplePortfolio portfolio = new SimplePortfolio("Foo");
portfolio.setUniqueId(UniqueId.of("Portfolio", "Test", "0"));
return portfolio;
}
private SecuritySource securities() {
final InMemorySecuritySource securities = new InMemorySecuritySource();
return securities;
}
private PositionSource positions() {
final MockPositionSource positions = new MockPositionSource();
positions.addPortfolio(portfolio());
return positions;
}
private ComputationTargetResolver targetResolver() {
return new DefaultComputationTargetResolver(securities(), positions());
}
private FunctionResolver functionResolver(final FunctionCompilationContext compilationContext) {
final InMemoryFunctionRepository functionRepository = new InMemoryFunctionRepository();
functionRepository.addFunction(mockFunctionX());
functionRepository.addFunction(mockFunctionA1());
functionRepository.addFunction(mockFunctionA2());
functionRepository.addFunction(mockFunctionY());
functionRepository.addFunction(mockFunctionZ1());
functionRepository.addFunction(mockFunctionZ2());
final FunctionRepositoryCompiler compiler = new CachingFunctionRepositoryCompiler();
final CompiledFunctionService cfs = new CompiledFunctionService(functionRepository, compiler, compilationContext);
TestLifecycle.register(cfs);
cfs.initialize();
return new DefaultFunctionResolver(cfs);
}
private AmbiguityCheckerContext context() {
final MarketDataAvailabilityProvider mdap = new OptimisticMarketDataAvailabilityFilter().withProvider(new DefaultMarketDataAvailabilityProvider());
final FunctionCompilationContext compilationContext = new FunctionCompilationContext();
compilationContext.setRawComputationTargetResolver(targetResolver());
final FunctionResolver resolver = functionResolver(compilationContext);
return new AmbiguityCheckerContext(mdap, compilationContext, resolver, null);
}
public void testPortfolioResolution() {
TestLifecycle.begin();
try {
ViewDefinition viewDefinition = new ViewDefinition("Test 1", UniqueId.of("Portfolio", "Test"), UserPrincipal.getTestUser());
ViewCalculationConfiguration calcConfig = new ViewCalculationConfiguration(viewDefinition, "Default");
SimpleRequirementAmbiguityChecker checker = new SimpleRequirementAmbiguityChecker(context(), Instant.now(), VersionCorrection.LATEST, calcConfig);
// Resolved the portfolio
assertEquals(checker.getCompilationContext().getPortfolio().getUniqueId(), portfolio().getUniqueId());
viewDefinition = new ViewDefinition("Test 2", UniqueId.of("Portfolio", "Missing", "1"), UserPrincipal.getTestUser());
calcConfig = new ViewCalculationConfiguration(viewDefinition, "Default");
checker = new SimpleRequirementAmbiguityChecker(context(), Instant.now(), VersionCorrection.LATEST, calcConfig);
// Portfolio id not found
assertEquals(checker.getCompilationContext().getPortfolio(), null);
viewDefinition = new ViewDefinition("Test 3", UserPrincipal.getTestUser());
calcConfig = new ViewCalculationConfiguration(viewDefinition, "Default");
checker = new SimpleRequirementAmbiguityChecker(context(), Instant.now(), VersionCorrection.LATEST, calcConfig);
// No portfolio requested
assertEquals(checker.getCompilationContext().getPortfolio(), null);
} finally {
TestLifecycle.end();
}
}
public void testDirectMarketDataRequest() {
TestLifecycle.begin();
try {
final SimpleRequirementAmbiguityChecker checker = new SimpleRequirementAmbiguityChecker(context(), Instant.now(), VersionCorrection.LATEST);
final ValueRequirement requirement = new ValueRequirement(MarketDataRequirementNames.MARKET_VALUE, ComputationTargetSpecification.NULL);
final FullRequirementResolution resolved = checker.resolve(requirement);
assertNotNull(resolved);
assertEquals(resolved.getRequirement(), requirement);
assertTrue(resolved.isResolved());
assertFalse(resolved.isAmbiguous());
assertEquals(resolved.getResolutions().size(), 1);
Collection<RequirementResolution> requirementResolutions = resolved.getResolutions().iterator().next();
assertEquals(requirementResolutions.size(), 1);
final RequirementResolution requirementResolution = requirementResolutions.iterator().next();
assertEquals(requirementResolution.getSpecification(),
new ValueSpecification(MarketDataRequirementNames.MARKET_VALUE, ComputationTargetSpecification.NULL, ValueProperties
.with(ValuePropertyNames.FUNCTION, "MarketDataSourcingFunction").get()));
} finally {
TestLifecycle.end();
}
}
public void testAliasedMarketDataRequest() {
TestLifecycle.begin();
try {
final SimpleRequirementAmbiguityChecker checker = new SimpleRequirementAmbiguityChecker(context(), Instant.now(), VersionCorrection.LATEST);
final ValueRequirement requirement = new ValueRequirement("Market_FooBar", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "Foobar")
.with("X", "Y").get());
final FullRequirementResolution resolved = checker.resolve(requirement);
assertNotNull(resolved);
assertEquals(resolved.getRequirement(), requirement);
assertTrue(resolved.isResolved());
assertFalse(resolved.isAmbiguous());
assertEquals(resolved.getResolutions().size(), 1);
Collection<RequirementResolution> requirementResolutions = resolved.getResolutions().iterator().next();
assertEquals(requirementResolutions.size(), 1);
final RequirementResolution requirementResolution = requirementResolutions.iterator().next();
assertEquals(requirementResolution.getSpecification(),
new ValueSpecification("Market_FooBar", ComputationTargetSpecification.NULL, ValueProperties.with(ValuePropertyNames.FUNCTION, "Foobar").with("X", "Y").get()));
} finally {
TestLifecycle.end();
}
}
public void testUnresolved() {
TestLifecycle.begin();
try {
final SimpleRequirementAmbiguityChecker checker = new SimpleRequirementAmbiguityChecker(context(), Instant.now(), VersionCorrection.LATEST);
final ValueRequirement requirement = new ValueRequirement("Fail", ComputationTargetSpecification.NULL);
final FullRequirementResolution resolved = checker.resolve(requirement);
assertNotNull(resolved);
assertFalse(resolved.isResolved());
assertFalse(resolved.isAmbiguous());
assertFalse(resolved.isDeeplyAmbiguous());
} finally {
TestLifecycle.end();
}
}
public void testUnambigousGraph() {
TestLifecycle.begin();
try {
final SimpleRequirementAmbiguityChecker checker = new SimpleRequirementAmbiguityChecker(context(), Instant.now(), VersionCorrection.LATEST);
final ValueRequirement requirement = new ValueRequirement("X", ComputationTargetSpecification.NULL);
final FullRequirementResolution resolved = checker.resolve(requirement);
assertNotNull(resolved);
assertTrue(resolved.isResolved());
assertFalse(resolved.isAmbiguous());
assertFalse(resolved.isDeeplyAmbiguous());
assertEquals(resolved.getResolutions().size(), 1);
Collection<RequirementResolution> requirementResolutions = resolved.getResolutions().iterator().next();
assertEquals(requirementResolutions.size(), 1);
final RequirementResolution requirementResolution = requirementResolutions.iterator().next();
assertEquals(requirementResolution.getSpecification().getFunctionUniqueId(), "X");
} finally {
TestLifecycle.end();
}
}
public void testAmbigiousFunctionSelection() {
TestLifecycle.begin();
try {
final SimpleRequirementAmbiguityChecker checker = new SimpleRequirementAmbiguityChecker(context(), Instant.now(), VersionCorrection.LATEST);
final ValueRequirement requirement = new ValueRequirement("A", ComputationTargetSpecification.NULL);
final FullRequirementResolution resolved = checker.resolve(requirement);
assertNotNull(resolved);
assertTrue(resolved.isResolved());
assertTrue(resolved.isAmbiguous());
assertTrue(resolved.isDeeplyAmbiguous());
assertEquals(resolved.getResolutions().size(), 1);
Collection<RequirementResolution> requirementResolutions = resolved.getResolutions().iterator().next();
assertEquals(requirementResolutions.size(), 2);
} finally {
TestLifecycle.end();
}
}
public void testAmbigousInputSelection() {
TestLifecycle.begin();
try {
final SimpleRequirementAmbiguityChecker checker = new SimpleRequirementAmbiguityChecker(context(), Instant.now(), VersionCorrection.LATEST);
final ValueRequirement requirement = new ValueRequirement("Y", ComputationTargetSpecification.NULL);
final FullRequirementResolution resolved = checker.resolve(requirement);
assertNotNull(resolved);
assertTrue(resolved.isResolved());
assertFalse(resolved.isAmbiguous());
assertTrue(resolved.isDeeplyAmbiguous());
assertEquals(resolved.getResolutions().size(), 1);
Collection<RequirementResolution> requirementResolutions = resolved.getResolutions().iterator().next();
assertEquals(requirementResolutions.size(), 1);
} finally {
TestLifecycle.end();
}
}
public void testAmbiguousAdditionalRequirements() {
TestLifecycle.begin();
try {
final SimpleRequirementAmbiguityChecker checker = new SimpleRequirementAmbiguityChecker(context(), Instant.now(), VersionCorrection.LATEST);
final ValueRequirement requirement = new ValueRequirement("Z", ComputationTargetSpecification.NULL);
final FullRequirementResolution resolved = checker.resolve(requirement);
assertNotNull(resolved);
assertTrue(resolved.isResolved());
assertTrue(resolved.isAmbiguous());
assertTrue(resolved.isDeeplyAmbiguous());
assertEquals(resolved.getResolutions().size(), 1);
Collection<RequirementResolution> requirementResolutions = resolved.getResolutions().iterator().next();
assertEquals(requirementResolutions.size(), 2);
for (RequirementResolution requirementResolution : requirementResolutions) {
final Collection<FullRequirementResolution> inputs = requirementResolution.getInputs();
assertEquals(inputs.size(), 2);
boolean ambiguous = false;
for (FullRequirementResolution input : inputs) {
ambiguous |= input.isAmbiguous();
}
assertTrue(ambiguous);
}
} finally {
TestLifecycle.end();
}
}
// TODO: Test function exclusion groups
}