/**
* Copyright (C) 2014 - 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.assertEquals;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicInteger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.Test;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.opengamma.util.test.TestGroup;
/**
* Test that checks the behaviour of the Guava cache {@code get()} method.
* <p>
* We're relying on the fact that a call to {@code get()} will block if a value is already being
* calculated for the specified key. It's common sense behaviour, but it isn't explicitly documented.
* <p>
* If this test fails it's probably because Guava has been updated and the behaviour has changed (which
* seems highly unlikely).
*/
@Test(groups = TestGroup.UNIT)
public class GuavaCacheTest {
private static final Logger s_logger = LoggerFactory.getLogger(GuavaCacheTest.class);
@Test
public void getMethodBlocksDuringCalculation() throws ExecutionException {
final Cache<String, Integer> cache = CacheBuilder.newBuilder().concurrencyLevel(4).maximumSize(50).build();
final CalculationTask task = new CalculationTask();
new Thread(new Runnable() {
@Override
public void run() {
try {
s_logger.info("getting value on other thread");
cache.get("a", task);
s_logger.info("got value on other thread");
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}, "other").start();
s_logger.info("getting value on main thread");
cache.get("a", task);
s_logger.info("got value on main thread");
assertEquals(1, task.getCalculationCount());
}
private static class CalculationTask implements Callable<Integer> {
private AtomicInteger _executionCount = new AtomicInteger(0);
@Override
public Integer call() throws Exception {
s_logger.info("calculating value on thread " + Thread.currentThread());
_executionCount.getAndIncrement();
Thread.sleep(3000);
return 0;
}
private int getCalculationCount() {
return _executionCount.get();
}
}
}