volatile ExecutorService executor;
@Test
public void test_ConcurrentManagedServicesWithConcurrentConfigurations()
{
final Log log = new Log(bundleContext);
log.info("starting test_ConcurrentManagedServicesWithConcurrentConfigurations");
// Use at least 10 parallel threads, or take all available processors if the running host contains more than 10 processors.
int parallelism = Math.max(10, Runtime.getRuntime().availableProcessors());
final ConfigurationAdmin ca = getConfigurationAdmin();
final ExecutorService executor = Executors.newFixedThreadPool(parallelism);
try
{
int pidCounter = 0;
long timeStamp = System.currentTimeMillis();
for (int loop = 0; loop < 1000; loop++)
{
log.debug("loop#%d -------------------------", (loop + 1));
final CountDownLatch managedServiceUpdated = new CountDownLatch(MANAGED_SERVICES);
final CountDownLatch managedServiceUnregistered = new CountDownLatch(MANAGED_SERVICES);
// Create some ManagedServices concurrently
log.info("registering aspects concurrently");
final CopyOnWriteArrayList<ServiceRegistration> managedServices = new CopyOnWriteArrayList<ServiceRegistration>();
final CopyOnWriteArrayList<Configuration> confs = new CopyOnWriteArrayList<Configuration>();
for (int i = 0; i < MANAGED_SERVICES; i++)
{
final String pid = "pid." + i + "-" + (pidCounter++);
executor.execute(new Runnable()
{
public void run()
{
Hashtable props = new Hashtable();
props.put(Constants.SERVICE_PID, pid);
ServiceRegistration sr = bundleContext.registerService(
ManagedService.class.getName(),
new TestManagedService(managedServiceUpdated), props);
managedServices.add(sr);
try
{
Configuration c = ca.getConfiguration(pid, null);
c.update(new Hashtable()
{
{
put("foo", "bar");
}
});
confs.add(c);
}
catch (IOException e)
{
log.error("could not create pid %s", e, pid);
return;
}
}
});
}
if (!managedServiceUpdated.await(MAXWAIT, TimeUnit.MILLISECONDS))
{
TestCase.fail("Detected errors logged during concurrent test");
break;
}
log.info("all managed services updated");
// Unregister managed services concurrently
log.info("unregistering services concurrently");
for (final ServiceRegistration sr : managedServices)
{
executor.execute(new Runnable()
{
public void run()
{
sr.unregister();
managedServiceUnregistered.countDown();
}
});
}
// Unregister configuration concurrently
log.info("unregistering configuration concurrently");
for (final Configuration c : confs)
{
c.delete();
}
// Wait until managed services have been unregistered
if (!managedServiceUnregistered.await(MAXWAIT, TimeUnit.MILLISECONDS))
{
TestCase.fail("Managed Servives could not be unregistered timely");
break;
}
if (log.errorsLogged())
{
TestCase.fail("Detected errors logged during concurrent test");
break;
}
log.info("finished one test loop");
if ((loop + 1) % 100 == 0)
{
long duration = System.currentTimeMillis() - timeStamp;
System.out.println(String.format("Performed %d tests in %d ms.", (loop + 1), duration));
timeStamp = System.currentTimeMillis();
}
}
}
catch (Throwable t)
{
Assert.fail("Test failed: " + t.getMessage());
}
finally
{
shutdown(executor);
log.close();
}
}