diff options
author | Thomas Watson | 2016-02-15 20:12:19 +0000 |
---|---|---|
committer | Thomas Watson | 2016-02-15 21:44:56 +0000 |
commit | 33c7f42010a0bd10d01fb0eaf3c7a6db43e64b74 (patch) | |
tree | 5dc71e66731c6bcbf69c1db9e6b643aabe066516 /bundles/org.eclipse.osgi.tests | |
parent | d2699fce816bd389b5c17cd54aa20a44f63f1473 (diff) | |
download | rt.equinox.framework-33c7f42010a0bd10d01fb0eaf3c7a6db43e64b74.tar.gz rt.equinox.framework-33c7f42010a0bd10d01fb0eaf3c7a6db43e64b74.tar.xz rt.equinox.framework-33c7f42010a0bd10d01fb0eaf3c7a6db43e64b74.zip |
Bug 487842 - Unable to acquire state change lock for the module whenI20160216-1400I20160216-0800
starting a bundle
Change-Id: Ibc7c58aaf610cbd7b0c2aaef154559e2ed7134c4
Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
Diffstat (limited to 'bundles/org.eclipse.osgi.tests')
2 files changed, 110 insertions, 0 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java index c1a7acb6f..efb7eda25 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java @@ -12,6 +12,7 @@ package org.eclipse.osgi.tests.container; import static java.util.jar.Attributes.Name.MANIFEST_VERSION; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import java.io.*; import java.util.*; @@ -2366,6 +2367,101 @@ public class TestModuleContainer extends AbstractTest { } } + @Test + public void testStartOnResolve() throws BundleException, IOException { + DummyContainerAdaptor adaptor = createDummyAdaptor(); + ModuleContainer container = adaptor.getContainer(); + + // install the system.bundle + Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container); + ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true); + Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException()); + systemBundle.start(); + + // install a bunch of modules + Map<String, String> manifest = new HashMap<String, String>(); + List<Module> modules = new ArrayList<Module>(); + for (int i = 0; i < 5; i++) { + manifest.clear(); + manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); + manifest.put(Constants.BUNDLE_SYMBOLICNAME, "module." + i); + manifest.put(Constants.IMPORT_PACKAGE, "export"); + Module module = installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container); + try { + module.start(); + fail("expected a bundle exception."); + } catch (BundleException e) { + // do nothing + } + modules.add(module); + } + + manifest.clear(); + manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); + manifest.put(Constants.BUNDLE_SYMBOLICNAME, "exporter"); + manifest.put(Constants.EXPORT_PACKAGE, "export"); + installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container); + + report = container.resolve(Collections.<Module> emptySet(), false); + Assert.assertNull("Found a error.", report.getResolutionException()); + + for (Module module : modules) { + Assert.assertEquals("Wrong state.", State.ACTIVE, module.getState()); + } + } + + @Test + public void testResolveDeadlock() throws BundleException, IOException, InterruptedException { + DummyContainerAdaptor adaptor = createDummyAdaptor(); + ModuleContainer container = adaptor.getContainer(); + + // install the system.bundle + Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container); + ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true); + Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException()); + systemBundle.start(); + + // install a bunch of modules + Map<String, String> manifest = new HashMap<String, String>(); + List<Module> modules = new ArrayList<Module>(); + for (int i = 0; i < 5; i++) { + manifest.clear(); + manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2"); + manifest.put(Constants.BUNDLE_SYMBOLICNAME, "module." + i); + modules.add(installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container)); + } + adaptor.setSlowdownEvents(true); + final ConcurrentLinkedQueue<BundleException> startErrors = new ConcurrentLinkedQueue<BundleException>(); + final ExecutorService executor = Executors.newFixedThreadPool(10); + try { + for (final Module module : modules) { + + executor.execute(new Runnable() { + + @Override + public void run() { + try { + module.start(); + } catch (BundleException e) { + startErrors.offer(e); + e.printStackTrace(); + } + } + }); + } + } finally { + executor.shutdown(); + executor.awaitTermination(5, TimeUnit.MINUTES); + systemBundle.stop(); + } + + Assert.assertNull("Found a error.", startErrors.poll()); + List<DummyContainerEvent> events = adaptor.getDatabase().getContainerEvents(); + for (DummyContainerEvent event : events) { + Assert.assertNotEquals("Found an error.", ContainerEvent.ERROR, event.type); + } + } + private static void assertWires(List<ModuleWire> required, List<ModuleWire>... provided) { for (ModuleWire requiredWire : required) { for (List<ModuleWire> providedList : provided) { diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyContainerAdaptor.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyContainerAdaptor.java index 645004e35..630b2f43e 100644 --- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyContainerAdaptor.java +++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyContainerAdaptor.java @@ -13,6 +13,7 @@ package org.eclipse.osgi.tests.container.dummys; import java.util.EnumSet; import java.util.Map; import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.osgi.container.*; import org.eclipse.osgi.container.Module.Settings; import org.eclipse.osgi.service.debug.DebugOptions; @@ -22,6 +23,7 @@ import org.osgi.framework.FrameworkListener; import org.osgi.framework.hooks.resolver.ResolverHookFactory; public class DummyContainerAdaptor extends ModuleContainerAdaptor { + private AtomicBoolean slowdownEvents = new AtomicBoolean(false); private final ModuleCollisionHook collisionHook; private final Map<String, String> configuration; private final DummyModuleDatabase moduleDatabase; @@ -86,8 +88,20 @@ public class DummyContainerAdaptor extends ModuleContainerAdaptor { return moduleDatabase; } + public void setSlowdownEvents(boolean slowdown) { + slowdownEvents.set(slowdown); + } + @Override public void publishModuleEvent(ModuleEvent type, Module module, Module origin) { + if (type == ModuleEvent.STARTING && slowdownEvents.get()) { + try { + Thread.sleep(6000); + } catch (InterruptedException e) { + // ignore + Thread.currentThread().interrupt(); + } + } moduleDatabase.addEvent(new DummyModuleEvent(module, type, module.getState())); } |