public void testConcurrentAddRemove() throws Exception {
ComponentMetadataRepo componentMetadataRepo = new ComponentMetadataRepo();
componentMetadataRepo.initialize(Collections.emptyList(), InterceptorChainTest.class.getClassLoader());
AsyncInterceptorChainImpl asyncInterceptorChain =
new AsyncInterceptorChainImpl(componentMetadataRepo);
GlobalConfiguration globalConfiguration = new GlobalConfigurationBuilder().build();
InterceptorChain ic = new InterceptorChain();
TestingUtil.inject(ic, asyncInterceptorChain);
ic.setFirstInChain(new DummyCallInterceptor());
ic.addInterceptor(new DummyActivationInterceptor(), 1);
CyclicBarrier barrier = new CyclicBarrier(4);
List<Future<Void>> futures = new ArrayList<Future<Void>>(2);
futures.add(fork(new InterceptorChainUpdater(ic, barrier, new DummyCacheMgmtInterceptor())));
futures.add(fork(new InterceptorChainUpdater(ic, barrier, new DummyDistCacheWriterInterceptor())));
futures.add(fork(new InterceptorChainUpdater(ic, barrier, new DummyInvalidationInterceptor())));
barrier.await();
barrier.await();
log.debug("All threads finished, let's shutdown the executor and check whether any exceptions were reported");
for (Future<Void> future : futures) future.get();
assert ic.containsInterceptorType(DummyCallInterceptor.class);
assert ic.containsInterceptorType(DummyActivationInterceptor.class);
assert ic.containsInterceptorType(DummyCacheMgmtInterceptor.class);
assert ic.containsInterceptorType(DummyDistCacheWriterInterceptor.class);
assert ic.containsInterceptorType(DummyInvalidationInterceptor.class);
assert ic.asList().size() == 5 : "Resulting interceptor chain was actually " + ic.asList();
}