/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.engine.function; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotSame; import static org.testng.AssertJUnit.assertSame; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import org.testng.annotations.Test; import org.threeten.bp.Instant; import com.opengamma.engine.ComputationTarget; import com.opengamma.engine.DefaultComputationTargetResolver; import com.opengamma.engine.target.ComputationTargetType; import com.opengamma.engine.value.ValueRequirement; import com.opengamma.engine.value.ValueSpecification; import com.opengamma.util.test.TestGroup; import com.opengamma.util.test.TestLifecycle; @Test(groups = TestGroup.UNIT) public class CachingFunctionRepositoryCompilerTest { private static class MockFunction extends AbstractFunction { private final AtomicInteger _compileCount = new AtomicInteger(); private final Long _validBefore; private final Long _validAfter; private MockFunction(final String name, final Long validBefore, final Long validAfter) { setUniqueId(name); _validBefore = validBefore; _validAfter = validAfter; } @Override public CompiledFunctionDefinition compile(FunctionCompilationContext context, Instant atInstant) { _compileCount.incrementAndGet(); final AbstractFunction.AbstractCompiledFunction compiled = new AbstractFunction.AbstractCompiledFunction() { @Override public ComputationTargetType getTargetType() { return null; } @Override public Set<ValueSpecification> getResults(FunctionCompilationContext context, ComputationTarget target) { return null; } @Override public Set<ValueRequirement> getRequirements(FunctionCompilationContext context, ComputationTarget target, final ValueRequirement desiredValue) { return null; } @Override public FunctionInvoker getFunctionInvoker() { return null; } @Override public boolean canApplyTo(FunctionCompilationContext context, ComputationTarget target) { return false; } }; if (_validBefore != null) { compiled.setEarliestInvocationTime(atInstant.minusMillis(_validBefore)); } if (_validAfter != null) { compiled.setLatestInvocationTime(atInstant.plusMillis(_validAfter)); } return compiled; } @Override public String getShortName() { return getUniqueId(); } } public void testCompileFunction() { TestLifecycle.begin(); try { final InMemoryFunctionRepository functions = new InMemoryFunctionRepository(); final MockFunction alwaysValid = new MockFunction("always valid", null, null); final MockFunction validUntil = new MockFunction("valid until", null, 30L); final MockFunction validFrom = new MockFunction("valid from", 30L, null); final MockFunction validWithin = new MockFunction("valid within", 30L, 30L); functions.addFunction(alwaysValid); functions.addFunction(validUntil); functions.addFunction(validFrom); functions.addFunction(validWithin); final CachingFunctionRepositoryCompiler compiler = new CachingFunctionRepositoryCompiler(); final FunctionCompilationContext context = new FunctionCompilationContext(); context.setRawComputationTargetResolver(new DefaultComputationTargetResolver()); final CompiledFunctionService cfs = new CompiledFunctionService(functions, compiler, context); TestLifecycle.register(cfs); cfs.initialize(); final Instant timestamp = Instant.now(); // Everything compiled once final CompiledFunctionRepository compiledFunctionsNow = cfs.compileFunctionRepository(timestamp); assertSame(alwaysValid, compiledFunctionsNow.getDefinition(alwaysValid.getUniqueId()).getFunctionDefinition()); assertSame(validUntil, compiledFunctionsNow.getDefinition(validUntil.getUniqueId()).getFunctionDefinition()); assertSame(validFrom, compiledFunctionsNow.getDefinition(validFrom.getUniqueId()).getFunctionDefinition()); assertSame(validWithin, compiledFunctionsNow.getDefinition(validWithin.getUniqueId()).getFunctionDefinition()); assertEquals(1, alwaysValid._compileCount.get()); assertEquals(1, validUntil._compileCount.get()); assertEquals(1, validFrom._compileCount.get()); assertEquals(1, validWithin._compileCount.get()); // All previously compiled ones still valid, so should use the "previous" cache final CompiledFunctionRepository compiledFunctionsAheadWithin = cfs.compileFunctionRepository(timestamp.plusMillis(29L)); assertSame(compiledFunctionsNow, compiledFunctionsAheadWithin); assertEquals(1, alwaysValid._compileCount.get()); assertEquals(1, validUntil._compileCount.get()); assertEquals(1, validFrom._compileCount.get()); assertEquals(1, validWithin._compileCount.get()); // All previously compiled ones still valid, so should use the "previous" cache final CompiledFunctionRepository compiledFunctionsAheadLimit = cfs.compileFunctionRepository(timestamp.plusMillis(30L)); assertSame(compiledFunctionsNow, compiledFunctionsAheadLimit); assertEquals(1, alwaysValid._compileCount.get()); assertEquals(1, validUntil._compileCount.get()); assertEquals(1, validFrom._compileCount.get()); assertEquals(1, validWithin._compileCount.get()); // Some functions to be recompiled, others from the "previous" cache final CompiledFunctionRepository compiledFunctionsAheadBeyond = cfs.compileFunctionRepository(timestamp.plusMillis(31L)); assertNotSame(compiledFunctionsNow, compiledFunctionsAheadBeyond); assertSame(compiledFunctionsNow.getDefinition(alwaysValid.getUniqueId()), compiledFunctionsAheadBeyond.getDefinition(alwaysValid.getUniqueId())); assertNotSame(compiledFunctionsNow.getDefinition(validUntil.getUniqueId()), compiledFunctionsAheadBeyond.getDefinition(validUntil.getUniqueId())); assertSame(compiledFunctionsNow.getDefinition(validFrom.getUniqueId()), compiledFunctionsAheadBeyond.getDefinition(validFrom.getUniqueId())); assertNotSame(compiledFunctionsNow.getDefinition(validWithin.getUniqueId()), compiledFunctionsAheadBeyond.getDefinition(validWithin.getUniqueId())); assertEquals(1, alwaysValid._compileCount.get()); assertEquals(2, validUntil._compileCount.get()); assertEquals(1, validFrom._compileCount.get()); assertEquals(2, validWithin._compileCount.get()); // All previously compiled functions, so should use the "ahead" cache final CompiledFunctionRepository compiledFunctionsBeforeWithin = cfs.compileFunctionRepository(timestamp.minusMillis(30L)); assertSame(compiledFunctionsNow, compiledFunctionsBeforeWithin); assertEquals(1, alwaysValid._compileCount.get()); assertEquals(2, validUntil._compileCount.get()); assertEquals(1, validFrom._compileCount.get()); assertEquals(2, validWithin._compileCount.get()); // Some functions to be recompiled, others from the "ahead" cache final CompiledFunctionRepository compiledFunctionsBeforeBeyond = cfs.compileFunctionRepository(timestamp.minusMillis(31L)); assertNotSame(compiledFunctionsNow, compiledFunctionsBeforeBeyond); assertSame(compiledFunctionsNow.getDefinition(alwaysValid.getUniqueId()), compiledFunctionsBeforeBeyond.getDefinition(alwaysValid.getUniqueId())); assertSame(compiledFunctionsNow.getDefinition(validUntil.getUniqueId()), compiledFunctionsBeforeBeyond.getDefinition(validUntil.getUniqueId())); assertNotSame(compiledFunctionsNow.getDefinition(validFrom.getUniqueId()), compiledFunctionsBeforeBeyond.getDefinition(validFrom.getUniqueId())); assertNotSame(compiledFunctionsNow.getDefinition(validWithin.getUniqueId()), compiledFunctionsBeforeBeyond.getDefinition(validWithin.getUniqueId())); assertEquals(1, alwaysValid._compileCount.get()); assertEquals(2, validUntil._compileCount.get()); assertEquals(2, validFrom._compileCount.get()); assertEquals(3, validWithin._compileCount.get()); } finally { TestLifecycle.end(); } } }