Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2016-01-05 14:55:46 +0000
committerThomas Watson2016-01-05 15:29:48 +0000
commite1aa6950b8be7c9e76b2df623d09eb8e25d1ef97 (patch)
tree2ca3b6daf3d5a8980a82444bec927b21041afbc4 /bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container
parentde43c1f9a0b333cfb78be0dc5a1844dcae29e733 (diff)
downloadrt.equinox.framework-e1aa6950b8be7c9e76b2df623d09eb8e25d1ef97.tar.gz
rt.equinox.framework-e1aa6950b8be7c9e76b2df623d09eb8e25d1ef97.tar.xz
rt.equinox.framework-e1aa6950b8be7c9e76b2df623d09eb8e25d1ef97.zip
Bug 485217 - Update resolver implementation and default to using batch
resolves with a timeout
Diffstat (limited to 'bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container')
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AbstractTest.java8
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/TestModuleContainer.java90
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/dummys/DummyContainerAdaptor.java17
3 files changed, 112 insertions, 3 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AbstractTest.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AbstractTest.java
index f49b085a0..846d8b97a 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AbstractTest.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/container/AbstractTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2015 IBM Corporation and others.
+ * Copyright (c) 2013, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -86,6 +86,12 @@ public abstract class AbstractTest {
return container.install(system, location, builder, null);
}
+ protected Module installDummyModule(Map<String, String> manifest, String location, ModuleContainer container) throws BundleException {
+ ModuleRevisionBuilder builder = OSGiManifestBuilderFactory.createBuilder(manifest);
+ Module system = container.getModule(0);
+ return container.install(system, location, builder, null);
+ }
+
protected void registerService(Class<?> clazz, Object service) {
serviceRegistrations.add(getSystemBundleContext().registerService(clazz.getName(), service, null));
}
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 5af409b98..a45d0825d 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2015 IBM Corporation and others.
+ * Copyright (c) 2013, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -21,6 +21,7 @@ import org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent;
import org.eclipse.osgi.container.builders.OSGiManifestBuilderFactory;
import org.eclipse.osgi.container.namespaces.EclipsePlatformNamespace;
import org.eclipse.osgi.internal.debug.Debug;
+import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
import org.eclipse.osgi.report.resolution.ResolutionReport;
import org.eclipse.osgi.tests.container.dummys.*;
import org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyContainerEvent;
@@ -1748,6 +1749,93 @@ public class TestModuleContainer extends AbstractTest {
}
@Test
+ public void testUsesTimeout() throws BundleException {
+ // Always want to go to zero threads when idle
+ int coreThreads = 0;
+ // use the number of processors - 1 because we use the current thread when rejected
+ int maxThreads = Math.max(Runtime.getRuntime().availableProcessors() - 1, 1);
+ // idle timeout; make it short to get rid of threads quickly after resolve
+ int idleTimeout = 5;
+ // use sync queue to force thread creation
+ BlockingQueue<Runnable> queue = new SynchronousQueue<Runnable>();
+ // try to name the threads with useful name
+ ThreadFactory threadFactory = new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r, "Resolver thread - UNIT TEST"); //$NON-NLS-1$
+ t.setDaemon(true);
+ return t;
+ }
+ };
+ // use a rejection policy that simply runs the task in the current thread once the max threads is reached
+ RejectedExecutionHandler rejectHandler = new RejectedExecutionHandler() {
+ @Override
+ public void rejectedExecution(Runnable r, ThreadPoolExecutor exe) {
+ r.run();
+ }
+ };
+ ExecutorService executor = new ThreadPoolExecutor(coreThreads, maxThreads, idleTimeout, TimeUnit.SECONDS, queue, threadFactory, rejectHandler);
+
+ Map<String, String> configuration = new HashMap<String, String>();
+ configuration.put(EquinoxConfiguration.PROP_RESOLVER_BATCH_TIMEOUT, "5000");
+ Map<String, String> debugOpts = Collections.singletonMap("org.eclipse.osgi/resolver/uses", "true");
+ DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(false), configuration, new DummyResolverHookFactory(), new DummyDebugOptions(debugOpts));
+ adaptor.setResolverExecutor(executor);
+ ModuleContainer container = adaptor.getContainer();
+ for (int i = 1; i <= 1000; i++) {
+ for (Map<String, String> manifest : getUsesTimeoutManifests("test" + i)) {
+ installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
+ }
+ }
+ ResolutionReport report = container.resolve(container.getModules(), true);
+ Assert.assertNull("Found resolution errors.", report.getResolutionException());
+ for (Module module : container.getModules()) {
+ Assert.assertEquals("Wrong state of module: " + module, State.RESOLVED, module.getState());
+ }
+ executor.shutdown();
+ System.gc();
+ System.gc();
+ System.gc();
+ }
+
+ private List<Map<String, String>> getUsesTimeoutManifests(String prefix) {
+ List<Map<String, String>> result = new ArrayList<Map<String, String>>();
+ // x1 bundle
+ Map<String, String> x1Manifest = new HashMap<String, String>();
+ x1Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ x1Manifest.put(Constants.BUNDLE_SYMBOLICNAME, prefix + ".x1");
+ x1Manifest.put(Constants.EXPORT_PACKAGE, prefix + ".a; version=1.0; uses:=" + prefix + ".b");
+ x1Manifest.put(Constants.IMPORT_PACKAGE, prefix + ".b; version=\"[1.1,1.2)\"");
+ result.add(x1Manifest);
+ // x2 bundle
+ Map<String, String> x2Manifest = new HashMap<String, String>();
+ x2Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ x2Manifest.put(Constants.BUNDLE_SYMBOLICNAME, prefix + ".x2");
+ x2Manifest.put(Constants.EXPORT_PACKAGE, prefix + ".a; version=1.1; uses:=" + prefix + ".b");
+ x2Manifest.put(Constants.IMPORT_PACKAGE, prefix + ".b; version=\"[1.0,1.1)\"");
+ result.add(x2Manifest);
+ // y1 bundle
+ Map<String, String> y1Manifest = new HashMap<String, String>();
+ y1Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ y1Manifest.put(Constants.BUNDLE_SYMBOLICNAME, prefix + ".y1");
+ y1Manifest.put(Constants.EXPORT_PACKAGE, prefix + ".b; version=1.0");
+ result.add(y1Manifest);
+ // y1 bundle
+ Map<String, String> y2Manifest = new HashMap<String, String>();
+ y2Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ y2Manifest.put(Constants.BUNDLE_SYMBOLICNAME, prefix + ".y2");
+ y2Manifest.put(Constants.EXPORT_PACKAGE, prefix + ".b; version=1.1");
+ result.add(y2Manifest);
+ // z1 bundle
+ Map<String, String> z1Manifest = new HashMap<String, String>();
+ z1Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
+ z1Manifest.put(Constants.BUNDLE_SYMBOLICNAME, prefix + ".z1");
+ z1Manifest.put(Constants.IMPORT_PACKAGE, prefix + ".a, " + prefix + ".b");
+ result.add(z1Manifest);
+ return result;
+ }
+
+ @Test
public void testOptionalSubstituted() throws BundleException, IOException {
DummyContainerAdaptor adaptor = createDummyAdaptor();
ModuleContainer container = adaptor.getContainer();
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 4d91c7db6..645004e35 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2015 IBM Corporation and others.
+ * Copyright (c) 2012, 2016 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -12,6 +12,7 @@ package org.eclipse.osgi.tests.container.dummys;
import java.util.EnumSet;
import java.util.Map;
+import java.util.concurrent.Executor;
import org.eclipse.osgi.container.*;
import org.eclipse.osgi.container.Module.Settings;
import org.eclipse.osgi.service.debug.DebugOptions;
@@ -27,6 +28,7 @@ public class DummyContainerAdaptor extends ModuleContainerAdaptor {
private final ModuleContainer container;
private final ResolverHookFactory resolverHookFactory;
private final DebugOptions debugOptions;
+ private volatile Executor resolverExecutor;
public DummyContainerAdaptor(ModuleCollisionHook collisionHook, Map<String, String> configuration) {
this(collisionHook, configuration, new DummyResolverHookFactory());
@@ -94,4 +96,17 @@ public class DummyContainerAdaptor extends ModuleContainerAdaptor {
return this.debugOptions;
}
+ public void setResolverExecutor(Executor executor) {
+ this.resolverExecutor = executor;
+ }
+
+ @Override
+ public Executor getResolverExecutor() {
+ Executor current = this.resolverExecutor;
+ if (current != null) {
+ return current;
+ }
+ return super.getResolverExecutor();
+ }
+
}

Back to the top