/** * Copyright (C) 2013 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.sesame.cache; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; import javax.inject.Provider; import org.testng.annotations.Test; import org.threeten.bp.ZoneId; import org.threeten.bp.ZonedDateTime; import com.google.common.cache.Cache; import com.google.common.collect.Lists; import com.google.common.util.concurrent.Callables; import com.opengamma.id.ExternalId; import com.opengamma.id.ExternalIdBundle; import com.opengamma.id.ObjectId; import com.opengamma.id.VersionCorrection; import com.opengamma.sesame.EngineTestUtils; import com.opengamma.sesame.config.EngineUtils; import com.opengamma.sesame.graph.FunctionId; import com.opengamma.util.test.TestGroup; @Test(groups = TestGroup.UNIT) public class CacheInvalidatorTest { private static final MethodInvocationKey METHOD_KEY_1 = methodKey(FunctionId.of(1), new ArrayList<>(), "subList", new Object[]{1, 2}); private static final MethodInvocationKey METHOD_KEY_2 = methodKey(FunctionId.of(1), new LinkedList<>(), "set", new Object[]{3, "foo"}); private static final MethodInvocationKey METHOD_KEY_3 = methodKey(FunctionId.of(1), new ArrayList<>(), "size", null); private static final Callable<Object> CALLABLE = Callables.returning(null); private final Cache<Object, Object> _cache = EngineTestUtils.createCacheProvider().get(); private void populateCache() { _cache.invalidateAll(); _cache.put(METHOD_KEY_1, new FutureTask<>(CALLABLE)); _cache.put(METHOD_KEY_2, new FutureTask<>(CALLABLE)); _cache.put(METHOD_KEY_3, new FutureTask<>(CALLABLE)); } private static MethodInvocationKey methodKey(FunctionId functionId, Object receiver, String methodName, Object[] args) { Method method = EngineUtils.getMethod(receiver.getClass(), methodName); return new MethodInvocationKey(functionId, method, args); } /** * test the invalidator in isolation */ @Test public void registerAndInvalidate() { // doesn't matter what this is as long as it doesn't change ZonedDateTime valuationTime = ZonedDateTime.now(); final LinkedList<MethodInvocationKey> keys = Lists.newLinkedList(); Provider<Collection<MethodInvocationKey>> provider = new Provider<Collection<MethodInvocationKey>>() { @Override public Collection<MethodInvocationKey> get() { return keys; } }; _cache.invalidateAll(); CacheInvalidator invalidator = new DefaultCacheInvalidator(provider, _cache); // this makes sure the market data factory is set before adding any data invalidator.invalidate( valuationTime, VersionCorrection.LATEST, Collections.<ExternalId>emptyList(), Collections.<ObjectId>emptyList()); // doesn't matter what the methods are ObjectId abc2 = ObjectId.of("abc", "2"); ExternalId abc1 = ExternalId.of("abc", "1"); ExternalId bnd1 = ExternalId.of("bnd", "1"); ExternalId bnd2 = ExternalId.of("bnd", "2"); keys.add(METHOD_KEY_1); invalidator.register(abc1); keys.add(METHOD_KEY_2); invalidator.register(abc2); keys.removeLast(); invalidator.register(ExternalIdBundle.of(bnd1, bnd2)); populateCache(); invalidator.invalidate( valuationTime, VersionCorrection.LATEST, Lists.newArrayList(abc1), Collections.<ObjectId>emptyList()); assertNull(_cache.getIfPresent(METHOD_KEY_1)); assertNotNull(_cache.getIfPresent(METHOD_KEY_2)); assertNotNull(_cache.getIfPresent(METHOD_KEY_3)); populateCache(); invalidator.invalidate( valuationTime, VersionCorrection.LATEST, Collections.<ExternalId>emptyList(), Lists.newArrayList(abc2)); assertNull(_cache.getIfPresent(METHOD_KEY_1)); assertNull(_cache.getIfPresent(METHOD_KEY_2)); assertNotNull(_cache.getIfPresent(METHOD_KEY_3)); populateCache(); invalidator.invalidate( valuationTime, VersionCorrection.LATEST, Lists.newArrayList(bnd1), Collections.<ObjectId>emptyList()); assertNull(_cache.getIfPresent(METHOD_KEY_1)); assertNotNull(_cache.getIfPresent(METHOD_KEY_2)); assertNotNull(_cache.getIfPresent(METHOD_KEY_3)); populateCache(); invalidator.invalidate( valuationTime, VersionCorrection.LATEST, Lists.newArrayList(bnd2), Collections.<ObjectId>emptyList()); assertNull(_cache.getIfPresent(METHOD_KEY_1)); assertNotNull(_cache.getIfPresent(METHOD_KEY_2)); assertNotNull(_cache.getIfPresent(METHOD_KEY_3)); } @Test public void valuationTime() { ZonedDateTime valuationTime = ZonedDateTime.of(2011, 3, 8, 2, 18, 0, 0, ZoneId.of("Europe/London")); final LinkedList<MethodInvocationKey> keys = Lists.newLinkedList(); Provider<Collection<MethodInvocationKey>> provider = new Provider<Collection<MethodInvocationKey>>() { @Override public Collection<MethodInvocationKey> get() { return keys; } }; populateCache(); CacheInvalidator invalidator = new DefaultCacheInvalidator(provider, _cache); // this key is only valid at the instant it was calculated (i.e. 1 cycle) keys.add(METHOD_KEY_1); invalidator.register(new ValuationTimeCacheEntry.ValidAtCalculationInstant(valuationTime)); keys.clear(); // this key is valid for the whole day on which is was calculated keys.add(METHOD_KEY_2); invalidator.register(new ValuationTimeCacheEntry.ValidOnCalculationDay(valuationTime.toLocalDate())); invalidator.invalidate( valuationTime, VersionCorrection.LATEST, Collections.<ExternalId>emptyList(), Collections.<ObjectId>emptyList()); assertNotNull(_cache.getIfPresent(METHOD_KEY_1)); assertNotNull(_cache.getIfPresent(METHOD_KEY_2)); invalidator.invalidate( valuationTime.plusHours(1), VersionCorrection.LATEST, Collections.<ExternalId>emptyList(), Collections.<ObjectId>emptyList()); assertNull(_cache.getIfPresent(METHOD_KEY_1)); assertNotNull(_cache.getIfPresent(METHOD_KEY_2)); invalidator.invalidate( valuationTime.plusDays(1), VersionCorrection.LATEST, Collections.<ExternalId>emptyList(), Collections.<ObjectId>emptyList()); assertNull(_cache.getIfPresent(METHOD_KEY_2)); } }