package org.infinispan.integrationtests.cdijcache.interceptor;
import static org.infinispan.integrationtests.cdijcache.Deployments.baseDeployment;
import static org.testng.Assert.fail;
import java.lang.invoke.MethodHandles;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Inject;
import org.infinispan.cdi.embedded.test.DefaultTestEmbeddedCacheManagerProducer;
import org.infinispan.integrationtests.cdijcache.interceptor.config.Config;
import org.infinispan.integrationtests.cdijcache.interceptor.service.CacheResultService;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.testng.Arquillian;
import org.jboss.shrinkwrap.api.Archive;
import org.testng.annotations.Test;
/**
* Checks if methods annotated with <code>@CacheResult</code> might be safely accessed with multiple threads.
*
* @author Sebastian Laskawiec
* @see javax.cache.annotation.CacheResult
*/
@Test(groups = "functional", testName = "cdi.test.interceptor.CacheResultInterceptorConcurrencyTest", description = "https://issues.jboss.org/browse/ISPN-4563")
public class CacheResultInterceptorConcurrencyTest extends Arquillian {
@Deployment
public static Archive<?> deployment() {
return baseDeployment()
.addClass(CacheResultInterceptorConcurrencyTest.class)
.addClass(CacheResultService.class)
.addPackage(Config.class.getPackage())
.addClass(DefaultTestEmbeddedCacheManagerProducer.class)
.addAsWebInfResource(MethodHandles.lookup().lookupClass().getResource("/beans-for-not-managed-domain.xml"), "beans.xml");
}
@Inject
private CacheResultService service;
@Inject
private BeanManager beanManager;
private static final int NUMBER_OF_THREADS = 100;
public void testConcurrentAccessToCache() throws Exception {
final AtomicReference<Exception> throwableHolder = new AtomicReference<>();
final CyclicBarrier counter = new CyclicBarrier(NUMBER_OF_THREADS);
ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_THREADS);
for(int i = 0; i < NUMBER_OF_THREADS; ++i) {
executorService.execute(new Runnable() {
@Override
public void run() {
try {
counter.await();
service.cacheResult("Thread " + Thread.currentThread().getId());
} catch (Exception t) {
throwableHolder.set(t);
}
}
});
}
executorService.shutdown();
if(!executorService.awaitTermination(10, TimeUnit.HOURS)) {
fail("Executor didn't finish all his tasks!");
}
if(throwableHolder.get() != null) {
throw throwableHolder.get();
}
}
}