1 /*******************************************************************************
2  * Copyright (c) 2013, 2017 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.osgi.tests.container;
15 
16 import static java.util.jar.Attributes.Name.MANIFEST_VERSION;
17 import static org.junit.Assert.assertEquals;
18 import static org.junit.Assert.assertNotNull;
19 import static org.junit.Assert.assertNull;
20 import static org.junit.Assert.assertTrue;
21 import static org.junit.Assert.fail;
22 
23 import java.io.ByteArrayInputStream;
24 import java.io.ByteArrayOutputStream;
25 import java.io.DataInputStream;
26 import java.io.DataOutputStream;
27 import java.io.IOException;
28 import java.io.PrintStream;
29 import java.nio.charset.StandardCharsets;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.Dictionary;
35 import java.util.Enumeration;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Set;
42 import java.util.concurrent.ArrayBlockingQueue;
43 import java.util.concurrent.BlockingQueue;
44 import java.util.concurrent.ConcurrentLinkedQueue;
45 import java.util.concurrent.CountDownLatch;
46 import java.util.concurrent.ExecutorService;
47 import java.util.concurrent.Executors;
48 import java.util.concurrent.RejectedExecutionHandler;
49 import java.util.concurrent.ScheduledExecutorService;
50 import java.util.concurrent.ScheduledThreadPoolExecutor;
51 import java.util.concurrent.SynchronousQueue;
52 import java.util.concurrent.ThreadFactory;
53 import java.util.concurrent.ThreadPoolExecutor;
54 import java.util.concurrent.TimeUnit;
55 import java.util.concurrent.TimeoutException;
56 import java.util.concurrent.atomic.AtomicInteger;
57 import java.util.concurrent.atomic.AtomicReference;
58 import java.util.jar.Attributes;
59 import java.util.jar.Manifest;
60 import org.eclipse.osgi.container.Module;
61 import org.eclipse.osgi.container.Module.StartOptions;
62 import org.eclipse.osgi.container.Module.State;
63 import org.eclipse.osgi.container.ModuleCapability;
64 import org.eclipse.osgi.container.ModuleContainer;
65 import org.eclipse.osgi.container.ModuleContainerAdaptor.ContainerEvent;
66 import org.eclipse.osgi.container.ModuleContainerAdaptor.ModuleEvent;
67 import org.eclipse.osgi.container.ModuleRequirement;
68 import org.eclipse.osgi.container.ModuleRevision;
69 import org.eclipse.osgi.container.ModuleRevisionBuilder;
70 import org.eclipse.osgi.container.ModuleWire;
71 import org.eclipse.osgi.container.ModuleWiring;
72 import org.eclipse.osgi.container.builders.OSGiManifestBuilderFactory;
73 import org.eclipse.osgi.container.namespaces.EclipsePlatformNamespace;
74 import org.eclipse.osgi.container.namespaces.EquinoxModuleDataNamespace;
75 import org.eclipse.osgi.framework.util.ThreadInfoReport;
76 import org.eclipse.osgi.internal.debug.Debug;
77 import org.eclipse.osgi.internal.framework.EquinoxConfiguration;
78 import org.eclipse.osgi.report.resolution.ResolutionReport;
79 import org.eclipse.osgi.tests.container.dummys.DummyCollisionHook;
80 import org.eclipse.osgi.tests.container.dummys.DummyContainerAdaptor;
81 import org.eclipse.osgi.tests.container.dummys.DummyDebugOptions;
82 import org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase;
83 import org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyContainerEvent;
84 import org.eclipse.osgi.tests.container.dummys.DummyModuleDatabase.DummyModuleEvent;
85 import org.eclipse.osgi.tests.container.dummys.DummyResolverHook;
86 import org.eclipse.osgi.tests.container.dummys.DummyResolverHookFactory;
87 import org.eclipse.osgi.util.ManifestElement;
88 import org.junit.Assert;
89 import org.junit.Test;
90 import org.osgi.framework.Bundle;
91 import org.osgi.framework.BundleContext;
92 import org.osgi.framework.BundleException;
93 import org.osgi.framework.BundleReference;
94 import org.osgi.framework.Constants;
95 import org.osgi.framework.Version;
96 import org.osgi.framework.hooks.resolver.ResolverHook;
97 import org.osgi.framework.hooks.resolver.ResolverHookFactory;
98 import org.osgi.framework.namespace.BundleNamespace;
99 import org.osgi.framework.namespace.ExecutionEnvironmentNamespace;
100 import org.osgi.framework.namespace.HostNamespace;
101 import org.osgi.framework.namespace.IdentityNamespace;
102 import org.osgi.framework.namespace.PackageNamespace;
103 import org.osgi.framework.wiring.BundleCapability;
104 import org.osgi.framework.wiring.BundleRequirement;
105 import org.osgi.framework.wiring.BundleRevision;
106 import org.osgi.framework.wiring.BundleWire;
107 import org.osgi.resource.Namespace;
108 
109 public class TestModuleContainer extends AbstractTest {
110 
111 	private static DummyModuleDatabase resolvedModuleDatabase;
112 
setupModuleDatabase()113 	private void setupModuleDatabase() throws BundleException {
114 		if (resolvedModuleDatabase == null) {
115 			resolvedModuleDatabase = getDatabase();
116 		}
117 	}
118 
119 	private static final String OSGI_OS = "osgi.os";
120 	private static final String OSGI_WS = "osgi.ws";
121 	private static final String OSGI_ARCH = "osgi.arch";
122 
getDatabase()123 	private DummyModuleDatabase getDatabase() throws BundleException {
124 		BundleContext context = ((BundleReference) getClass().getClassLoader()).getBundle().getBundleContext();
125 
126 		DummyContainerAdaptor adaptor = createDummyAdaptor();
127 		final ModuleContainer container = adaptor.getContainer();
128 
129 		Bundle systemBundle = context.getBundle(0);
130 		String extraPackages = context.getProperty(Constants.FRAMEWORK_SYSTEMPACKAGES);
131 		String extraCapabilities = context.getProperty(Constants.FRAMEWORK_SYSTEMCAPABILITIES);
132 		extraCapabilities = (extraCapabilities == null ? "" : (extraCapabilities + ", "));
133 		String osName = context.getProperty(OSGI_OS);
134 		String wsName = context.getProperty(OSGI_WS);
135 		String archName = context.getProperty(OSGI_ARCH);
136 		extraCapabilities += EclipsePlatformNamespace.ECLIPSE_PLATFORM_NAMESPACE + "; " + OSGI_OS + "=" + osName + "; " + OSGI_WS + "=" + wsName + "; " + OSGI_ARCH + "=" + archName;
137 		ModuleRevisionBuilder systembuilder = OSGiManifestBuilderFactory.createBuilder(asMap(systemBundle.getHeaders("")), Constants.SYSTEM_BUNDLE_SYMBOLICNAME, extraPackages, extraCapabilities);
138 		container.install(null, systemBundle.getLocation(), systembuilder, null);
139 
140 		final List<Throwable> installErrors = new ArrayList<>(0);
141 		// just trying to pound the container with a bunch of installs
142 		ExecutorService executor = Executors.newFixedThreadPool(10);
143 		Bundle[] bundles = context.getBundles();
144 		for (final Bundle bundle : bundles) {
145 			if (bundle.getBundleId() == 0)
146 				continue;
147 			executor.execute(new Runnable() {
148 				@Override
149 				public void run() {
150 					try {
151 						ModuleRevisionBuilder builder = OSGiManifestBuilderFactory.createBuilder(asMap(bundle.getHeaders("")));
152 						container.install(null, bundle.getLocation(), builder, null);
153 					} catch (Throwable t) {
154 						t.printStackTrace();
155 						synchronized (installErrors) {
156 							installErrors.add(t);
157 						}
158 					}
159 				}
160 			});
161 		}
162 		executor.shutdown();
163 		try {
164 			executor.awaitTermination(2, TimeUnit.MINUTES);
165 		} catch (InterruptedException e) {
166 			e.printStackTrace();
167 		}
168 		synchronized (installErrors) {
169 			if (!installErrors.isEmpty()) {
170 				Assert.assertNull("Unexpected install errors.", installErrors);
171 			}
172 		}
173 		container.resolve(new ArrayList<Module>(), false);
174 		List<Module> modules = container.getModules();
175 		for (Module module : modules) {
176 			if (module.getCurrentRevision().getWiring() == null) {
177 				System.out.println("Could not resolve module: " + module.getCurrentRevision());
178 			}
179 		}
180 		return adaptor.getDatabase();
181 	}
182 
asMap(Dictionary<K, V> dictionary)183 	static <K, V> Map<K, V> asMap(Dictionary<K, V> dictionary) {
184 		Map<K, V> map = new HashMap<>();
185 		for (Enumeration<K> eKeys = dictionary.keys(); eKeys.hasMoreElements();) {
186 			K key = eKeys.nextElement();
187 			V value = dictionary.get(key);
188 			map.put(key, value);
189 		}
190 		return map;
191 	}
192 
193 	@Test
testModuleContainerCreate()194 	public void testModuleContainerCreate() {
195 		createDummyAdaptor();
196 	}
197 
198 	// Disabled @Test
testResolveInstallBundles()199 	public void testResolveInstallBundles() throws BundleException, IOException {
200 		setupModuleDatabase();
201 		DummyContainerAdaptor adaptor = createDummyAdaptor();
202 		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
203 		resolvedModuleDatabase.store(new DataOutputStream(bytes), false);
204 		bytes.close();
205 		adaptor.getDatabase().load(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray())));
206 		adaptor.getContainer().resolve(new ArrayList<Module>(), false);
207 	}
208 
209 	// Disabled @Test
testResolveInstallBundles01()210 	public void testResolveInstallBundles01() throws BundleException, IOException {
211 		setupModuleDatabase();
212 		DummyContainerAdaptor adaptor = createDummyAdaptor();
213 		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
214 		resolvedModuleDatabase.store(new DataOutputStream(bytes), false);
215 		bytes.close();
216 		adaptor.getDatabase().load(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray())));
217 		for (int i = 0; i < 50; i++) {
218 			adaptor.getContainer().refresh(adaptor.getContainer().getModules());
219 		}
220 	}
221 
222 	// Disabled @Test
testResolveAlreadyResolvedBundles()223 	public void testResolveAlreadyResolvedBundles() throws BundleException, IOException {
224 		setupModuleDatabase();
225 		DummyContainerAdaptor adaptor = createDummyAdaptor();
226 		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
227 		resolvedModuleDatabase.store(new DataOutputStream(bytes), true);
228 		bytes.close();
229 		adaptor.getDatabase().load(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray())));
230 		adaptor.getContainer().resolve(new ArrayList<Module>(), false);
231 	}
232 
233 	// Disabled @Test
testRefreshSystemBundle()234 	public void testRefreshSystemBundle() throws BundleException, IOException {
235 		setupModuleDatabase();
236 		DummyContainerAdaptor adaptor = createDummyAdaptor();
237 		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
238 		resolvedModuleDatabase.store(new DataOutputStream(bytes), true);
239 		bytes.close();
240 		adaptor.getDatabase().load(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray())));
241 		adaptor.getContainer().refresh(Arrays.asList(adaptor.getContainer().getModule(0)));
242 	}
243 
244 	// disabled @Test
testLoadPerformance()245 	public void testLoadPerformance() throws BundleException, IOException {
246 		setupModuleDatabase();
247 		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
248 		resolvedModuleDatabase.store(new DataOutputStream(bytes), true);
249 		bytes.close();
250 		System.out.println("SIZE: " + bytes.size());
251 		long start = System.currentTimeMillis();
252 		for (int i = 0; i < 1000; i++) {
253 			DummyContainerAdaptor adaptor = createDummyAdaptor();
254 			adaptor.getDatabase().load(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray())));
255 		}
256 		System.out.println("END: " + (System.currentTimeMillis() - start));
257 	}
258 
259 	@Test
testSimpleResolve()260 	public void testSimpleResolve() throws BundleException, IOException {
261 		DummyContainerAdaptor adaptor = createDummyAdaptor();
262 		ModuleContainer container = adaptor.getContainer();
263 
264 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
265 		ModuleRevision systemRevision = systemBundle.getCurrentRevision();
266 		container.resolve(Arrays.asList(systemBundle), true);
267 		ModuleWiring systemWiring = systemRevision.getWiring();
268 		Assert.assertNotNull("system wiring is null", systemWiring);
269 
270 		Module b1 = installDummyModule("b1_v1.MF", "b1", container);
271 		ModuleRevision b1Revision = b1.getCurrentRevision();
272 		container.resolve(Arrays.asList(b1), true);
273 		ModuleWiring b1Wiring = b1Revision.getWiring();
274 		Assert.assertNotNull("b1 wiring is null", b1Wiring);
275 	}
276 
277 	@Test
testSimpleUnResolveable()278 	public void testSimpleUnResolveable() throws BundleException, IOException {
279 		DummyContainerAdaptor adaptor = createDummyAdaptor();
280 		ModuleContainer container = adaptor.getContainer();
281 
282 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
283 		container.resolve(Arrays.asList(systemBundle), true);
284 
285 		Module c7 = installDummyModule("c7_v1.MF", "c7", container);
286 		installDummyModule("c6_v1.MF", "c6", container);
287 
288 		ResolutionReport report = container.resolve(Arrays.asList(c7), true);
289 		Assert.assertNotNull("Expected a resolution exception", report.getResolutionException());
290 
291 		// Should resolve now
292 		installDummyModule("c4_v1.MF", "c4", container);
293 		report = container.resolve(Arrays.asList(c7), true);
294 		Assert.assertNull("Unexpected resoltuion exception", report.getResolutionException());
295 	}
296 
297 	@Test
testMultiHost()298 	public void testMultiHost() throws BundleException, IOException {
299 		DummyContainerAdaptor adaptor = createDummyAdaptor();
300 		ModuleContainer container = adaptor.getContainer();
301 		installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
302 		Module h1v1 = installDummyModule("h1_v1.MF", "h1_v1", container);
303 		Module h1v2 = installDummyModule("h1_v2.MF", "h1_v2", container);
304 		Module f1v1 = installDummyModule("f1_v1.MF", "f1_v1", container);
305 		Module b3 = installDummyModule("b3_v1.MF", "b3_v1", container);
306 		ResolutionReport report = container.resolve(Arrays.asList(h1v1, h1v2, f1v1, b3), true);
307 		Assert.assertNull("Expected no resolution exception.", report.getResolutionException());
308 	}
309 
310 	@Test
testMissingHost()311 	public void testMissingHost() throws BundleException, IOException {
312 		DummyContainerAdaptor adaptor = createDummyAdaptor();
313 		ModuleContainer container = adaptor.getContainer();
314 		installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
315 		Module f1v1 = installDummyModule("f1_v1.MF", "f1_v1", container);
316 		Module b3 = installDummyModule("b3_v1.MF", "b3_v1", container);
317 		ResolutionReport report = container.resolve(Arrays.asList(f1v1, b3), true);
318 		Assert.assertNotNull("Expected a resolution exception.", report.getResolutionException());
319 
320 		Module h1v1 = installDummyModule("h1_v1.MF", "h1_v1", container);
321 		report = container.resolve(Arrays.asList(b3), true);
322 		Assert.assertNull("Expected no resolution exception.", report.getResolutionException());
323 		ModuleWiring wiring = b3.getCurrentRevision().getWiring();
324 		List<ModuleWire> packageWires = wiring.getRequiredModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
325 		Assert.assertEquals("Expected 1 import.", 1, packageWires.size());
326 		ModuleWire pkgWire = packageWires.get(0);
327 		Assert.assertEquals("Wrong host exporter.", pkgWire.getProviderWiring().getRevision(), h1v1.getCurrentRevision());
328 	}
329 
330 	@Test
testFragments01()331 	public void testFragments01() throws BundleException, IOException {
332 		DummyContainerAdaptor adaptor = createDummyAdaptor();
333 		ModuleContainer container = adaptor.getContainer();
334 		Module systemModule = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
335 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
336 		Module h2 = installDummyModule("h2_v1.MF", "h2_v1", container);
337 		Module f2 = installDummyModule("f2_v1.MF", "f2_v1", container);
338 		container.resolve(Arrays.asList(systemModule, c1, h2, f2), true);
339 
340 		ModuleWiring wiring = h2.getCurrentRevision().getWiring();
341 		List<ModuleWire> requiredWires = wiring.getRequiredModuleWires(null);
342 		Assert.assertEquals("Wrong number of required wires.", 3, requiredWires.size());
343 		for (ModuleWire wire : requiredWires) {
344 			ModuleCapability capability = wire.getCapability();
345 			Assert.assertEquals("Wrong namespace.", PackageNamespace.PACKAGE_NAMESPACE, capability.getNamespace());
346 
347 			Assert.assertEquals("Wrong requirer.", h2.getCurrentRevision(), wire.getRequirer());
348 
349 			String pkgName = (String) capability.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
350 			Assert.assertNotNull("No package name.", pkgName);
351 			ModuleRevision expectedReqRevision;
352 			if (pkgName.equals("org.osgi.framework")) {
353 				expectedReqRevision = h2.getCurrentRevision();
354 			} else {
355 				expectedReqRevision = f2.getCurrentRevision();
356 			}
357 			Assert.assertEquals("Wrong requirement revision.", expectedReqRevision, wire.getRequirement().getRevision());
358 		}
359 	}
360 
361 	@Test
testFragments02()362 	public void testFragments02() throws BundleException, IOException {
363 		DummyContainerAdaptor adaptor = createDummyAdaptor();
364 		ModuleContainer container = adaptor.getContainer();
365 		Module systemModule = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
366 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
367 		Module h2 = installDummyModule("h2_v1.MF", "h2_v1", container);
368 
369 		container.resolve(Arrays.asList(systemModule, c1, h2), true);
370 
371 		ModuleWiring h2wiring = h2.getCurrentRevision().getWiring();
372 		Assert.assertNotNull("Wiring is null.", h2wiring);
373 
374 		Module f2 = installDummyModule("f2_v1.MF", "f2_v1", container);
375 		Assert.assertEquals("Wrong state.", State.INSTALLED, f2.getState());
376 		container.resolve(Arrays.asList(f2), false);
377 		Assert.assertNull("Expected to not be able to resolve f2.", f2.getCurrentRevision().getWiring());
378 	}
379 
380 	@Test
testExecutionEnvironment()381 	public void testExecutionEnvironment() throws BundleException, IOException {
382 		DummyContainerAdaptor adaptor = createDummyAdaptor();
383 		ModuleContainer container = adaptor.getContainer();
384 		String extraCapabilities = "osgi.ee; osgi.ee=JavaSE; version:List<Version>=\"1.3, 1.4, 1.5, 1.6, 1.7\"";
385 		installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, null, null, extraCapabilities, container);
386 		container.resolve(null, false);
387 
388 		Module ee1 = installDummyModule("ee1_v1.MF", "ee1", container);
389 		Module ee2 = installDummyModule("ee2_v1.MF", "ee2", container);
390 		Module ee3 = installDummyModule("ee3_v1.MF", "ee3", container);
391 		container.resolve(Arrays.asList(ee1, ee2), true);
392 		container.resolve(Arrays.asList(ee3), false);
393 
394 		ModuleWiring ee1Wiring = ee1.getCurrentRevision().getWiring();
395 		ModuleWiring ee2Wiring = ee2.getCurrentRevision().getWiring();
396 		ModuleWiring ee3Wiring = ee3.getCurrentRevision().getWiring();
397 		Assert.assertNotNull("ee1 is not resolved", ee1Wiring);
398 		Assert.assertNotNull("ee2 is not resolved", ee2Wiring);
399 		Assert.assertNull("ee3 is resolved", ee3Wiring);
400 
401 		// make sure the fragment ee requirement did not get merged into the host
402 		List<ModuleRequirement> ee1Requirements = ee1Wiring.getModuleRequirements(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
403 		Assert.assertEquals("Wrong number of requirements", 1, ee1Requirements.size());
404 		List<ModuleWire> ee1Wires = ee1Wiring.getRequiredModuleWires(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
405 		Assert.assertEquals("Wrong number of wires", 1, ee1Wires.size());
406 
407 		List<ModuleRequirement> ee2Requirements = ee2Wiring.getModuleRequirements(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
408 		Assert.assertEquals("Wrong number of requirements", 1, ee2Requirements.size());
409 		List<ModuleWire> ee2Wires = ee2Wiring.getRequiredModuleWires(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
410 		Assert.assertEquals("Wrong number of wires", 1, ee2Wires.size());
411 	}
412 
413 	@Test
testPlatformFilter01()414 	public void testPlatformFilter01() throws BundleException, IOException {
415 		DummyContainerAdaptor adaptor = createDummyAdaptor();
416 		ModuleContainer container = adaptor.getContainer();
417 		String extraCapabilities = EclipsePlatformNamespace.ECLIPSE_PLATFORM_NAMESPACE + "; osgi.os=foo; osgi.arch=bar";
418 		installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, null, null, extraCapabilities, container);
419 		container.resolve(null, false);
420 
421 		Module platformFilter1 = installDummyModule("platformFilter1_v1.MF", "ee1", container);
422 		container.resolve(Arrays.asList(platformFilter1), true);
423 
424 		ModuleWiring platformFilter1Wiring = platformFilter1.getCurrentRevision().getWiring();
425 		Assert.assertNotNull("platformFilter1 is not resolved", platformFilter1Wiring);
426 	}
427 
428 	@Test
testPlatformFilter02()429 	public void testPlatformFilter02() throws BundleException, IOException {
430 		DummyContainerAdaptor adaptor = createDummyAdaptor();
431 		ModuleContainer container = adaptor.getContainer();
432 		String extraCapabilities = EclipsePlatformNamespace.ECLIPSE_PLATFORM_NAMESPACE + "; osgi.os=baz; osgi.arch=boz";
433 		installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, null, null, extraCapabilities, container);
434 		container.resolve(null, false);
435 
436 		Module platformFilter1 = installDummyModule("platformFilter1_v1.MF", "ee1", container);
437 		container.resolve(Arrays.asList(platformFilter1), false);
438 
439 		ModuleWiring platformFilter1Wiring = platformFilter1.getCurrentRevision().getWiring();
440 		Assert.assertNull("platformFilter1 is resolved", platformFilter1Wiring);
441 	}
442 
443 	@Test
testInstallCollision01()444 	public void testInstallCollision01() throws BundleException, IOException {
445 		DummyContainerAdaptor adaptor = createDummyAdaptor();
446 		ModuleContainer container = adaptor.getContainer();
447 		installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
448 		installDummyModule("b1_v1.MF", "b1_a", container);
449 		try {
450 			installDummyModule("b1_v1.MF", "b1_b", container);
451 			Assert.fail("Expected to fail installation because of a collision.");
452 		} catch (BundleException e) {
453 			// expected
454 			Assert.assertEquals("Wrong exception type.", BundleException.DUPLICATE_BUNDLE_ERROR, e.getType());
455 		}
456 	}
457 
458 	@Test
testInstallCollision02()459 	public void testInstallCollision02() throws BundleException, IOException {
460 		DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(true), Collections.<String, String> emptyMap());
461 		ModuleContainer container = adaptor.getContainer();
462 		installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
463 		installDummyModule("b1_v1.MF", "b1_a", container);
464 		installDummyModule("b1_v1.MF", "b1_b", container);
465 	}
466 
467 	@Test
testUpdateCollision01()468 	public void testUpdateCollision01() throws BundleException, IOException {
469 		DummyContainerAdaptor adaptor = createDummyAdaptor();
470 		ModuleContainer container = adaptor.getContainer();
471 		Module b1_v1 = installDummyModule("b1_v1.MF", "b1_v1", container);
472 		installDummyModule("b1_v2.MF", "b1_v2", container);
473 		try {
474 			container.update(b1_v1, OSGiManifestBuilderFactory.createBuilder(getManifest("b1_v2.MF")), null);
475 			Assert.fail("Expected to fail update because of a collision.");
476 		} catch (BundleException e) {
477 			// expected
478 			Assert.assertEquals("Wrong exception type.", BundleException.DUPLICATE_BUNDLE_ERROR, e.getType());
479 		}
480 	}
481 
482 	@Test
testUpdateCollision02()483 	public void testUpdateCollision02() throws BundleException, IOException {
484 		DummyContainerAdaptor adaptor = createDummyAdaptor();
485 		ModuleContainer container = adaptor.getContainer();
486 		Module b1_v1 = installDummyModule("b1_v1.MF", "b1_v1", container);
487 		try {
488 			container.update(b1_v1, OSGiManifestBuilderFactory.createBuilder(getManifest("b1_v1.MF")), null);
489 		} catch (BundleException e) {
490 			Assert.assertNull("Expected to succeed update to same revision.", e);
491 		}
492 	}
493 
494 	@Test
testUpdateCollision03()495 	public void testUpdateCollision03() throws BundleException, IOException {
496 
497 		DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(true), Collections.<String, String> emptyMap());
498 		ModuleContainer container = adaptor.getContainer();
499 		Module b1_v1 = installDummyModule("b1_v1.MF", "b1_v1", container);
500 		installDummyModule("b1_v2.MF", "b1_v2", container);
501 		try {
502 			container.update(b1_v1, OSGiManifestBuilderFactory.createBuilder(getManifest("b1_v2.MF")), null);
503 		} catch (BundleException e) {
504 			Assert.assertNull("Expected to succeed update to same revision.", e);
505 		}
506 	}
507 
508 	@Test
testSingleton01()509 	public void testSingleton01() throws BundleException, IOException {
510 		DummyContainerAdaptor adaptor = createDummyAdaptor();
511 		ModuleContainer container = adaptor.getContainer();
512 		Module s1 = installDummyModule("singleton1_v1.MF", "s1_v1", container);
513 		Module s2 = installDummyModule("singleton1_v2.MF", "s1_v2", container);
514 		Module s3 = installDummyModule("singleton1_v3.MF", "s1_v3", container);
515 
516 		container.resolve(null, false);
517 
518 		Assert.assertFalse("Singleton v1 is resolved.", Module.RESOLVED_SET.contains(s1.getState()));
519 		Assert.assertFalse("Singleton v2 is resolved.", Module.RESOLVED_SET.contains(s2.getState()));
520 		Assert.assertTrue("Singleton v3 is not resolved.", Module.RESOLVED_SET.contains(s3.getState()));
521 	}
522 
523 	@Test
testSingleton02()524 	public void testSingleton02() throws BundleException, IOException {
525 		ResolverHookFactory resolverHookFactory = new ResolverHookFactory() {
526 
527 			@Override
528 			public ResolverHook begin(Collection<BundleRevision> triggers) {
529 				return new ResolverHook() {
530 
531 					@Override
532 					public void filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates) {
533 						collisionCandidates.clear();
534 					}
535 
536 					@Override
537 					public void filterResolvable(Collection<BundleRevision> candidates) {
538 						// nothing
539 					}
540 
541 					@Override
542 					public void filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates) {
543 						// nothing
544 					}
545 
546 					@Override
547 					public void end() {
548 						// nothing
549 					}
550 				};
551 			}
552 		};
553 		DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(false), Collections.<String, String> emptyMap(), resolverHookFactory);
554 		ModuleContainer container = adaptor.getContainer();
555 
556 		Module s1 = installDummyModule("singleton1_v1.MF", "s1_v1", container);
557 		Module s2 = installDummyModule("singleton1_v2.MF", "s1_v2", container);
558 		Module s3 = installDummyModule("singleton1_v3.MF", "s1_v3", container);
559 
560 		container.resolve(null, false);
561 
562 		Assert.assertTrue("Singleton v1 is not resolved.", Module.RESOLVED_SET.contains(s1.getState()));
563 		Assert.assertTrue("Singleton v2 is not resolved.", Module.RESOLVED_SET.contains(s2.getState()));
564 		Assert.assertTrue("Singleton v3 is not resolved.", Module.RESOLVED_SET.contains(s3.getState()));
565 	}
566 
567 	@Test
testSingleton03()568 	public void testSingleton03() throws BundleException, IOException {
569 		DummyContainerAdaptor adaptor = createDummyAdaptor();
570 		ModuleContainer container = adaptor.getContainer();
571 		Module s1 = installDummyModule("singleton1_v1.MF", "s1_v1", container);
572 		// Resolve s1 first
573 		container.resolve(null, false);
574 		Assert.assertTrue("Singleton v1 is not resolved.", Module.RESOLVED_SET.contains(s1.getState()));
575 
576 		Module s2 = installDummyModule("singleton1_v2.MF", "s1_v2", container);
577 		Module s3 = installDummyModule("singleton1_v3.MF", "s1_v3", container);
578 
579 		container.resolve(Arrays.asList(s2, s3), false);
580 
581 		// Make sure s1 is the only on resolved because it was first resolved
582 		Assert.assertTrue("Singleton v1 is not resolved.", Module.RESOLVED_SET.contains(s1.getState()));
583 		Assert.assertFalse("Singleton v2 is resolved.", Module.RESOLVED_SET.contains(s2.getState()));
584 		Assert.assertFalse("Singleton v3 is resolved.", Module.RESOLVED_SET.contains(s3.getState()));
585 	}
586 
587 	@Test
testSingleton04()588 	public void testSingleton04() throws BundleException, IOException {
589 		final Collection<BundleRevision> disabled = new ArrayList<>();
590 		ResolverHookFactory resolverHookFactory = new ResolverHookFactory() {
591 
592 			@Override
593 			public ResolverHook begin(Collection<BundleRevision> triggers) {
594 				return new ResolverHook() {
595 
596 					@Override
597 					public void filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates) {
598 						// nothing
599 					}
600 
601 					@Override
602 					public void filterResolvable(Collection<BundleRevision> candidates) {
603 						candidates.removeAll(disabled);
604 					}
605 
606 					@Override
607 					public void filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates) {
608 						// nothing
609 					}
610 
611 					@Override
612 					public void end() {
613 						// nothing
614 					}
615 				};
616 			}
617 		};
618 		DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(false), Collections.<String, String> emptyMap(), resolverHookFactory);
619 		ModuleContainer container = adaptor.getContainer();
620 
621 		Module s1_v1 = installDummyModule("singleton1_v1.MF", "s1_v1", container);
622 		Module s1_v2 = installDummyModule("singleton1_v2.MF", "s1_v2", container);
623 		Module s1_v3 = installDummyModule("singleton1_v3.MF", "s1_v3", container);
624 
625 		Module s2_v1 = installDummyModule("singleton2_v1.MF", "s1_v1", container);
626 		Module s2_v2 = installDummyModule("singleton2_v2.MF", "s1_v2", container);
627 		Module s2_v3 = installDummyModule("singleton2_v3.MF", "s1_v3", container);
628 
629 		container.resolve(null, false);
630 
631 		Assert.assertFalse("Singleton v1 is resolved.", Module.RESOLVED_SET.contains(s1_v1.getState()));
632 		Assert.assertFalse("Singleton v2 is resolved.", Module.RESOLVED_SET.contains(s1_v2.getState()));
633 		Assert.assertTrue("Singleton v3 is not resolved.", Module.RESOLVED_SET.contains(s1_v3.getState()));
634 
635 		Assert.assertFalse("client v1 is resolved.", Module.RESOLVED_SET.contains(s2_v1.getState()));
636 		Assert.assertFalse("client v2 is resolved.", Module.RESOLVED_SET.contains(s2_v2.getState()));
637 		Assert.assertTrue("client v3 is not resolved.", Module.RESOLVED_SET.contains(s2_v3.getState()));
638 
639 		// now disable s1_v3
640 		disabled.add(s1_v3.getCurrentRevision());
641 		container.refresh(Arrays.asList(s1_v3));
642 		Assert.assertFalse("Singleton v1 is resolved.", Module.RESOLVED_SET.contains(s1_v1.getState()));
643 		Assert.assertTrue("Singleton v2 is not resolved.", Module.RESOLVED_SET.contains(s1_v2.getState()));
644 		Assert.assertFalse("Singleton v3 is resolved.", Module.RESOLVED_SET.contains(s1_v3.getState()));
645 
646 		Assert.assertFalse("client v1 is resolved.", Module.RESOLVED_SET.contains(s2_v1.getState()));
647 		Assert.assertTrue("client v2 is not resolved.", Module.RESOLVED_SET.contains(s2_v2.getState()));
648 		Assert.assertFalse("client v3 is resolved.", Module.RESOLVED_SET.contains(s2_v3.getState()));
649 
650 		// now disable s1_v2
651 		disabled.add(s1_v2.getCurrentRevision());
652 		container.refresh(Arrays.asList(s1_v2));
653 		Assert.assertTrue("Singleton v1 is not resolved.", Module.RESOLVED_SET.contains(s1_v1.getState()));
654 		Assert.assertFalse("Singleton v2 is resolved.", Module.RESOLVED_SET.contains(s1_v2.getState()));
655 		Assert.assertFalse("Singleton v3 is resolved.", Module.RESOLVED_SET.contains(s1_v3.getState()));
656 
657 		Assert.assertTrue("client v1 is not resolved.", Module.RESOLVED_SET.contains(s2_v1.getState()));
658 		Assert.assertFalse("client v2 is resolved.", Module.RESOLVED_SET.contains(s2_v2.getState()));
659 		Assert.assertFalse("client v3 is resolved.", Module.RESOLVED_SET.contains(s2_v3.getState()));
660 
661 	}
662 
663 	@Test
testEventsInstall()664 	public void testEventsInstall() throws BundleException, IOException {
665 		DummyContainerAdaptor adaptor = createDummyAdaptor();
666 		ModuleContainer container = adaptor.getContainer();
667 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
668 		Module c2 = installDummyModule("c2_v1.MF", "c2_v1", container);
669 		Module c3 = installDummyModule("c3_v1.MF", "c3_v1", container);
670 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
671 		Module c5 = installDummyModule("c5_v1.MF", "c5_v1", container);
672 		Module c6 = installDummyModule("c6_v1.MF", "c6_v1", container);
673 		Module c7 = installDummyModule("c7_v1.MF", "c7_v1", container);
674 
675 		List<DummyModuleEvent> actual = adaptor.getDatabase().getModuleEvents();
676 		List<DummyModuleEvent> expected = Arrays.asList(new DummyModuleEvent(c1, ModuleEvent.INSTALLED, State.INSTALLED), new DummyModuleEvent(c2, ModuleEvent.INSTALLED, State.INSTALLED), new DummyModuleEvent(c3, ModuleEvent.INSTALLED, State.INSTALLED), new DummyModuleEvent(c4, ModuleEvent.INSTALLED, State.INSTALLED), new DummyModuleEvent(c5, ModuleEvent.INSTALLED, State.INSTALLED), new DummyModuleEvent(c6, ModuleEvent.INSTALLED, State.INSTALLED), new DummyModuleEvent(c7, ModuleEvent.INSTALLED, State.INSTALLED));
677 		Assert.assertEquals("Wrong install events.", expected, actual);
678 	}
679 
680 	@Test
testEventsResolved()681 	public void testEventsResolved() throws BundleException, IOException {
682 		DummyContainerAdaptor adaptor = createDummyAdaptor();
683 		ModuleContainer container = adaptor.getContainer();
684 		DummyModuleDatabase database = adaptor.getDatabase();
685 
686 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
687 
688 		container.resolve(Arrays.asList(systemBundle), true);
689 
690 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
691 		Module c2 = installDummyModule("c2_v1.MF", "c2_v1", container);
692 		Module c3 = installDummyModule("c3_v1.MF", "c3_v1", container);
693 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
694 		Module c5 = installDummyModule("c5_v1.MF", "c5_v1", container);
695 		Module c6 = installDummyModule("c6_v1.MF", "c6_v1", container);
696 		Module c7 = installDummyModule("c7_v1.MF", "c7_v1", container);
697 		// throw away installed events
698 		database.getModuleEvents();
699 
700 		container.resolve(Arrays.asList(c1, c2, c3, c4, c5, c6, c7), true);
701 		List<DummyModuleEvent> actual = database.getModuleEvents();
702 		List<DummyModuleEvent> expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(c1, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c2, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c3, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c4, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c5, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c6, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c7, ModuleEvent.RESOLVED, State.RESOLVED)));
703 		assertEvents(expected, actual, false);
704 	}
705 
706 	@Test
testEventsRefresh()707 	public void testEventsRefresh() throws BundleException, IOException {
708 		DummyContainerAdaptor adaptor = createDummyAdaptor();
709 		ModuleContainer container = adaptor.getContainer();
710 		DummyModuleDatabase database = adaptor.getDatabase();
711 
712 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
713 
714 		container.resolve(Arrays.asList(systemBundle), true);
715 
716 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
717 		Module c2 = installDummyModule("c2_v1.MF", "c2_v1", container);
718 		Module c3 = installDummyModule("c3_v1.MF", "c3_v1", container);
719 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
720 		Module c5 = installDummyModule("c5_v1.MF", "c5_v1", container);
721 		Module c6 = installDummyModule("c6_v1.MF", "c6_v1", container);
722 		Module c7 = installDummyModule("c7_v1.MF", "c7_v1", container);
723 
724 		container.resolve(Arrays.asList(c1, c2, c3, c4, c5, c6, c7), true);
725 		// throw away installed and resolved events
726 		database.getModuleEvents();
727 
728 		container.refresh(Arrays.asList(systemBundle));
729 		List<DummyModuleEvent> actual = database.getModuleEvents();
730 		List<DummyModuleEvent> expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(systemBundle, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c1, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c2, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c3, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c4, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c5, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c6, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c7, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(systemBundle, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c1, ModuleEvent.RESOLVED, State.RESOLVED),
731 				new DummyModuleEvent(c2, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c3, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c4, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c5, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c6, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c7, ModuleEvent.RESOLVED, State.RESOLVED)));
732 		assertEvents(expected, actual, false);
733 	}
734 
735 	@Test
testEventsStart()736 	public void testEventsStart() throws BundleException, IOException {
737 		DummyContainerAdaptor adaptor = createDummyAdaptor();
738 		ModuleContainer container = adaptor.getContainer();
739 		DummyModuleDatabase database = adaptor.getDatabase();
740 
741 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
742 
743 		container.resolve(Arrays.asList(systemBundle), true);
744 
745 		// actually launch the container
746 		systemBundle.start();
747 
748 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
749 		Module c2 = installDummyModule("c2_v1.MF", "c2_v1", container);
750 		Module c3 = installDummyModule("c3_v1.MF", "c3_v1", container);
751 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
752 		Module c5 = installDummyModule("c5_v1.MF", "c5_v1", container);
753 		Module c6 = installDummyModule("c6_v1.MF", "c6_v1", container);
754 		Module c7 = installDummyModule("c7_v1.MF", "c7_v1", container);
755 		// throw away installed events
756 		database.getModuleEvents();
757 
758 		c7.start();
759 
760 		List<DummyModuleEvent> actual = database.getModuleEvents();
761 		List<DummyModuleEvent> expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(c1, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c2, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c3, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c4, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c5, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c6, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c7, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c7, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c7, ModuleEvent.STARTED, State.ACTIVE)));
762 		assertEvents(expected, actual, false);
763 	}
764 
765 	@Test
testEventsStartRefresh()766 	public void testEventsStartRefresh() throws BundleException, IOException {
767 		DummyContainerAdaptor adaptor = createDummyAdaptor();
768 		ModuleContainer container = adaptor.getContainer();
769 		DummyModuleDatabase database = adaptor.getDatabase();
770 
771 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
772 
773 		container.resolve(Arrays.asList(systemBundle), true);
774 		// actually launch the container
775 		systemBundle.start();
776 
777 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
778 		Module c5 = installDummyModule("c5_v1.MF", "c5_v1", container);
779 		Module c6 = installDummyModule("c6_v1.MF", "c6_v1", container);
780 		Module c7 = installDummyModule("c7_v1.MF", "c7_v1", container);
781 
782 		c7.start();
783 		// discard events
784 		database.getModuleEvents();
785 		container.refresh(Arrays.asList(c4));
786 		List<DummyModuleEvent> actual = database.getModuleEvents();
787 		List<DummyModuleEvent> expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(c7, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c7, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c4, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c5, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c6, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c7, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c4, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c5, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c6, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c7, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c7, ModuleEvent.STARTING, State.STARTING),
788 				new DummyModuleEvent(c7, ModuleEvent.STARTED, State.ACTIVE)));
789 		assertEvents(expected, actual, false);
790 	}
791 
792 	@Test
testRemovalPending()793 	public void testRemovalPending() throws BundleException, IOException {
794 		DummyContainerAdaptor adaptor = createDummyAdaptor();
795 		ModuleContainer container = adaptor.getContainer();
796 		DummyModuleDatabase database = adaptor.getDatabase();
797 
798 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
799 
800 		container.resolve(Arrays.asList(systemBundle), true);
801 
802 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
803 		Module c6 = installDummyModule("c6_v1.MF", "c6_v1", container);
804 		Module c7 = installDummyModule("c7_v1.MF", "c7_v1", container);
805 
806 		container.resolve(Arrays.asList(c7), true);
807 		// throw out installed and resolved events
808 		database.getModuleEvents();
809 
810 		ModuleRevision c4Revision0 = c4.getCurrentRevision();
811 		// updating to identical content
812 		container.update(c4, OSGiManifestBuilderFactory.createBuilder(getManifest("c4_v1.MF")), null);
813 		container.resolve(Arrays.asList(c4), true);
814 
815 		Collection<ModuleRevision> removalPending = container.getRemovalPending();
816 		Assert.assertEquals("Wrong number of removal pending", 1, removalPending.size());
817 		Assert.assertTrue("Wrong module removalPending: " + removalPending, removalPending.contains(c4Revision0));
818 
819 		ModuleRevision c6Revision0 = c6.getCurrentRevision();
820 		// updating to identical content
821 		container.update(c6, OSGiManifestBuilderFactory.createBuilder(getManifest("c6_v1.MF")), null);
822 		container.resolve(Arrays.asList(c6), true);
823 
824 		removalPending = container.getRemovalPending();
825 		Assert.assertEquals("Wrong number of removal pending", 2, removalPending.size());
826 		Assert.assertTrue("Wrong module removalPending: " + removalPending, removalPending.containsAll(Arrays.asList(c4Revision0, c6Revision0)));
827 
828 		// update again with identical content
829 		container.update(c4, OSGiManifestBuilderFactory.createBuilder(getManifest("c4_v1.MF")), null);
830 		container.update(c6, OSGiManifestBuilderFactory.createBuilder(getManifest("c6_v1.MF")), null);
831 		container.resolve(Arrays.asList(c4, c6), true);
832 
833 		// Again we only have two since the previous current revisions did not have any dependents
834 		removalPending = container.getRemovalPending();
835 		Assert.assertEquals("Wrong number of removal pending", 2, removalPending.size());
836 		Assert.assertTrue("Wrong module removalPending: " + removalPending, removalPending.containsAll(Arrays.asList(c4Revision0, c6Revision0)));
837 
838 		container.refresh(null);
839 
840 		removalPending = container.getRemovalPending();
841 		Assert.assertEquals("Wrong number of removal pending", 0, removalPending.size());
842 
843 		List<DummyModuleEvent> actual = database.getModuleEvents();
844 		List<DummyModuleEvent> expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(c4, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c4, ModuleEvent.UPDATED, State.INSTALLED), new DummyModuleEvent(c4, ModuleEvent.RESOLVED, State.RESOLVED),
845 
846 				new DummyModuleEvent(c6, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c6, ModuleEvent.UPDATED, State.INSTALLED), new DummyModuleEvent(c6, ModuleEvent.RESOLVED, State.RESOLVED),
847 
848 				new DummyModuleEvent(c4, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c4, ModuleEvent.UPDATED, State.INSTALLED), new DummyModuleEvent(c6, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c6, ModuleEvent.UPDATED, State.INSTALLED), new DummyModuleEvent(c4, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c6, ModuleEvent.RESOLVED, State.RESOLVED),
849 
850 				new DummyModuleEvent(c4, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c6, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c7, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c4, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c6, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(c7, ModuleEvent.RESOLVED, State.RESOLVED)));
851 		assertEvents(expected, actual, false);
852 
853 		// uninstall c4
854 		c4Revision0 = c4.getCurrentRevision();
855 		container.uninstall(c4);
856 		removalPending = container.getRemovalPending();
857 		Assert.assertEquals("Wrong number of removal pending", 1, removalPending.size());
858 		Assert.assertTrue("Wrong module removalPending: " + removalPending, removalPending.containsAll(Arrays.asList(c4Revision0)));
859 
860 		container.refresh(null);
861 		actual = database.getModuleEvents();
862 		expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(c4, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c4, ModuleEvent.UNINSTALLED, State.UNINSTALLED), new DummyModuleEvent(c6, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c7, ModuleEvent.UNRESOLVED, State.INSTALLED)));
863 		assertEvents(expected, actual, false);
864 
865 		// Test bug 411833
866 		// install c4 again and resolve c6
867 		c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
868 		container.resolve(Arrays.asList(c6), true);
869 		// throw out installed and resolved events
870 		database.getModuleEvents();
871 
872 		removalPending = container.getRemovalPending();
873 		Assert.assertEquals("Wrong number of removal pending", 0, removalPending.size());
874 
875 		c4Revision0 = c4.getCurrentRevision();
876 		// uninstall c4, but refresh c6 instead
877 		// this should result in removal pending c4 to be removed.
878 		container.uninstall(c4);
879 		removalPending = container.getRemovalPending();
880 		Assert.assertEquals("Wrong number of removal pending", 1, removalPending.size());
881 		Assert.assertTrue("Wrong module removalPending: " + removalPending, removalPending.containsAll(Arrays.asList(c4Revision0)));
882 
883 		container.refresh(Collections.singletonList(c6));
884 		actual = database.getModuleEvents();
885 		expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(c4, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c4, ModuleEvent.UNINSTALLED, State.UNINSTALLED), new DummyModuleEvent(c6, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(c7, ModuleEvent.UNRESOLVED, State.INSTALLED)));
886 		assertEvents(expected, actual, false);
887 
888 		removalPending = container.getRemovalPending();
889 		Assert.assertEquals("Wrong number of removal pending", 0, removalPending.size());
890 	}
891 
892 	@Test
testSubstitutableExports01()893 	public void testSubstitutableExports01() throws BundleException, IOException {
894 		DummyContainerAdaptor adaptor = createDummyAdaptor();
895 		ModuleContainer container = adaptor.getContainer();
896 
897 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
898 
899 		container.resolve(Arrays.asList(systemBundle), true);
900 
901 		Module sub1 = installDummyModule("sub1_v1.MF", "sub1", container);
902 		Module sub2 = installDummyModule("sub2_v1.MF", "sub2", container);
903 
904 		ModuleRevision sub1Revision0 = sub1.getCurrentRevision();
905 
906 		container.resolve(Arrays.asList(sub2), true);
907 
908 		container.update(sub1, OSGiManifestBuilderFactory.createBuilder(getManifest("sub1_v2.MF")), null);
909 		container.resolve(Arrays.asList(sub1), true);
910 
911 		ModuleWiring sub1Wiring = sub1.getCurrentRevision().getWiring();
912 		List<BundleCapability> exportedPackages = sub1Wiring.getCapabilities(PackageNamespace.PACKAGE_NAMESPACE);
913 		Assert.assertEquals("Wrong number of exported packages: " + exportedPackages, 0, exportedPackages.size());
914 		List<BundleWire> requiredWires = sub1Wiring.getRequiredWires(PackageNamespace.PACKAGE_NAMESPACE);
915 		Assert.assertEquals("Wrong number of imported packages: ", 2, requiredWires.size());
916 		Assert.assertEquals("Wrong provider for package: " + requiredWires.get(1).getProvider(), sub1Revision0, requiredWires.get(1).getProvider());
917 
918 		container.refresh(Arrays.asList(sub1));
919 
920 		sub1Wiring = sub1.getCurrentRevision().getWiring();
921 		exportedPackages = sub1Wiring.getCapabilities(PackageNamespace.PACKAGE_NAMESPACE);
922 		Assert.assertEquals("Wrong number of exported packages: " + exportedPackages, 1, exportedPackages.size());
923 		requiredWires = sub1Wiring.getRequiredWires(PackageNamespace.PACKAGE_NAMESPACE);
924 		Assert.assertEquals("Wrong number of imported packages: ", 1, requiredWires.size());
925 
926 	}
927 
928 	@Test
testSubstitutableExports02()929 	public void testSubstitutableExports02() throws BundleException, IOException {
930 		DummyContainerAdaptor adaptor = createDummyAdaptor();
931 		ModuleContainer container = adaptor.getContainer();
932 
933 		Module a = installDummyModule("sub.a.MF", "a", container);
934 		Module b = installDummyModule("sub.b.MF", "b", container);
935 		Module c = installDummyModule("sub.c.MF", "c", container);
936 
937 		container.resolve(Arrays.asList(a, b, c), true);
938 
939 		ModuleWiring wiringA = a.getCurrentRevision().getWiring();
940 		ModuleWiring wiringB = b.getCurrentRevision().getWiring();
941 		ModuleWiring wiringC = c.getCurrentRevision().getWiring();
942 
943 		List<ModuleWire> providedWiresA = wiringA.getProvidedModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
944 		Assert.assertEquals("Wrong number of provided wires.", 2, providedWiresA.size());
945 
946 		Collection<ModuleRevision> requirers = new ArrayList<>();
947 		for (ModuleWire wire : providedWiresA) {
948 			requirers.add(wire.getRequirer());
949 		}
950 		Assert.assertTrue("b does not require.", requirers.contains(b.getCurrentRevision()));
951 		Assert.assertTrue("c does not require.", requirers.contains(c.getCurrentRevision()));
952 
953 		List<ModuleWire> requiredWiresB = wiringB.getRequiredModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
954 		Assert.assertEquals("Wrong number of required wires.", 1, requiredWiresB.size());
955 		Assert.assertEquals("Unexpected package name.", "javax.servlet", requiredWiresB.iterator().next().getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
956 		Assert.assertEquals("Wrong provider.", a.getCurrentRevision(), requiredWiresB.iterator().next().getProvider());
957 
958 		List<ModuleWire> requiredWiresC = wiringC.getRequiredModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
959 		Assert.assertEquals("Wrong number of required wires.", 1, requiredWiresC.size());
960 		Assert.assertEquals("Wrong number of required wires.", 1, requiredWiresC.size());
961 		Assert.assertEquals("Unexpected package name.", "javax.servlet", requiredWiresC.iterator().next().getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
962 		Assert.assertEquals("Wrong provider.", a.getCurrentRevision(), requiredWiresC.iterator().next().getProvider());
963 
964 		Module d = installDummyModule("sub.d.MF", "d", container);
965 
966 		container.resolve(Arrays.asList(d), true);
967 
968 		ModuleWiring wiringD = d.getCurrentRevision().getWiring();
969 		List<ModuleWire> requiredWiresD = wiringD.getRequiredModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
970 		Assert.assertEquals("Wrong number of required wires.", 2, requiredWiresD.size());
971 		Assert.assertEquals("Unexpected package name.", "org.ops4j.pax.web.service", requiredWiresD.get(0).getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
972 		Assert.assertEquals("Wrong provider.", c.getCurrentRevision(), requiredWiresD.get(0).getProvider());
973 		Assert.assertEquals("Unexpected package name.", "javax.servlet", requiredWiresD.get(1).getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
974 		Assert.assertEquals("Wrong provider.", a.getCurrentRevision(), requiredWiresD.get(1).getProvider());
975 
976 	}
977 
978 	@Test
testSubstitutableExports03()979 	public void testSubstitutableExports03() throws BundleException, IOException {
980 		DummyContainerAdaptor adaptor = createDummyAdaptor();
981 		ModuleContainer container = adaptor.getContainer();
982 
983 		// install order does not really matter
984 		Module g = installDummyModule("sub.g.MF", "g", container);
985 		Module f = installDummyModule("sub.f.MF", "f", container);
986 		Module e = installDummyModule("sub.e.MF", "e", container);
987 
988 		// resolve order does matter so that transitive dependencies are pulled in
989 		// and cause substitution to happen in a certain way
990 		container.resolve(Arrays.asList(g, f, e), true);
991 
992 		ModuleWiring wiringE = e.getCurrentRevision().getWiring();
993 		ModuleWiring wiringF = f.getCurrentRevision().getWiring();
994 
995 		List<ModuleWire> providedWiresE = wiringE.getProvidedModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
996 		Assert.assertEquals("Wrong number of provided wires.", 3, providedWiresE.size());
997 
998 		Collection<ModuleRevision> requirers = new HashSet<>();
999 		for (ModuleWire wire : providedWiresE) {
1000 			requirers.add(wire.getRequirer());
1001 		}
1002 		Assert.assertTrue("f does not require.", requirers.remove(f.getCurrentRevision()));
1003 		Assert.assertTrue("g does not require.", requirers.remove(g.getCurrentRevision()));
1004 		Assert.assertTrue("No requirers should be left: " + requirers, requirers.isEmpty());
1005 
1006 		List<ModuleWire> providedWiresF = wiringF.getProvidedModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
1007 		Assert.assertEquals("Wrong number of provided wires: " + providedWiresF, 0, providedWiresF.size());
1008 	}
1009 
1010 	@Test
testSubstitutableExports04()1011 	public void testSubstitutableExports04() throws BundleException, IOException {
1012 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1013 		ModuleContainer container = adaptor.getContainer();
1014 
1015 		// install order does not really matter
1016 		installDummyModule("sub.h.MF", "h", container);
1017 		Module i = installDummyModule("sub.i.MF", "i", container);
1018 		installDummyModule("sub.j.MF", "j", container);
1019 		Module k = installDummyModule("sub.k.MF", "k", container);
1020 
1021 		// resolve order does matter so that transitive dependencies are pulled in
1022 		// and cause substitution to happen in a certain way
1023 		container.resolve(Arrays.asList(k), true);
1024 
1025 		ModuleWiring wiringI = i.getCurrentRevision().getWiring();
1026 		ModuleWiring wiringK = k.getCurrentRevision().getWiring();
1027 
1028 		List<ModuleWire> requiredWiresK = wiringK.getRequiredModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
1029 
1030 		// I should be the provider for all of K
1031 		Assert.assertEquals("Wrong number of required wires: " + requiredWiresK, 2, requiredWiresK.size());
1032 		for (ModuleWire moduleWire : requiredWiresK) {
1033 			Assert.assertEquals("Wrong provider: " + moduleWire.getProviderWiring(), wiringI, moduleWire.getProviderWiring());
1034 		}
1035 	}
1036 
1037 	@Test
testLazy01()1038 	public void testLazy01() throws BundleException, IOException {
1039 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1040 		ModuleContainer container = adaptor.getContainer();
1041 		DummyModuleDatabase database = adaptor.getDatabase();
1042 
1043 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1044 
1045 		container.resolve(Arrays.asList(systemBundle), true);
1046 
1047 		// actually launch the container
1048 		systemBundle.start();
1049 
1050 		Module lazy1 = installDummyModule("lazy1_v1.MF", "lazy1", container);
1051 
1052 		// throw out installed and resolved events
1053 		database.getModuleEvents();
1054 
1055 		lazy1.start(StartOptions.USE_ACTIVATION_POLICY);
1056 
1057 		List<DummyModuleEvent> actual = database.getModuleEvents();
1058 		List<DummyModuleEvent> expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(lazy1, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(lazy1, ModuleEvent.LAZY_ACTIVATION, State.LAZY_STARTING)));
1059 		assertEvents(expected, actual, true);
1060 
1061 		lazy1.start(StartOptions.LAZY_TRIGGER);
1062 
1063 		actual = database.getModuleEvents();
1064 		expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(lazy1, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(lazy1, ModuleEvent.STARTED, State.ACTIVE)));
1065 		assertEvents(expected, actual, true);
1066 
1067 		container.refresh(Arrays.asList(lazy1));
1068 
1069 		actual = database.getModuleEvents();
1070 		expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(lazy1, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(lazy1, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(lazy1, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(lazy1, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(lazy1, ModuleEvent.LAZY_ACTIVATION, State.LAZY_STARTING)));
1071 		assertEvents(expected, actual, true);
1072 
1073 		container.update(lazy1, OSGiManifestBuilderFactory.createBuilder(getManifest("lazy1_v1.MF")), null);
1074 		actual = database.getModuleEvents();
1075 		expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(lazy1, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(lazy1, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(lazy1, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(lazy1, ModuleEvent.UPDATED, State.INSTALLED), new DummyModuleEvent(lazy1, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(lazy1, ModuleEvent.LAZY_ACTIVATION, State.LAZY_STARTING)));
1076 		assertEvents(expected, actual, true);
1077 
1078 		container.refresh(Arrays.asList(lazy1));
1079 		actual = database.getModuleEvents();
1080 		expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(lazy1, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(lazy1, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(lazy1, ModuleEvent.UNRESOLVED, State.INSTALLED), new DummyModuleEvent(lazy1, ModuleEvent.RESOLVED, State.RESOLVED), new DummyModuleEvent(lazy1, ModuleEvent.LAZY_ACTIVATION, State.LAZY_STARTING)));
1081 		assertEvents(expected, actual, true);
1082 	}
1083 
1084 	@Test
testSettings01()1085 	public void testSettings01() throws BundleException, IOException {
1086 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1087 		ModuleContainer container = adaptor.getContainer();
1088 		DummyModuleDatabase database = adaptor.getDatabase();
1089 
1090 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1091 
1092 		container.resolve(Arrays.asList(systemBundle), true);
1093 
1094 		// actually launch the container
1095 		systemBundle.start();
1096 
1097 		container.getFrameworkStartLevel().setInitialBundleStartLevel(2);
1098 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
1099 		Module lazy1 = installDummyModule("lazy1_v1.MF", "lazy1", container);
1100 
1101 		container.resolve(Arrays.asList(c4, lazy1), true);
1102 
1103 		Assert.assertEquals("Wrong startlevel.", 2, c4.getStartLevel());
1104 		Assert.assertEquals("Wrong startlevel.", 2, lazy1.getStartLevel());
1105 
1106 		c4.setStartLevel(3);
1107 		lazy1.setStartLevel(3);
1108 
1109 		Assert.assertEquals("Wrong startlevel.", 3, c4.getStartLevel());
1110 		Assert.assertEquals("Wrong startlevel.", 3, lazy1.getStartLevel());
1111 
1112 		database.getModuleEvents();
1113 
1114 		c4.start();
1115 		lazy1.start(StartOptions.USE_ACTIVATION_POLICY);
1116 
1117 		List<DummyModuleEvent> actual = database.getModuleEvents();
1118 		Assert.assertEquals("Did not expect any events.", 0, actual.size());
1119 
1120 		database.getContainerEvents();
1121 		container.getFrameworkStartLevel().setStartLevel(3);
1122 
1123 		List<DummyContainerEvent> actualContainerEvents = database.getContainerEvents(1);
1124 		List<DummyContainerEvent> expectedContainerEvents = new ArrayList<>(Arrays.asList(new DummyContainerEvent(ContainerEvent.START_LEVEL, systemBundle, null)));
1125 		Assert.assertEquals("Wrong container events.", expectedContainerEvents, actualContainerEvents);
1126 
1127 		actual = database.getModuleEvents(3);
1128 		List<DummyModuleEvent> expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(lazy1, ModuleEvent.LAZY_ACTIVATION, State.LAZY_STARTING), new DummyModuleEvent(c4, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c4, ModuleEvent.STARTED, State.ACTIVE)));
1129 		assertEvents(expected, actual, true);
1130 
1131 		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
1132 		DataOutputStream data = new DataOutputStream(bytes);
1133 		database.store(data, true);
1134 
1135 		systemBundle.stop();
1136 
1137 		// reload into a new container
1138 		adaptor = createDummyAdaptor();
1139 		container = adaptor.getContainer();
1140 		database = adaptor.getDatabase();
1141 		database.load(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray())));
1142 
1143 		systemBundle = container.getModule(0);
1144 		Assert.assertNotNull("System bundle is null.", systemBundle);
1145 		Assert.assertTrue("System bundle should always use activation policy.", systemBundle.isActivationPolicyUsed());
1146 		Assert.assertTrue("System bundle should always have its auto-start flag set.", systemBundle.isPersistentlyStarted());
1147 
1148 		c4 = container.getModule(c4.getId());
1149 		Assert.assertNotNull("c4 is null", c4);
1150 		lazy1 = container.getModule(lazy1.getId());
1151 		Assert.assertNotNull("lazy1 is null", lazy1);
1152 
1153 		Assert.assertFalse("c4 has activation policy set.", c4.isActivationPolicyUsed());
1154 		Assert.assertTrue("c4 is not auto started.", c4.isPersistentlyStarted());
1155 		Assert.assertEquals("c4 has wrong start-level", 3, c4.getStartLevel());
1156 		Assert.assertTrue("lazy1 is using activation policy.", lazy1.isActivationPolicyUsed());
1157 		Assert.assertTrue("lazy1 is not auto started.", lazy1.isPersistentlyStarted());
1158 		Assert.assertEquals("lazy1 has wrong start-level", 3, lazy1.getStartLevel());
1159 
1160 		// relaunch the container
1161 		systemBundle.start();
1162 
1163 		actualContainerEvents = database.getContainerEvents();
1164 		expectedContainerEvents = new ArrayList<>(Arrays.asList(new DummyContainerEvent(ContainerEvent.START_LEVEL, systemBundle, null), new DummyContainerEvent(ContainerEvent.STARTED, systemBundle, null)));
1165 
1166 		actual = database.getModuleEvents(2);
1167 		expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(systemBundle, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(systemBundle, ModuleEvent.STARTED, State.ACTIVE)));
1168 		assertEvents(expected, actual, true);
1169 
1170 		container.getFrameworkStartLevel().setStartLevel(3);
1171 
1172 		actualContainerEvents = database.getContainerEvents(1);
1173 		expectedContainerEvents = new ArrayList<>(Arrays.asList(new DummyContainerEvent(ContainerEvent.START_LEVEL, systemBundle, null)));
1174 		Assert.assertEquals("Wrong container events.", expectedContainerEvents, actualContainerEvents);
1175 
1176 		actual = database.getModuleEvents(3);
1177 		expected = new ArrayList<>(Arrays.asList(new DummyModuleEvent(lazy1, ModuleEvent.LAZY_ACTIVATION, State.LAZY_STARTING), new DummyModuleEvent(c4, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c4, ModuleEvent.STARTED, State.ACTIVE)));
1178 		assertEvents(expected, actual, true);
1179 	}
1180 
1181 	@Test
testTimestampSeeding()1182 	public void testTimestampSeeding() throws BundleException, IOException, InterruptedException {
1183 		Assert.assertNotEquals("The timestamps are the same!", createTestContainerAndGetTimestamp(), createTestContainerAndGetTimestamp());
1184 	}
1185 
createTestContainerAndGetTimestamp()1186 	private long createTestContainerAndGetTimestamp() throws BundleException, IOException, InterruptedException {
1187 		// wait here to ensure current time really has increased
1188 		Thread.sleep(100);
1189 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1190 		ModuleContainer container = adaptor.getContainer();
1191 		DummyModuleDatabase database = adaptor.getDatabase();
1192 
1193 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1194 
1195 		container.resolve(Arrays.asList(systemBundle), true);
1196 
1197 		// actually launch the container
1198 		systemBundle.start();
1199 
1200 		// install some bundles and set some settings
1201 		container.getFrameworkStartLevel().setInitialBundleStartLevel(2);
1202 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
1203 		Module lazy1 = installDummyModule("lazy1_v1.MF", "lazy1", container);
1204 
1205 		container.resolve(Arrays.asList(c4, lazy1), true);
1206 
1207 		// set some settings
1208 		Assert.assertEquals("Wrong startlevel.", 2, c4.getStartLevel());
1209 		Assert.assertEquals("Wrong startlevel.", 2, lazy1.getStartLevel());
1210 		return database.getTimestamp();
1211 	}
1212 
1213 	@Test
testEventsStartLevelBeginningAt100()1214 	public void testEventsStartLevelBeginningAt100() throws BundleException, IOException {
1215 		doTestEventsStartLevel(100);
1216 	}
1217 
1218 	@Test
testEventsStartLevelBeginningAt1()1219 	public void testEventsStartLevelBeginningAt1() throws BundleException, IOException {
1220 		doTestEventsStartLevel(1);
1221 	}
1222 
doTestEventsStartLevel(int beginningStartLevel)1223 	private void doTestEventsStartLevel(int beginningStartLevel) throws BundleException, IOException {
1224 		Map<String, String> configuration = new HashMap<>();
1225 		configuration.put(Constants.FRAMEWORK_BEGINNING_STARTLEVEL, String.valueOf(beginningStartLevel));
1226 
1227 		DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(false), configuration);
1228 		ModuleContainer container = adaptor.getContainer();
1229 		DummyModuleDatabase database = adaptor.getDatabase();
1230 
1231 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1232 
1233 		container.resolve(Arrays.asList(systemBundle), true);
1234 
1235 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
1236 		Module c2 = installDummyModule("c2_v1.MF", "c2_v1", container);
1237 		Module c3 = installDummyModule("c3_v1.MF", "c3_v1", container);
1238 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
1239 		Module c5 = installDummyModule("c5_v1.MF", "c5_v1", container);
1240 		Module c6 = installDummyModule("c6_v1.MF", "c6_v1", container);
1241 		Module c7 = installDummyModule("c7_v1.MF", "c7_v1", container);
1242 		container.resolve(Arrays.asList(c1, c2, c3, c4, c5, c6, c7), true);
1243 		database.getModuleEvents();
1244 
1245 		c1.setStartLevel(70);
1246 		c2.setStartLevel(60);
1247 		c3.setStartLevel(50);
1248 		c4.setStartLevel(40);
1249 		c5.setStartLevel(30);
1250 		c6.setStartLevel(20);
1251 		c7.setStartLevel(10);
1252 
1253 		c1.start();
1254 		c2.start();
1255 		c3.start();
1256 		c4.start();
1257 		c5.start();
1258 		c6.start();
1259 		c7.start();
1260 
1261 		List<DummyModuleEvent> actualModuleEvents = database.getModuleEvents();
1262 		Assert.assertEquals("Expecting no events.", 0, actualModuleEvents.size());
1263 
1264 		systemBundle.start();
1265 
1266 		if (beginningStartLevel == 1) {
1267 			actualModuleEvents = database.getModuleEvents(2);
1268 			List<DummyModuleEvent> expectedModuleEvents = new ArrayList<>(Arrays.asList(new DummyModuleEvent(systemBundle, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(systemBundle, ModuleEvent.STARTED, State.ACTIVE)));
1269 			assertEvents(expectedModuleEvents, actualModuleEvents, true);
1270 
1271 			List<DummyContainerEvent> actualContainerEvents = database.getContainerEvents();
1272 			List<DummyContainerEvent> expectedContainerEvents = new ArrayList<>(Arrays.asList(new DummyContainerEvent(ContainerEvent.STARTED, systemBundle, null)));
1273 			Assert.assertEquals("Wrong container events.", expectedContainerEvents, actualContainerEvents);
1274 
1275 			container.getFrameworkStartLevel().setStartLevel(100);
1276 			actualModuleEvents = database.getModuleEvents(14);
1277 			expectedModuleEvents = new ArrayList<>(Arrays.asList(new DummyModuleEvent(c7, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c7, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c6, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c6, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c5, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c5, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c4, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c4, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c3, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c3, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c2, ModuleEvent.STARTING, State.STARTING),
1278 					new DummyModuleEvent(c2, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c1, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c1, ModuleEvent.STARTED, State.ACTIVE)));
1279 
1280 			actualContainerEvents = database.getContainerEvents(1);
1281 			expectedContainerEvents = new ArrayList<>(Arrays.asList(new DummyContainerEvent(ContainerEvent.START_LEVEL, systemBundle, null)));
1282 			Assert.assertEquals("Wrong container events.", expectedContainerEvents, actualContainerEvents);
1283 		} else {
1284 			actualModuleEvents = database.getModuleEvents(16);
1285 			List<DummyModuleEvent> expectedModuleEvents = new ArrayList<>(Arrays.asList(new DummyModuleEvent(systemBundle, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c7, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c7, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c6, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c6, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c5, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c5, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c4, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c4, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c3, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c3, ModuleEvent.STARTED, State.ACTIVE),
1286 					new DummyModuleEvent(c2, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c2, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(c1, ModuleEvent.STARTING, State.STARTING), new DummyModuleEvent(c1, ModuleEvent.STARTED, State.ACTIVE), new DummyModuleEvent(systemBundle, ModuleEvent.STARTED, State.ACTIVE)));
1287 			assertEvents(expectedModuleEvents, actualModuleEvents, true);
1288 
1289 			List<DummyContainerEvent> actualContainerEvents = database.getContainerEvents();
1290 			List<DummyContainerEvent> expectedContainerEvents = new ArrayList<>(Arrays.asList(new DummyContainerEvent(ContainerEvent.STARTED, systemBundle, null)));
1291 			Assert.assertEquals("Wrong container events.", expectedContainerEvents, actualContainerEvents);
1292 		}
1293 
1294 		if (beginningStartLevel == 1) {
1295 			container.getFrameworkStartLevel().setStartLevel(1);
1296 			actualModuleEvents = database.getModuleEvents(14);
1297 			List<DummyModuleEvent> expectedModuleEvents = new ArrayList<>(Arrays.asList(new DummyModuleEvent(c1, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c1, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c2, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c2, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c3, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c3, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c4, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c4, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c5, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c5, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c6, ModuleEvent.STOPPING, State.STOPPING),
1298 					new DummyModuleEvent(c6, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c7, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c7, ModuleEvent.STOPPED, State.RESOLVED)));
1299 			assertEvents(expectedModuleEvents, actualModuleEvents, true);
1300 
1301 			List<DummyContainerEvent> actualContainerEvents = database.getContainerEvents(1);
1302 			List<DummyContainerEvent> expectedContainerEvents = new ArrayList<>(Arrays.asList(new DummyContainerEvent(ContainerEvent.START_LEVEL, systemBundle, null)));
1303 			Assert.assertEquals("Wrong container events.", expectedContainerEvents, actualContainerEvents);
1304 		}
1305 
1306 		systemBundle.stop();
1307 
1308 		if (beginningStartLevel == 1) {
1309 			actualModuleEvents = database.getModuleEvents(2);
1310 			List<DummyModuleEvent> expectedModuleEvents = new ArrayList<>(Arrays.asList(new DummyModuleEvent(systemBundle, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(systemBundle, ModuleEvent.STOPPED, State.RESOLVED)));
1311 			assertEvents(expectedModuleEvents, actualModuleEvents, true);
1312 		} else {
1313 			actualModuleEvents = database.getModuleEvents(16);
1314 			List<DummyModuleEvent> expectedModuleEvents = new ArrayList<>(Arrays.asList(new DummyModuleEvent(systemBundle, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c1, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c1, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c2, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c2, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c3, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c3, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c4, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c4, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c5, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c5, ModuleEvent.STOPPED, State.RESOLVED),
1315 					new DummyModuleEvent(c6, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c6, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(c7, ModuleEvent.STOPPING, State.STOPPING), new DummyModuleEvent(c7, ModuleEvent.STOPPED, State.RESOLVED), new DummyModuleEvent(systemBundle, ModuleEvent.STOPPED, State.RESOLVED)));
1316 			assertEvents(expectedModuleEvents, actualModuleEvents, true);
1317 		}
1318 		List<DummyContainerEvent> actualContainerEvents = database.getContainerEvents();
1319 		List<DummyContainerEvent> expectedContainerEvents = new ArrayList<>(Arrays.asList(new DummyContainerEvent(ContainerEvent.STOPPED, systemBundle, null)));
1320 		Assert.assertEquals("Wrong container events.", expectedContainerEvents, actualContainerEvents);
1321 	}
1322 
1323 	@Test
testDynamicImport01()1324 	public void testDynamicImport01() throws BundleException, IOException {
1325 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1326 		ModuleContainer container = adaptor.getContainer();
1327 
1328 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, null, null, "osgi.ee; osgi.ee=JavaSE; version:Version=\"1.5.0\"", container);
1329 
1330 		container.resolve(Arrays.asList(systemBundle), true);
1331 
1332 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
1333 		Module dynamic1 = installDummyModule("dynamic1_v1.MF", "dynamic1_v1", container);
1334 
1335 		container.resolve(Arrays.asList(c1, dynamic1), true);
1336 
1337 		ModuleWire dynamicWire = container.resolveDynamic("org.osgi.framework", dynamic1.getCurrentRevision());
1338 		Assert.assertNotNull("No dynamic wire found.", dynamicWire);
1339 		Assert.assertEquals("Wrong package found.", "org.osgi.framework", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1340 		Assert.assertEquals("Wrong provider for the wire found.", systemBundle.getCurrentRevision(), dynamicWire.getProvider());
1341 
1342 		dynamicWire = container.resolveDynamic("org.osgi.framework.wiring", dynamic1.getCurrentRevision());
1343 		Assert.assertNotNull("No dynamic wire found.", dynamicWire);
1344 		Assert.assertEquals("Wrong package found.", "org.osgi.framework.wiring", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1345 		Assert.assertEquals("Wrong provider for the wire found.", systemBundle.getCurrentRevision(), dynamicWire.getProvider());
1346 
1347 		dynamicWire = container.resolveDynamic("c1.b", dynamic1.getCurrentRevision());
1348 		Assert.assertNotNull("No dynamic wire found.", dynamicWire);
1349 		Assert.assertEquals("Wrong package found.", "c1.b", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1350 		Assert.assertEquals("Wrong provider for the wire found.", c1.getCurrentRevision(), dynamicWire.getProvider());
1351 	}
1352 
1353 	@Test
testDynamicImport02()1354 	public void testDynamicImport02() throws BundleException, IOException {
1355 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1356 		ModuleContainer container = adaptor.getContainer();
1357 
1358 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, null, null, "osgi.ee; osgi.ee=JavaSE; version:Version=\"1.5.0\"", container);
1359 
1360 		container.resolve(Arrays.asList(systemBundle), true);
1361 
1362 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
1363 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
1364 		Module dynamic1 = installDummyModule("dynamic1_v1.MF", "dynamic1_v1", container);
1365 		Module dynamic1Frag = installDummyModule("dynamic1.frag_v1.MF", "dynamic1.frag_v1", container);
1366 
1367 		container.resolve(Arrays.asList(c1, c4, dynamic1, dynamic1Frag), true);
1368 
1369 		ModuleWire dynamicWire = container.resolveDynamic("c1.b", dynamic1.getCurrentRevision());
1370 		Assert.assertNotNull("No dynamic wire found.", dynamicWire);
1371 		Assert.assertEquals("Wrong package found.", "c1.b", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1372 		Assert.assertEquals("Wrong provider for the wire found.", c1.getCurrentRevision(), dynamicWire.getProvider());
1373 
1374 		dynamicWire = container.resolveDynamic("c4.a", dynamic1.getCurrentRevision());
1375 		Assert.assertNotNull("No dynamic wire found.", dynamicWire);
1376 		Assert.assertEquals("Wrong package found.", "c4.a", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1377 		Assert.assertEquals("Wrong provider for the wire found.", c4.getCurrentRevision(), dynamicWire.getProvider());
1378 
1379 		dynamicWire = container.resolveDynamic("c4.b", dynamic1.getCurrentRevision());
1380 		Assert.assertNotNull("No dynamic wire found.", dynamicWire);
1381 		Assert.assertEquals("Wrong package found.", "c4.b", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1382 		Assert.assertEquals("Wrong provider for the wire found.", c4.getCurrentRevision(), dynamicWire.getProvider());
1383 	}
1384 
1385 	@Test
testDynamicImport03()1386 	public void testDynamicImport03() throws BundleException, IOException {
1387 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1388 		ModuleContainer container = adaptor.getContainer();
1389 		DummyModuleDatabase database = adaptor.getDatabase();
1390 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1391 
1392 		container.resolve(Arrays.asList(systemBundle), true);
1393 
1394 		Module dynamic3 = installDummyModule("dynamic2_v1.MF", "dynamic2_v1", container);
1395 
1396 		container.resolve(Arrays.asList(systemBundle, dynamic3), true);
1397 
1398 		ModuleWire dynamicWire = container.resolveDynamic("c1.a", dynamic3.getCurrentRevision());
1399 		Assert.assertNull("Dynamic wire found.", dynamicWire);
1400 
1401 		Module c1v1 = installDummyModule("c1_v1.MF", "c1_v1", container);
1402 		database.getModuleEvents();
1403 
1404 		dynamicWire = container.resolveDynamic("c1.a", dynamic3.getCurrentRevision());
1405 		Assert.assertNotNull("Dynamic wire not found.", dynamicWire);
1406 		Assert.assertEquals("Wrong package found.", "c1.a", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1407 		Assert.assertEquals("Wrong provider for the wire found.", c1v1.getCurrentRevision(), dynamicWire.getProvider());
1408 
1409 		ModuleWiring c1v1Wiring = c1v1.getCurrentRevision().getWiring();
1410 		Assert.assertNotNull("c1 wiring is null.", c1v1Wiring);
1411 
1412 		Module c1v2 = installDummyModule("c1_v2.MF", "c1_v2", container);
1413 		container.resolve(Arrays.asList(c1v2), true);
1414 		database.getModuleEvents();
1415 
1416 		dynamicWire = container.resolveDynamic("c1.b", dynamic3.getCurrentRevision());
1417 		Assert.assertNotNull("Dynamic wire not found.", dynamicWire);
1418 		Assert.assertEquals("Wrong package found.", "c1.b", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1419 		Assert.assertEquals("Wrong provider.", c1v1.getCurrentRevision(), dynamicWire.getProvider());
1420 	}
1421 
1422 	@Test
testDynamicImport04()1423 	public void testDynamicImport04() throws BundleException, IOException {
1424 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1425 		ModuleContainer container = adaptor.getContainer();
1426 		DummyModuleDatabase database = adaptor.getDatabase();
1427 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1428 
1429 		container.resolve(Arrays.asList(systemBundle), true);
1430 
1431 		Module dynamic3 = installDummyModule("dynamic2_v1.MF", "dynamic2_v1", container);
1432 
1433 		container.resolve(Arrays.asList(systemBundle, dynamic3), true);
1434 
1435 		ModuleWire dynamicWire = container.resolveDynamic("h1.a", dynamic3.getCurrentRevision());
1436 		Assert.assertNull("Dynamic wire found.", dynamicWire);
1437 
1438 		Module h1 = installDummyModule("h1_v1.MF", "h1_v1", container);
1439 		Module f1 = installDummyModule("f1_v1.MF", "f1_v1", container);
1440 		database.getModuleEvents();
1441 
1442 		dynamicWire = container.resolveDynamic("h1.a", dynamic3.getCurrentRevision());
1443 		Assert.assertNotNull("Dynamic wire not found.", dynamicWire);
1444 		Assert.assertEquals("Wrong package found.", "h1.a", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1445 		Assert.assertEquals("Wrong provider for the wire found.", h1.getCurrentRevision(), dynamicWire.getProvider());
1446 
1447 		dynamicWire = container.resolveDynamic("f1.a", dynamic3.getCurrentRevision());
1448 		Assert.assertNotNull("Dynamic wire not found.", dynamicWire);
1449 		Assert.assertEquals("Wrong package found.", "f1.a", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1450 		Assert.assertEquals("Wrong provider for the wire found.", h1.getCurrentRevision(), dynamicWire.getProvider());
1451 
1452 		ModuleWiring h1Wiring = h1.getCurrentRevision().getWiring();
1453 		Assert.assertNotNull("h1 wiring is null.", h1Wiring);
1454 
1455 		ModuleWiring f1Wiring = f1.getCurrentRevision().getWiring();
1456 		Assert.assertNotNull("f1 wiring is null.", f1Wiring);
1457 	}
1458 
1459 	@Test
testDynamicImport05()1460 	public void testDynamicImport05() throws BundleException, IOException {
1461 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1462 		ModuleContainer container = adaptor.getContainer();
1463 
1464 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, null, null, "osgi.ee; osgi.ee=JavaSE; version:Version=\"1.5.0\"", container);
1465 
1466 		container.resolve(Arrays.asList(systemBundle), true);
1467 
1468 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
1469 		Module c4 = installDummyModule("c4_v1.MF", "c4_v1", container);
1470 		Module dynamic3 = installDummyModule("dynamic3_v1.MF", "dynamic3_v1", container);
1471 		Module dynamic3Frag = installDummyModule("dynamic3.frag_v1.MF", "dynamic3.frag_v1", container);
1472 
1473 		container.resolve(Arrays.asList(c1, c4, dynamic3, dynamic3Frag), true);
1474 
1475 		ModuleWire dynamicWire = container.resolveDynamic("c4.a", dynamic3.getCurrentRevision());
1476 		Assert.assertNotNull("No dynamic wire found.", dynamicWire);
1477 		Assert.assertEquals("Wrong package found.", "c4.a", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1478 		Assert.assertEquals("Wrong provider for the wire found.", c4.getCurrentRevision(), dynamicWire.getProvider());
1479 
1480 		dynamicWire = container.resolveDynamic("c4.b", dynamic3.getCurrentRevision());
1481 		Assert.assertNotNull("No dynamic wire found.", dynamicWire);
1482 		Assert.assertEquals("Wrong package found.", "c4.b", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1483 		Assert.assertEquals("Wrong provider for the wire found.", c4.getCurrentRevision(), dynamicWire.getProvider());
1484 	}
1485 
1486 	@Test
testDynamicImport06()1487 	public void testDynamicImport06() throws BundleException, IOException {
1488 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1489 		ModuleContainer container = adaptor.getContainer();
1490 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1491 
1492 		container.resolve(Arrays.asList(systemBundle), true);
1493 
1494 		Module dynamic3 = installDummyModule("dynamic2_v1.MF", "dynamic2_v1", container);
1495 
1496 		container.resolve(Arrays.asList(systemBundle, dynamic3), true);
1497 
1498 		Module f1 = installDummyModule("f1_v1.MF", "f1_v1", container);
1499 
1500 		ModuleWire dynamicWire;
1501 		dynamicWire = container.resolveDynamic("h1.a", dynamic3.getCurrentRevision());
1502 		Assert.assertNull("Dynamic wire found.", dynamicWire);
1503 		dynamicWire = container.resolveDynamic("f1.a", dynamic3.getCurrentRevision());
1504 		Assert.assertNull("Dynamic wire found.", dynamicWire);
1505 
1506 		Module h1 = installDummyModule("h1_v1.MF", "h1_v1", container);
1507 
1508 		dynamicWire = container.resolveDynamic("h1.a", dynamic3.getCurrentRevision());
1509 		Assert.assertNotNull("Dynamic wire not found.", dynamicWire);
1510 		Assert.assertEquals("Wrong package found.", "h1.a", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1511 		Assert.assertEquals("Wrong host revision found.", h1.getCurrentRevision(), dynamicWire.getProvider());
1512 
1513 		dynamicWire = container.resolveDynamic("f1.a", dynamic3.getCurrentRevision());
1514 		Assert.assertNotNull("Dynamic wire not found.", dynamicWire);
1515 		Assert.assertEquals("Wrong package found.", "f1.a", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1516 		Assert.assertEquals("Wrong host revision found.", h1.getCurrentRevision(), dynamicWire.getProvider());
1517 
1518 		ModuleWiring h1Wiring = h1.getCurrentRevision().getWiring();
1519 		Assert.assertNotNull("h1 wiring is null.", h1Wiring);
1520 
1521 		ModuleWiring f1Wiring = f1.getCurrentRevision().getWiring();
1522 		Assert.assertNotNull("f1 wiring is null.", f1Wiring);
1523 	}
1524 
1525 	@Test
testDynamicImport07()1526 	public void testDynamicImport07() throws BundleException, IOException {
1527 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1528 		ModuleContainer container = adaptor.getContainer();
1529 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1530 
1531 		container.resolve(Arrays.asList(systemBundle), true);
1532 
1533 		Module dynamic3 = installDummyModule("dynamic2_v1.MF", "dynamic2_v1", container);
1534 
1535 		Assert.assertNull("Expected no resolution exception.", container.resolve(Arrays.asList(systemBundle, dynamic3), true).getResolutionException());
1536 
1537 		installDummyModule("c6_v1.MF", "c6_v1", container);
1538 
1539 		ModuleWire dynamicWire = container.resolveDynamic("c6", dynamic3.getCurrentRevision());
1540 		Assert.assertNull("Dynamic wire found.", dynamicWire);
1541 	}
1542 
1543 	@Test
testDynamicImport08()1544 	public void testDynamicImport08() throws BundleException, IOException {
1545 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1546 		ModuleContainer container = adaptor.getContainer();
1547 		DummyModuleDatabase database = adaptor.getDatabase();
1548 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1549 
1550 		container.resolve(Arrays.asList(systemBundle), true);
1551 
1552 		Module dynamic2 = installDummyModule("dynamic2_v1.MF", "dynamic2_v1", container);
1553 
1554 		container.resolve(Arrays.asList(systemBundle, dynamic2), true);
1555 
1556 		Module h1 = installDummyModule("h1_v1.MF", "h1_v1", container);
1557 		Module f1 = installDummyModule("f1_v1.MF", "f1_v1", container);
1558 		database.getModuleEvents();
1559 		// make sure h1 is not resolved
1560 		ModuleWiring h1Wiring = h1.getCurrentRevision().getWiring();
1561 		Assert.assertNull("h1 got resolved somehow.", h1Wiring);
1562 		// do not resolve the host first; make sure it gets pulled in while attempting to resolve
1563 		// to a fragment capability.
1564 		ModuleWire dynamicWire = container.resolveDynamic("f1.a", dynamic2.getCurrentRevision());
1565 		Assert.assertNotNull("Dynamic wire not found.", dynamicWire);
1566 		Assert.assertEquals("Wrong package found.", "f1.a", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1567 		Assert.assertEquals("Wrong provider for the wire found.", h1.getCurrentRevision(), dynamicWire.getProvider());
1568 
1569 		h1Wiring = h1.getCurrentRevision().getWiring();
1570 		Assert.assertNotNull("h1 wiring is null.", h1Wiring);
1571 
1572 		ModuleWiring f1Wiring = f1.getCurrentRevision().getWiring();
1573 		Assert.assertNotNull("f1 wiring is null.", f1Wiring);
1574 	}
1575 
1576 	@Test
testDynamicImportMiss01()1577 	public void testDynamicImportMiss01() throws BundleException, IOException {
1578 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1579 		ModuleContainer container = adaptor.getContainer();
1580 
1581 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, null, null, "osgi.ee; osgi.ee=JavaSE; version:Version=\"1.5.0\"", container);
1582 
1583 		container.resolve(Arrays.asList(systemBundle), true);
1584 		Module c1 = installDummyModule("c1_v1.MF", "c1_v1", container);
1585 		Module dynamic1 = installDummyModule("dynamic1_v1.MF", "dynamic1_v1", container);
1586 
1587 		container.resolve(Arrays.asList(c1, dynamic1), true);
1588 
1589 		DummyResolverHookFactory factory = (DummyResolverHookFactory) adaptor.getResolverHookFactory();
1590 		DummyResolverHook hook = (DummyResolverHook) factory.getHook();
1591 		hook.getResolutionReports().clear();
1592 		ModuleWire dynamicWire = container.resolveDynamic("org.osgi.framework", dynamic1.getCurrentRevision());
1593 		Assert.assertNotNull("No dynamic wire found.", dynamicWire);
1594 		Assert.assertEquals("Wrong package found.", "org.osgi.framework", dynamicWire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
1595 		Assert.assertEquals("Wrong provider for the wire found.", systemBundle.getCurrentRevision(), dynamicWire.getProvider());
1596 
1597 		Assert.assertEquals("Wrong number of reports.", 1, hook.getResolutionReports().size());
1598 		hook.getResolutionReports().clear();
1599 
1600 		dynamicWire = container.resolveDynamic("does.not.exist", dynamic1.getCurrentRevision());
1601 		Assert.assertNull("Unexpected Dynamic wire found.", dynamicWire);
1602 		Assert.assertEquals("Wrong number of reports.", 1, hook.getResolutionReports().size());
1603 
1604 		// Try again; no report should be generated a second time
1605 		hook.getResolutionReports().clear();
1606 		dynamicWire = container.resolveDynamic("does.not.exist", dynamic1.getCurrentRevision());
1607 		Assert.assertNull("Unexpected Dynamic wire found.", dynamicWire);
1608 		Assert.assertEquals("Wrong number of reports.", 0, hook.getResolutionReports().size());
1609 	}
1610 
1611 	@Test
testRequireBundleUses()1612 	public void testRequireBundleUses() throws BundleException, IOException {
1613 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1614 		ModuleContainer container = adaptor.getContainer();
1615 
1616 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1617 
1618 		container.resolve(Arrays.asList(systemBundle), true);
1619 		Module b1 = installDummyModule("require.b1.MF", "b1", container);
1620 		installDummyModule("require.b2.MF", "b2", container);
1621 		installDummyModule("require.b3.MF", "b3", container);
1622 		installDummyModule("require.b4.MF", "b4", container);
1623 
1624 		container.resolve(null, false);
1625 
1626 		Assert.assertEquals("b1 should not resolve.", State.INSTALLED, b1.getState());
1627 	}
1628 
1629 	/*
1630 	 * Test that a resolve process does not blow up because of one unresolvable uses constraint issue
1631 	 */
1632 	@Test
testUses1()1633 	public void testUses1() throws BundleException, IOException {
1634 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1635 		ModuleContainer container = adaptor.getContainer();
1636 
1637 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1638 
1639 		container.resolve(Arrays.asList(systemBundle), true);
1640 		Module uses_a = installDummyModule("uses.a.MF", "a", container);
1641 		Module uses_b = installDummyModule("uses.b.MF", "b", container);
1642 		Module uses_c = installDummyModule("uses.c.MF", "c", container);
1643 
1644 		container.resolve(null, false);
1645 
1646 		Assert.assertEquals("a should resolve.", State.RESOLVED, uses_a.getState());
1647 		Assert.assertEquals("b should resolve.", State.RESOLVED, uses_b.getState());
1648 		Assert.assertEquals("c should not resolve.", State.INSTALLED, uses_c.getState());
1649 	}
1650 
1651 	@Test
testUses1Dynamic()1652 	public void testUses1Dynamic() throws BundleException, IOException {
1653 		DummyContainerAdaptor adaptor = createDummyAdaptor(new DummyDebugOptions(Collections.singletonMap("org.eclipse.osgi/resolver/report", "true")));
1654 		ModuleContainer container = adaptor.getContainer();
1655 
1656 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1657 
1658 		container.resolve(Arrays.asList(systemBundle), true);
1659 		Module uses_a = installDummyModule("uses.a.MF", "a", container);
1660 		Module uses_b = installDummyModule("uses.b.MF", "b", container);
1661 		Module uses_c_dynamic = installDummyModule("uses.c.dynamic.MF", "c", container);
1662 
1663 		container.resolve(null, false);
1664 
1665 		Assert.assertEquals("a should resolve.", State.RESOLVED, uses_a.getState());
1666 		Assert.assertEquals("b should resolve.", State.RESOLVED, uses_b.getState());
1667 		Assert.assertEquals("c should resolve.", State.RESOLVED, uses_c_dynamic.getState());
1668 
1669 		ModuleWire dynamicWire = container.resolveDynamic("uses1", uses_c_dynamic.getCurrentRevision());
1670 		Assert.assertNotNull("No dynamic wire.", dynamicWire);
1671 
1672 		PrintStream originalOut = Debug.out;
1673 		ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
1674 		PrintStream testOut = new PrintStream(bytesOut);
1675 		Debug.out = testOut;
1676 		try {
1677 			dynamicWire = container.resolveDynamic("uses2", uses_c_dynamic.getCurrentRevision());
1678 			Assert.assertNull("Dynamic wire found.", dynamicWire);
1679 		} finally {
1680 			Debug.out = originalOut;
1681 			testOut.close();
1682 		}
1683 		String traceOutput = bytesOut.toString();
1684 		Assert.assertTrue("Wrong traceOutput: " + traceOutput, traceOutput.startsWith("org.apache.felix.resolver.reason.ReasonException"));
1685 	}
1686 
1687 	/*
1688 	 * Test that split packages are handled ok with uses constraints
1689 	 */
1690 	@Test
testUses2()1691 	public void testUses2() throws BundleException, IOException {
1692 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1693 		ModuleContainer container = adaptor.getContainer();
1694 
1695 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1696 
1697 		container.resolve(Arrays.asList(systemBundle), true);
1698 		Module uses_a = installDummyModule("uses.a.MF", "a", container);
1699 		Module uses_b = installDummyModule("uses.b.MF", "b", container);
1700 		Module uses_d = installDummyModule("uses.d.MF", "d", container);
1701 
1702 		container.resolve(null, false);
1703 
1704 		Assert.assertEquals("a should resolve.", State.RESOLVED, uses_a.getState());
1705 		Assert.assertEquals("b should resolve.", State.RESOLVED, uses_b.getState());
1706 		Assert.assertEquals("d should resolve.", State.RESOLVED, uses_d.getState());
1707 	}
1708 
1709 	/*
1710 	 * Test that split packages are handled ok with uses constraints
1711 	 */
1712 	@Test
testUses3()1713 	public void testUses3() throws BundleException, IOException {
1714 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1715 		ModuleContainer container = adaptor.getContainer();
1716 
1717 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1718 
1719 		container.resolve(Arrays.asList(systemBundle), true);
1720 		Module uses_a = installDummyModule("uses.a.MF", "a", container);
1721 		Module uses_b = installDummyModule("uses.b.MF", "b", container);
1722 		Module uses_e = installDummyModule("uses.e.MF", "e", container);
1723 		Module uses_f = installDummyModule("uses.f.MF", "f", container);
1724 		Module uses_g = installDummyModule("uses.g.MF", "g", container);
1725 
1726 		container.resolve(null, false);
1727 
1728 		Assert.assertEquals("a should resolve.", State.RESOLVED, uses_a.getState());
1729 		Assert.assertEquals("b should resolve.", State.RESOLVED, uses_b.getState());
1730 		Assert.assertEquals("e should resolve.", State.RESOLVED, uses_e.getState());
1731 		Assert.assertEquals("f should resolve.", State.RESOLVED, uses_f.getState());
1732 		Assert.assertEquals("g should not resolve.", State.INSTALLED, uses_g.getState());
1733 	}
1734 
1735 	/*
1736 	 * Test that fragments and uses constraints
1737 	 */
1738 	@Test
testUses4()1739 	public void testUses4() throws BundleException, IOException {
1740 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1741 		ModuleContainer container = adaptor.getContainer();
1742 
1743 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1744 
1745 		container.resolve(Arrays.asList(systemBundle), true);
1746 		Module uses_h = installDummyModule("uses.h.MF", "h", container);
1747 		Module uses_h_frag = installDummyModule("uses.h.frag.MF", "h.frag", container);
1748 
1749 		container.resolve(null, false);
1750 
1751 		Assert.assertEquals("h should resolve.", State.RESOLVED, uses_h.getState());
1752 		Assert.assertEquals("h.frag should resolve.", State.RESOLVED, uses_h_frag.getState());
1753 
1754 		Module uses_i = installDummyModule("uses.i.MF", "i", container);
1755 		Module uses_j = installDummyModule("uses.j.MF", "j", container);
1756 
1757 		container.resolve(null, false);
1758 
1759 		Assert.assertEquals("i should resolve.", State.RESOLVED, uses_i.getState());
1760 		Assert.assertEquals("j should resolve.", State.RESOLVED, uses_j.getState());
1761 
1762 		List<BundleWire> requiredWires = uses_j.getCurrentRevision().getWiring().getRequiredWires(null);
1763 		Assert.assertEquals("Wrong number of wires for j", 2, requiredWires.size());
1764 		for (BundleWire wire : requiredWires) {
1765 			Assert.assertEquals("Wrong provider", uses_i.getCurrentRevision(), wire.getProvider());
1766 		}
1767 
1768 		Module uses_j_dynamic = installDummyModule("uses.j.dynamic.MF", "j.dynamic", container);
1769 		container.resolve(null, false);
1770 		ModuleWire dynamicWire = container.resolveDynamic("uses2", uses_j_dynamic.getCurrentRevision());
1771 		Assert.assertNotNull("Null dynamic wire.", dynamicWire);
1772 		Assert.assertEquals("Wrong provider", uses_i.getCurrentRevision(), dynamicWire.getProvider());
1773 	}
1774 
1775 	/**
1776 	 * Test optional constraints
1777 	 * @throws BundleException
1778 	 * @throws IOException
1779 	 */
1780 	@Test
testUses5Importer()1781 	public void testUses5Importer() throws BundleException, IOException {
1782 		doTestUses5("uses.k.importer.MF");
1783 	}
1784 
1785 	@Test
testUses5ReqCap()1786 	public void testUses5ReqCap() throws BundleException, IOException {
1787 		doTestUses5("uses.k.reqCap.MF");
1788 	}
1789 
1790 	@Test
testUses5Requirer()1791 	public void testUses5Requirer() throws BundleException, IOException {
1792 		doTestUses5("uses.k.requirer.MF");
1793 	}
1794 
doTestUses5(String kManifest)1795 	public void doTestUses5(String kManifest) throws BundleException, IOException {
1796 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1797 		ModuleContainer container = adaptor.getContainer();
1798 
1799 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1800 
1801 		container.resolve(Arrays.asList(systemBundle), true);
1802 		Module uses_k = installDummyModule(kManifest, "k", container);
1803 		Module uses_l = installDummyModule("uses.l.MF", "l", container);
1804 		Module uses_m_conflict1 = installDummyModule("uses.m.conflict1.MF", "m.conflict1", container);
1805 		Module uses_m_conflict2 = installDummyModule("uses.m.conflict2.MF", "m.conflict2", container);
1806 
1807 		container.resolve(null, false);
1808 
1809 		Assert.assertEquals("k should resolve.", State.RESOLVED, uses_k.getState());
1810 		Assert.assertEquals("l should resolve.", State.RESOLVED, uses_l.getState());
1811 		Assert.assertEquals("m.conflict1 should resolve.", State.RESOLVED, uses_m_conflict1.getState());
1812 		Assert.assertEquals("m.conflict2 should resolve.", State.RESOLVED, uses_m_conflict2.getState());
1813 	}
1814 
1815 	@Test
testUses6FragConflicts()1816 	public void testUses6FragConflicts() throws BundleException, IOException {
1817 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1818 		ModuleContainer container = adaptor.getContainer();
1819 
1820 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1821 
1822 		container.resolve(Arrays.asList(systemBundle), true);
1823 		Module uses_n1 = installDummyModule("uses.n1.MF", "n1", container);
1824 		installDummyModule("uses.n2.MF", "n2", container);
1825 		Module uses_n2_frag = installDummyModule("uses.n2.frag.MF", "n2.frag", container);
1826 		Module uses_n3 = installDummyModule("uses.n3.MF", "n3", container);
1827 		ResolutionReport report = container.resolve(null, false);
1828 		Assert.assertNull("resolution report has a resolution exception.", report.getResolutionException());
1829 
1830 		Assert.assertEquals("n1 should resolve.", State.RESOLVED, uses_n1.getState());
1831 		// TODO The following should be true, but on the current resolver in Mars the host is thrown away also
1832 		//Assert.assertEquals("n2 should resolve.", State.RESOLVED, uses_n2.getState());
1833 		Assert.assertEquals("n2.frag should not resolve.", State.INSTALLED, uses_n2_frag.getState());
1834 		Assert.assertEquals("n3 should resolve.", State.RESOLVED, uses_n3.getState());
1835 	}
1836 
1837 	@Test
testUsesTimeout()1838 	public void testUsesTimeout() throws BundleException {
1839 		// Always want to go to zero threads when idle
1840 		int coreThreads = 0;
1841 		// use the number of processors - 1 because we use the current thread when rejected
1842 		int maxThreads = Math.max(Runtime.getRuntime().availableProcessors() - 1, 1);
1843 		// idle timeout; make it short to get rid of threads quickly after resolve
1844 		int idleTimeout = 5;
1845 		// use sync queue to force thread creation
1846 		BlockingQueue<Runnable> queue = new SynchronousQueue<>();
1847 		// try to name the threads with useful name
1848 		ThreadFactory threadFactory = new ThreadFactory() {
1849 			@Override
1850 			public Thread newThread(Runnable r) {
1851 				Thread t = new Thread(r, "Resolver thread - UNIT TEST"); //$NON-NLS-1$
1852 				t.setDaemon(true);
1853 				return t;
1854 			}
1855 		};
1856 		// use a rejection policy that simply runs the task in the current thread once the max threads is reached
1857 		RejectedExecutionHandler rejectHandler = new RejectedExecutionHandler() {
1858 			@Override
1859 			public void rejectedExecution(Runnable r, ThreadPoolExecutor exe) {
1860 				r.run();
1861 			}
1862 		};
1863 		ExecutorService executor = new ThreadPoolExecutor(coreThreads, maxThreads, idleTimeout, TimeUnit.SECONDS, queue, threadFactory, rejectHandler);
1864 		ScheduledExecutorService timeoutExecutor = new ScheduledThreadPoolExecutor(1);
1865 
1866 		Map<String, String> configuration = new HashMap<>();
1867 		configuration.put(EquinoxConfiguration.PROP_RESOLVER_BATCH_TIMEOUT, "5000");
1868 		Map<String, String> debugOpts = Collections.emptyMap();
1869 		DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(false), configuration, new DummyResolverHookFactory(), new DummyDebugOptions(debugOpts));
1870 		adaptor.setResolverExecutor(executor);
1871 		adaptor.setTimeoutExecutor(timeoutExecutor);
1872 		ModuleContainer container = adaptor.getContainer();
1873 		for (int i = 1; i <= 1000; i++) {
1874 			for (Map<String, String> manifest : getUsesTimeoutManifests("test" + i)) {
1875 				installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
1876 			}
1877 		}
1878 		ResolutionReport report = container.resolve(container.getModules(), true);
1879 		Assert.assertNull("Found resolution errors.", report.getResolutionException());
1880 		for (Module module : container.getModules()) {
1881 			Assert.assertEquals("Wrong state of module: " + module, State.RESOLVED, module.getState());
1882 		}
1883 		executor.shutdown();
1884 		timeoutExecutor.shutdown();
1885 		System.gc();
1886 		System.gc();
1887 		System.gc();
1888 	}
1889 
getUsesTimeoutManifests(String prefix)1890 	private List<Map<String, String>> getUsesTimeoutManifests(String prefix) {
1891 		List<Map<String, String>> result = new ArrayList<>();
1892 		// x1 bundle
1893 		Map<String, String> x1Manifest = new HashMap<>();
1894 		x1Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
1895 		x1Manifest.put(Constants.BUNDLE_SYMBOLICNAME, prefix + ".x1");
1896 		x1Manifest.put(Constants.EXPORT_PACKAGE, prefix + ".a; version=1.0; uses:=" + prefix + ".b");
1897 		x1Manifest.put(Constants.IMPORT_PACKAGE, prefix + ".b; version=\"[1.1,1.2)\"");
1898 		result.add(x1Manifest);
1899 		// x2 bundle
1900 		Map<String, String> x2Manifest = new HashMap<>();
1901 		x2Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
1902 		x2Manifest.put(Constants.BUNDLE_SYMBOLICNAME, prefix + ".x2");
1903 		x2Manifest.put(Constants.EXPORT_PACKAGE, prefix + ".a; version=1.1; uses:=" + prefix + ".b");
1904 		x2Manifest.put(Constants.IMPORT_PACKAGE, prefix + ".b; version=\"[1.0,1.1)\"");
1905 		result.add(x2Manifest);
1906 		// y1 bundle
1907 		Map<String, String> y1Manifest = new HashMap<>();
1908 		y1Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
1909 		y1Manifest.put(Constants.BUNDLE_SYMBOLICNAME, prefix + ".y1");
1910 		y1Manifest.put(Constants.EXPORT_PACKAGE, prefix + ".b; version=1.0");
1911 		result.add(y1Manifest);
1912 		// y1 bundle
1913 		Map<String, String> y2Manifest = new HashMap<>();
1914 		y2Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
1915 		y2Manifest.put(Constants.BUNDLE_SYMBOLICNAME, prefix + ".y2");
1916 		y2Manifest.put(Constants.EXPORT_PACKAGE, prefix + ".b; version=1.1");
1917 		result.add(y2Manifest);
1918 		// z1 bundle
1919 		Map<String, String> z1Manifest = new HashMap<>();
1920 		z1Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
1921 		z1Manifest.put(Constants.BUNDLE_SYMBOLICNAME, prefix + ".z1");
1922 		z1Manifest.put(Constants.IMPORT_PACKAGE, prefix + ".a, " + prefix + ".b");
1923 		result.add(z1Manifest);
1924 		return result;
1925 	}
1926 
1927 	@Test
testOptionalSubstituted()1928 	public void testOptionalSubstituted() throws BundleException, IOException {
1929 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1930 		ModuleContainer container = adaptor.getContainer();
1931 
1932 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1933 
1934 		container.resolve(Arrays.asList(systemBundle), true);
1935 		Module sub_n = installDummyModule("sub.n.MF", "n", container);
1936 		Module sub_l = installDummyModule("sub.l.MF", "l", container);
1937 		Module sub_m = installDummyModule("sub.m.MF", "m", container);
1938 
1939 		container.resolve(null, false);
1940 
1941 		Assert.assertEquals("l should resolve.", State.RESOLVED, sub_l.getState());
1942 		Assert.assertEquals("m should resolve.", State.RESOLVED, sub_m.getState());
1943 		Assert.assertEquals("n should resolve.", State.RESOLVED, sub_n.getState());
1944 	}
1945 
1946 	@Test
testStaticSubstituted()1947 	public void testStaticSubstituted() throws BundleException, IOException {
1948 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1949 		ModuleContainer container = adaptor.getContainer();
1950 
1951 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1952 
1953 		container.resolve(Arrays.asList(systemBundle), true);
1954 		Module sub_n = installDummyModule("sub.n.static.MF", "n", container);
1955 		Module sub_l = installDummyModule("sub.l.MF", "l", container);
1956 		Module sub_m = installDummyModule("sub.m.MF", "m", container);
1957 
1958 		container.resolve(null, false);
1959 
1960 		Assert.assertEquals("l should resolve.", State.RESOLVED, sub_l.getState());
1961 		Assert.assertEquals("m should resolve.", State.RESOLVED, sub_m.getState());
1962 		Assert.assertEquals("n should resolve.", State.RESOLVED, sub_n.getState());
1963 	}
1964 
1965 	@Test
testMultiCardinalityUses()1966 	public void testMultiCardinalityUses() throws BundleException, IOException {
1967 		DummyContainerAdaptor adaptor = createDummyAdaptor();
1968 		ModuleContainer container = adaptor.getContainer();
1969 
1970 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
1971 
1972 		container.resolve(Arrays.asList(systemBundle), true);
1973 
1974 		Module p5v100 = installDummyModule("p5_v100.MF", "p5_v100", container);
1975 		Module p5v101 = installDummyModule("p5_v101.MF", "p5_v101", container);
1976 		Module p5v110 = installDummyModule("p5_v110.MF", "p5_v110", container);
1977 		Module p5v111 = installDummyModule("p5_v111.MF", "p5_v111", container);
1978 		installDummyModule("p6_v100.MF", "p6_v100", container);
1979 		installDummyModule("p6_v110.MF", "p6_v110", container);
1980 		installDummyModule("p7_v100.MF", "p7_v100", container);
1981 		installDummyModule("p7_v110.MF", "p7_v110", container);
1982 
1983 		container.resolve(null, false);
1984 
1985 		Module c6v100 = installDummyModule("c6_v100.MF", "c6_v100", container);
1986 		Module c6v110 = installDummyModule("c6_v110.MF", "c6_v110", container);
1987 		Module c6v130 = installDummyModule("c6_v130.MF", "c6_v130", container);
1988 		Module c6v140 = installDummyModule("c6_v140.MF", "c6_v140", container);
1989 		Module c6v150 = installDummyModule("c6_v150.MF", "c6_v150", container);
1990 		Module c6v170 = installDummyModule("c6_v170.MF", "c6_v170", container);
1991 
1992 		//		Module c6v180 = installDummyModule("c6_v180.MF", "c6_v180", container);
1993 		//		Module c6v120 = installDummyModule("c6_v120.MF", "c6_v120", container);
1994 
1995 		container.resolve(null, false);
1996 
1997 		final String namespace5 = "namespace.5";
1998 		List<ModuleWire> p5v100Provided = p5v100.getCurrentRevision().getWiring().getProvidedModuleWires(namespace5);
1999 		List<ModuleWire> p5v101Provided = p5v101.getCurrentRevision().getWiring().getProvidedModuleWires(namespace5);
2000 		List<ModuleWire> p5v110Provided = p5v110.getCurrentRevision().getWiring().getProvidedModuleWires(namespace5);
2001 		List<ModuleWire> p5v111Provided = p5v111.getCurrentRevision().getWiring().getProvidedModuleWires(namespace5);
2002 
2003 		ModuleWiring c6v100Wiring = c6v100.getCurrentRevision().getWiring();
2004 		List<ModuleWire> c6v100Required = c6v100Wiring.getRequiredModuleWires(namespace5);
2005 		Assert.assertEquals("Wrong number of capabilities", 2, c6v100Required.size());
2006 		assertWires(c6v100Required, p5v100Provided, p5v101Provided);
2007 
2008 		ModuleWiring c6v110Wiring = c6v110.getCurrentRevision().getWiring();
2009 		List<ModuleWire> c6v110Required = c6v110Wiring.getRequiredModuleWires(namespace5);
2010 		Assert.assertEquals("Wrong number of capabilities", 2, c6v110Required.size());
2011 		assertWires(c6v110Required, p5v100Provided, p5v101Provided);
2012 
2013 		ModuleWiring c6v130Wiring = c6v130.getCurrentRevision().getWiring();
2014 		List<ModuleWire> c6v130Required = c6v130Wiring.getRequiredModuleWires(namespace5);
2015 		Assert.assertEquals("Wrong number of capabilities", 2, c6v130Required.size());
2016 		assertWires(c6v130Required, p5v100Provided, p5v101Provided);
2017 
2018 		ModuleWiring c6v140Wiring = c6v140.getCurrentRevision().getWiring();
2019 		List<ModuleWire> c6v140Required = c6v140Wiring.getRequiredModuleWires(namespace5);
2020 		Assert.assertEquals("Wrong number of capabilities", 2, c6v140Required.size());
2021 		assertWires(c6v140Required, p5v100Provided, p5v101Provided);
2022 
2023 		ModuleWiring c6v150Wiring = c6v150.getCurrentRevision().getWiring();
2024 		List<ModuleWire> c6v150Required = c6v150Wiring.getRequiredModuleWires(namespace5);
2025 		Assert.assertEquals("Wrong number of capabilities", 2, c6v150Required.size());
2026 		assertWires(c6v150Required, p5v110Provided, p5v111Provided);
2027 
2028 		ModuleWiring c6v170Wiring = c6v170.getCurrentRevision().getWiring();
2029 		List<ModuleWire> c6v170Required = c6v170Wiring.getRequiredModuleWires(namespace5);
2030 		Assert.assertEquals("Wrong number of capabilities", 2, c6v170Required.size());
2031 		assertWires(c6v170Required, p5v110Provided, p5v111Provided);
2032 
2033 		Module c6v160 = installDummyModule("c6_v160.MF", "c6_v160", container);
2034 
2035 		container.resolve(null, false);
2036 
2037 		Assert.assertNull("Bundle should not be resolved: " + c6v160, c6v160.getCurrentRevision().getWiring());
2038 
2039 		container.uninstall(c6v160);
2040 
2041 		Module c6v180 = installDummyModule("c6_v180.MF", "c6_v180", container);
2042 
2043 		container.resolve(null, false);
2044 
2045 		Assert.assertNull("Bundle should not be resolved: " + c6v180, c6v180.getCurrentRevision().getWiring());
2046 
2047 		container.uninstall(c6v180);
2048 	}
2049 
2050 	@Test
testCompatSingleton()2051 	public void testCompatSingleton() throws BundleException, IOException {
2052 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2053 		ModuleContainer container = adaptor.getContainer();
2054 		Module s1 = installDummyModule("compatSingleton1.MF", "s1", container);
2055 		Module s2 = installDummyModule("compatSingleton2.MF", "s2", container);
2056 		Module s3 = installDummyModule("compatSingleton3.MF", "s3", container);
2057 
2058 		String s1Singleton = s1.getCurrentRevision().getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).iterator().next().getDirectives().get(IdentityNamespace.CAPABILITY_SINGLETON_DIRECTIVE);
2059 		String s2Singleton = s2.getCurrentRevision().getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).iterator().next().getDirectives().get(IdentityNamespace.CAPABILITY_SINGLETON_DIRECTIVE);
2060 		String s3Singleton = s3.getCurrentRevision().getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).iterator().next().getDirectives().get(IdentityNamespace.CAPABILITY_SINGLETON_DIRECTIVE);
2061 
2062 		Assert.assertEquals("Wrong singleton directive: " + s1, "true", s1Singleton);
2063 		Assert.assertNull("Wrong singleton directive: " + s2, s2Singleton);
2064 		Assert.assertEquals("Wrong singleton directive: " + s3, "true", s3Singleton);
2065 	}
2066 
2067 	@Test
testCompatReprovide()2068 	public void testCompatReprovide() throws BundleException, IOException {
2069 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2070 		ModuleContainer container = adaptor.getContainer();
2071 		Module b1 = installDummyModule("compatReprovide1.MF", "b1", container);
2072 		Module b2 = installDummyModule("compatReprovide2.MF", "b2", container);
2073 		Module b3 = installDummyModule("compatReprovide3.MF", "b3", container);
2074 
2075 		String b1Visibility = b1.getCurrentRevision().getRequirements(BundleNamespace.BUNDLE_NAMESPACE).iterator().next().getDirectives().get(BundleNamespace.REQUIREMENT_VISIBILITY_DIRECTIVE);
2076 		String b2Visibility = b2.getCurrentRevision().getRequirements(BundleNamespace.BUNDLE_NAMESPACE).iterator().next().getDirectives().get(BundleNamespace.REQUIREMENT_VISIBILITY_DIRECTIVE);
2077 		String b3Visibility = b3.getCurrentRevision().getRequirements(BundleNamespace.BUNDLE_NAMESPACE).iterator().next().getDirectives().get(BundleNamespace.REQUIREMENT_VISIBILITY_DIRECTIVE);
2078 
2079 		Assert.assertEquals("Wrong visibility directive: " + b1, BundleNamespace.VISIBILITY_REEXPORT, b1Visibility);
2080 		Assert.assertNull("Wrong visibility directive: ", b2Visibility);
2081 		Assert.assertEquals("Wrong visibility directive: " + b2, BundleNamespace.VISIBILITY_REEXPORT, b3Visibility);
2082 	}
2083 
2084 	@Test
testCompatOptional()2085 	public void testCompatOptional() throws BundleException, IOException {
2086 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2087 		ModuleContainer container = adaptor.getContainer();
2088 		Module b1 = installDummyModule("compatOptional1.MF", "b1", container);
2089 		Module b2 = installDummyModule("compatOptional2.MF", "b2", container);
2090 		Module b3 = installDummyModule("compatOptional3.MF", "b3", container);
2091 
2092 		String b1BundleResolution = b1.getCurrentRevision().getRequirements(BundleNamespace.BUNDLE_NAMESPACE).iterator().next().getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
2093 		String b2BundleResolution = b2.getCurrentRevision().getRequirements(BundleNamespace.BUNDLE_NAMESPACE).iterator().next().getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
2094 		String b3BundleResolution = b3.getCurrentRevision().getRequirements(BundleNamespace.BUNDLE_NAMESPACE).iterator().next().getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
2095 
2096 		String b1PackageResolution = b1.getCurrentRevision().getRequirements(PackageNamespace.PACKAGE_NAMESPACE).iterator().next().getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
2097 		String b2PackageResolution = b2.getCurrentRevision().getRequirements(PackageNamespace.PACKAGE_NAMESPACE).iterator().next().getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
2098 		String b3PackageResolution = b3.getCurrentRevision().getRequirements(PackageNamespace.PACKAGE_NAMESPACE).iterator().next().getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE);
2099 
2100 		Assert.assertEquals("Wrong resolution directive: " + b1, Namespace.RESOLUTION_OPTIONAL, b1BundleResolution);
2101 		Assert.assertNull("Wrong resolution directive: ", b2BundleResolution);
2102 		Assert.assertEquals("Wrong resolution directive: " + b2, Namespace.RESOLUTION_OPTIONAL, b3BundleResolution);
2103 
2104 		Assert.assertEquals("Wrong resolution directive: " + b1, Namespace.RESOLUTION_OPTIONAL, b1PackageResolution);
2105 		Assert.assertNull("Wrong resolution directive: ", b2PackageResolution);
2106 		Assert.assertEquals("Wrong resolution directive: " + b2, Namespace.RESOLUTION_OPTIONAL, b3PackageResolution);
2107 	}
2108 
2109 	@Test
testCompatProvidePackage()2110 	public void testCompatProvidePackage() throws BundleException, IOException {
2111 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2112 		ModuleContainer container = adaptor.getContainer();
2113 		Module b1 = installDummyModule("compatProvidePackage1.MF", "b1", container);
2114 
2115 		List<ModuleCapability> packageCaps = b1.getCurrentRevision().getModuleCapabilities(PackageNamespace.PACKAGE_NAMESPACE);
2116 		Assert.assertEquals("Wrong number of exports", 5, packageCaps.size());
2117 
2118 		Assert.assertEquals("Wrong package name.", "foo", packageCaps.get(0).getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
2119 		Assert.assertEquals("Wrong package name.", "faa", packageCaps.get(1).getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
2120 		Assert.assertEquals("Wrong package name.", "bar", packageCaps.get(2).getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
2121 		Assert.assertEquals("Wrong package name.", "baz", packageCaps.get(3).getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
2122 		Assert.assertEquals("Wrong package name.", "biz", packageCaps.get(4).getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE));
2123 	}
2124 
2125 	@Test
testBug457118()2126 	public void testBug457118() throws BundleException, IOException {
2127 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2128 		ModuleContainer container = adaptor.getContainer();
2129 
2130 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
2131 
2132 		container.resolve(Arrays.asList(systemBundle), true);
2133 		Module e = installDummyModule("bug457118.e.MF", "e", container);
2134 		Module a = installDummyModule("bug457118.a.MF", "a", container);
2135 		Module b = installDummyModule("bug457118.b.MF", "b", container);
2136 		Module c = installDummyModule("bug457118.c.MF", "c", container);
2137 		Module d = installDummyModule("bug457118.d.MF", "d", container);
2138 
2139 		installDummyModule("bug457118.a2.MF", "a2", container);
2140 		installDummyModule("bug457118.b2.MF", "b2", container);
2141 		installDummyModule("bug457118.c2.MF", "c2", container);
2142 		installDummyModule("bug457118.d2.MF", "d2", container);
2143 
2144 		container.resolve(null, true);
2145 
2146 		Assert.assertEquals("e should resolve.", State.RESOLVED, e.getState());
2147 		Assert.assertEquals("a should resolve.", State.RESOLVED, a.getState());
2148 		Assert.assertEquals("b should resolve.", State.RESOLVED, b.getState());
2149 		Assert.assertEquals("c should resolve.", State.RESOLVED, c.getState());
2150 		Assert.assertEquals("d should resolve.", State.RESOLVED, d.getState());
2151 
2152 		List<ModuleWire> bundleWires = e.getCurrentRevision().getWiring().getRequiredModuleWires(BundleNamespace.BUNDLE_NAMESPACE);
2153 		Assert.assertEquals("Wrong number of bundle wires: " + bundleWires, 1, bundleWires.size());
2154 		Assert.assertEquals("Wrong bundle provider", a.getCurrentRevision(), bundleWires.get(0).getProvider());
2155 	}
2156 
2157 	@Test
testBadNativeCode()2158 	public void testBadNativeCode() throws IOException {
2159 		try {
2160 			OSGiManifestBuilderFactory.createBuilder(getManifest("bad.native.code.MF"));
2161 		} catch (BundleException e) {
2162 			Assert.assertEquals("Wrong exception type.", BundleException.MANIFEST_ERROR, e.getType());
2163 		}
2164 
2165 	}
2166 
2167 	@Test
testNativeWithFilterChars()2168 	public void testNativeWithFilterChars() throws BundleException, IOException {
2169 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2170 		ModuleContainer container = adaptor.getContainer();
2171 
2172 		// install the system.bundle
2173 		String extraCapabilities = "osgi.native; osgi.native.osname=\"Windows NT (unknown)\"";
2174 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, extraCapabilities, container);
2175 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
2176 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2177 
2178 		// install bundle with Bundle-NativeCode
2179 		Map<String, String> nativeCodeManifest = new HashMap<>();
2180 		nativeCodeManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2181 		nativeCodeManifest.put(Constants.BUNDLE_SYMBOLICNAME, "importer");
2182 		nativeCodeManifest.put(Constants.BUNDLE_NATIVECODE, //
2183 				"/lib/mylib.dll; osname=\"win32\"; osname=\"Windows NT (unknown)\"," + //
2184 						"/lib/mylib.lib; osname=\"Linux\"");
2185 
2186 		Module nativeCodeModule = installDummyModule(nativeCodeManifest, "nativeCodeBundle", container);
2187 
2188 		// unsatisfied optional and dynamic imports do not fail a resolve.
2189 		report = container.resolve(Arrays.asList(nativeCodeModule), true);
2190 		Assert.assertNull("Failed to resolve nativeCodeBundle.", report.getResolutionException());
2191 	}
2192 
2193 	@Test
testUTF8LineContinuation()2194 	public void testUTF8LineContinuation() throws BundleException, IOException {
2195 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2196 		ModuleContainer container = adaptor.getContainer();
2197 		String utfString = "a.with.�.multibyte";
2198 		while (utfString.getBytes(StandardCharsets.UTF_8).length < 500) {
2199 			Map<String, String> manifest = getUTFManifest(utfString);
2200 			Module testModule = installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
2201 			Assert.assertEquals("Wrong bns for the bundle.", utfString, testModule.getCurrentRevision().getSymbolicName());
2202 
2203 			ModuleCapability exportPackage = testModule.getCurrentRevision().getModuleCapabilities(PackageNamespace.PACKAGE_NAMESPACE).get(0);
2204 			ModuleRequirement importPackage = testModule.getCurrentRevision().getModuleRequirements(PackageNamespace.PACKAGE_NAMESPACE).get(0);
2205 
2206 			String actualPackageName = (String) exportPackage.getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE);
2207 			Assert.assertEquals("Wrong exported package name.", utfString, actualPackageName);
2208 
2209 			Assert.assertTrue("import does not match export: " + importPackage, importPackage.matches(exportPackage));
2210 
2211 			utfString = "a" + utfString;
2212 		}
2213 	}
2214 
2215 	@Test
testDynamicWithOptionalImport()2216 	public void testDynamicWithOptionalImport() throws BundleException, IOException {
2217 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2218 		ModuleContainer container = adaptor.getContainer();
2219 
2220 		// install the system.bundle
2221 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2222 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
2223 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2224 
2225 		// install an importer
2226 		Map<String, String> optionalImporterManifest = new HashMap<>();
2227 		optionalImporterManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2228 		optionalImporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "importer");
2229 		optionalImporterManifest.put(Constants.IMPORT_PACKAGE, "exporter; resolution:=optional");
2230 		optionalImporterManifest.put(Constants.DYNAMICIMPORT_PACKAGE, "exporter");
2231 		Module optionalImporterModule = installDummyModule(optionalImporterManifest, "optionalImporter", container);
2232 
2233 		// unsatisfied optional and dynamic imports do not fail a resolve.
2234 		report = container.resolve(Arrays.asList(optionalImporterModule), true);
2235 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2236 
2237 		//dynamic and optional imports are same. Optional import is not satisfied we should only see the dynamic import
2238 		List<BundleRequirement> importReqsList = optionalImporterModule.getCurrentRevision().getWiring().getRequirements(PackageNamespace.PACKAGE_NAMESPACE);
2239 		assertEquals("Wrong number of imports.", 1, importReqsList.size());
2240 		assertEquals("Import was not dynamic", PackageNamespace.RESOLUTION_DYNAMIC, importReqsList.get(0).getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE));
2241 
2242 		// install a exporter to satisfy existing optional import
2243 		Map<String, String> exporterManifest = new HashMap<>();
2244 		exporterManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2245 		exporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "exporter");
2246 		exporterManifest.put(Constants.EXPORT_PACKAGE, "exporter");
2247 		installDummyModule(exporterManifest, "exporter", container);
2248 
2249 		ModuleWire dynamicWire = container.resolveDynamic("exporter", optionalImporterModule.getCurrentRevision());
2250 		Assert.assertNotNull("Expected to find a dynamic wire.", dynamicWire);
2251 
2252 		// re-resolve importer
2253 		container.refresh(Collections.singleton(optionalImporterModule));
2254 
2255 		report = container.resolve(Arrays.asList(optionalImporterModule), true);
2256 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2257 
2258 		importReqsList = optionalImporterModule.getCurrentRevision().getWiring().getRequirements(PackageNamespace.PACKAGE_NAMESPACE);
2259 		assertEquals("Wrong number of imports.", 2, importReqsList.size());
2260 	}
2261 
2262 	@Test
testDynamicWithExport()2263 	public void testDynamicWithExport() throws BundleException, IOException {
2264 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2265 		ModuleContainer container = adaptor.getContainer();
2266 
2267 		// install the system.bundle
2268 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2269 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
2270 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2271 
2272 		// install an importer
2273 		Map<String, String> optionalImporterManifest = new HashMap<>();
2274 		optionalImporterManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2275 		optionalImporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "importer");
2276 		optionalImporterManifest.put(Constants.EXPORT_PACKAGE, "exporter");
2277 		optionalImporterManifest.put(Constants.DYNAMICIMPORT_PACKAGE, "exporter");
2278 		Module optionalImporterModule = installDummyModule(optionalImporterManifest, "optionalImporter", container);
2279 
2280 		// unsatisfied optional and dynamic imports do not fail a resolve.
2281 		report = container.resolve(Arrays.asList(optionalImporterModule), true);
2282 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2283 
2284 		//dynamic and optional imports are same. Optional import is not satisfied we should only see the dynamic import
2285 		List<BundleRequirement> importReqsList = optionalImporterModule.getCurrentRevision().getWiring().getRequirements(PackageNamespace.PACKAGE_NAMESPACE);
2286 		assertEquals("Wrong number of imports.", 1, importReqsList.size());
2287 		assertEquals("Import was not dynamic", PackageNamespace.RESOLUTION_DYNAMIC, importReqsList.get(0).getDirectives().get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE));
2288 
2289 		ModuleWire dynamicWire = container.resolveDynamic("exporter", optionalImporterModule.getCurrentRevision());
2290 		Assert.assertNull("Expected no dynamic wire.", dynamicWire);
2291 	}
2292 
2293 	@Test
testSubstitutableExport()2294 	public void testSubstitutableExport() throws BundleException, IOException {
2295 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2296 		ModuleContainer container = adaptor.getContainer();
2297 
2298 		// install the system.bundle
2299 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2300 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
2301 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2302 
2303 		// install an exporter with substitutable export.
2304 		Map<String, String> exporterManifest = new HashMap<>();
2305 		exporterManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2306 		exporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "exporter");
2307 		exporterManifest.put(Constants.EXPORT_PACKAGE, "exporter");
2308 		exporterManifest.put(Constants.IMPORT_PACKAGE, "exporter");
2309 		Module moduleSubsExport = installDummyModule(exporterManifest, "exporter", container);
2310 		report = container.resolve(Arrays.asList(moduleSubsExport), true);
2311 		Assert.assertNull("Failed to resolve", report.getResolutionException());
2312 		List<BundleRequirement> reqs = moduleSubsExport.getCurrentRevision().getWiring().getRequirements(PackageNamespace.PACKAGE_NAMESPACE);
2313 		assertEquals("Wrong number of imports.", 0, reqs.size());
2314 
2315 		container.uninstall(moduleSubsExport);
2316 
2317 		exporterManifest = new HashMap<>();
2318 		exporterManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2319 		exporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "substitutableExporter");
2320 		exporterManifest.put(Constants.EXPORT_PACKAGE, "exporter");
2321 		exporterManifest.put(Constants.IMPORT_PACKAGE, "exporter; pickme=true");
2322 
2323 		moduleSubsExport = installDummyModule(exporterManifest, "substitutableExporter", container);
2324 
2325 		exporterManifest = new HashMap<>();
2326 		exporterManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2327 		exporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "exporter");
2328 		exporterManifest.put(Constants.EXPORT_PACKAGE, "exporter; pickme=true");
2329 
2330 		Module moduleExport = installDummyModule(exporterManifest, "exporter", container);
2331 		report = container.resolve(Arrays.asList(moduleSubsExport/* ,moduleExport */), true);
2332 		Assert.assertNull("Failed to resolve", report.getResolutionException());
2333 
2334 		List<BundleCapability> caps = moduleSubsExport.getCurrentRevision().getWiring().getCapabilities(PackageNamespace.PACKAGE_NAMESPACE);
2335 		assertEquals("Wrong number of capabilities.", 0, caps.size());
2336 
2337 		reqs = moduleSubsExport.getCurrentRevision().getWiring().getRequirements(PackageNamespace.PACKAGE_NAMESPACE);
2338 		assertEquals("Wrong number of imports.", 1, reqs.size());
2339 
2340 		ModuleWiring wiring = moduleSubsExport.getCurrentRevision().getWiring();
2341 		List<ModuleWire> packageWires = wiring.getRequiredModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
2342 		Assert.assertEquals("Unexpected number of wires", 1, packageWires.size());
2343 		Assert.assertEquals("Wrong exporter", packageWires.get(0).getProviderWiring().getRevision(), moduleExport.getCurrentRevision());
2344 	}
2345 
2346 	@Test
testSubstitutableExportBatch()2347 	public void testSubstitutableExportBatch() throws BundleException, IOException {
2348 		DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(false), Collections.singletonMap(EquinoxConfiguration.PROP_RESOLVER_REVISION_BATCH_SIZE, Integer.toString(1)));
2349 		ModuleContainer container = adaptor.getContainer();
2350 
2351 		// install the system.bundle
2352 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2353 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
2354 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2355 
2356 		Map<String, String> manifest = new HashMap<>();
2357 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2358 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, "substitutableExporter");
2359 		manifest.put(Constants.EXPORT_PACKAGE, "exporter; uses:=usedPkg; version=1.1, usedPkg");
2360 		manifest.put(Constants.IMPORT_PACKAGE, "exporter; pickme=true");
2361 
2362 		Module moduleSubsExport = installDummyModule(manifest, "substitutableExporter", container);
2363 
2364 		manifest = new HashMap<>();
2365 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2366 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, "exporter");
2367 		manifest.put(Constants.EXPORT_PACKAGE, "exporter; version=1.0; pickme=true");
2368 		Module moduleExport = installDummyModule(manifest, "exporter", container);
2369 
2370 		manifest = new HashMap<>();
2371 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2372 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, "importer1");
2373 		manifest.put(Constants.IMPORT_PACKAGE, "exporter, usedPkg");
2374 		Module moduleImporter1 = installDummyModule(manifest, "importer1", container);
2375 
2376 		manifest = new HashMap<>();
2377 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2378 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, "importer2");
2379 		manifest.put(Constants.EXPORT_PACKAGE, "pkgUser; uses:=exporter");
2380 		manifest.put(Constants.IMPORT_PACKAGE, "exporter, usedPkg");
2381 		Module moduleImporter2 = installDummyModule(manifest, "importer2", container);
2382 
2383 		manifest = new HashMap<>();
2384 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2385 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, "importer3");
2386 		manifest.put(Constants.IMPORT_PACKAGE, "pkgUser, exporter");
2387 		Module moduleImporter3 = installDummyModule(manifest, "importer3", container);
2388 
2389 		report = container.resolve(Arrays.asList(moduleExport, moduleSubsExport, moduleImporter1, moduleImporter2, moduleImporter3), true);
2390 		Assert.assertNull("Failed to resolve", report.getResolutionException());
2391 
2392 		ModuleWiring subsExportWiring = moduleSubsExport.getCurrentRevision().getWiring();
2393 		Collection<String> substituteNames = subsExportWiring.getSubstitutedNames();
2394 		Assert.assertEquals("Wrong number of exports: " + substituteNames, 1, substituteNames.size());
2395 		List<ModuleWire> providedWires = moduleSubsExport.getCurrentRevision().getWiring().getProvidedModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
2396 		assertEquals("Wrong number of wires.", 2, providedWires.size());
2397 
2398 		ModuleWiring importer3Wiring = moduleImporter3.getCurrentRevision().getWiring();
2399 		for (ModuleWire wire : importer3Wiring.getRequiredModuleWires(PackageNamespace.PACKAGE_NAMESPACE)) {
2400 			if ("exporter".equals(wire.getCapability().getAttributes().get(PackageNamespace.PACKAGE_NAMESPACE))) {
2401 				assertEquals("wrong provider", moduleExport.getCurrentRevision(), wire.getProvider());
2402 			}
2403 
2404 		}
2405 	}
2406 
2407 	@Test
testR3()2408 	public void testR3() throws BundleException, IOException {
2409 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2410 		ModuleContainer container = adaptor.getContainer();
2411 		// install the system.bundle
2412 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2413 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
2414 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2415 
2416 		//R3 bundle
2417 		Map<String, String> exporterManifest = new HashMap<>();
2418 		exporterManifest = new HashMap<>();
2419 		exporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "exporter");
2420 		exporterManifest.put(Constants.EXPORT_PACKAGE, "exporter; version=\"1.1\"");
2421 
2422 		Module moduleExport = installDummyModule(exporterManifest, "exporter", container);
2423 		report = container.resolve(Arrays.asList(moduleExport, moduleExport), true);
2424 		Assert.assertNull("Failed to resolve", report.getResolutionException());
2425 		List<BundleRequirement> reqs = moduleExport.getCurrentRevision().getWiring().getRequirements(PackageNamespace.PACKAGE_NAMESPACE);
2426 		assertEquals("Wrong number of imports.", 0, reqs.size());
2427 
2428 		//R3 bundle
2429 		exporterManifest.clear();
2430 		exporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "dynamicExporter");
2431 		exporterManifest.put(Constants.EXPORT_PACKAGE, "exporter; version=\"1.0\"");
2432 		exporterManifest.put(Constants.DYNAMICIMPORT_PACKAGE, "exporter");
2433 		Module moduleWithDynExport = installDummyModule(exporterManifest, "dynamicExporter", container);
2434 		report = container.resolve(Arrays.asList(moduleWithDynExport), true);
2435 		Assert.assertNull("Failed to resolve", report.getResolutionException());
2436 		reqs = moduleWithDynExport.getCurrentRevision().getWiring().getRequirements(PackageNamespace.PACKAGE_NAMESPACE);
2437 		assertEquals("Wrong number of imports.", 2, reqs.size());
2438 
2439 		report = container.resolve(Arrays.asList(moduleWithDynExport), true);
2440 		Assert.assertNull("Failed to resolve", report.getResolutionException());
2441 		reqs = moduleWithDynExport.getCurrentRevision().getWiring().getRequirements(PackageNamespace.PACKAGE_NAMESPACE);
2442 		assertEquals("Wrong number of imports.", 2, reqs.size());
2443 		ModuleWiring wiring = moduleWithDynExport.getCurrentRevision().getWiring();
2444 		List<ModuleWire> packageWires = wiring.getRequiredModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
2445 		Assert.assertEquals("Unexpected number of wires", 1, packageWires.size());
2446 		Assert.assertEquals("Wrong exporter", packageWires.get(0).getProviderWiring().getRevision(), moduleExport.getCurrentRevision());
2447 	}
2448 
getUTFManifest(String packageName)2449 	private static Map<String, String> getUTFManifest(String packageName) throws IOException, BundleException {
2450 		// using manifest class to force a split line right in the middle of a double byte UTF-8 character
2451 		ByteArrayOutputStream out = new ByteArrayOutputStream();
2452 		{
2453 			Manifest m = new Manifest();
2454 			Attributes a = m.getMainAttributes();
2455 			a.put(MANIFEST_VERSION, "1.0");
2456 			a.putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
2457 			a.putValue(Constants.BUNDLE_SYMBOLICNAME, packageName);
2458 			a.putValue(Constants.EXPORT_PACKAGE, packageName);
2459 			a.putValue(Constants.IMPORT_PACKAGE, packageName);
2460 			m.write(out);
2461 		}
2462 		return ManifestElement.parseBundleManifest(new ByteArrayInputStream(out.toByteArray()), null);
2463 	}
2464 
2465 	@Test
testPersistence()2466 	public void testPersistence() throws BundleException, IOException {
2467 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2468 		ModuleContainer container = adaptor.getContainer();
2469 
2470 		// install the system.bundle
2471 		installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2472 
2473 		Map<String, Object> attrs = new HashMap<>();
2474 		attrs.put("string", "sValue");
2475 		attrs.put("string.list1", Arrays.asList("v1", "v2", "v3"));
2476 		attrs.put("string.list2", Arrays.asList("v4", "v5", "v6"));
2477 		attrs.put("version", Version.valueOf("1.1"));
2478 		attrs.put("version.list", Arrays.asList(Version.valueOf("1.0"), Version.valueOf("2.0"), Version.valueOf("3.0")));
2479 		attrs.put("long", Long.valueOf(12345));
2480 		attrs.put("long.list", Arrays.asList(Long.valueOf(1), Long.valueOf(2), Long.valueOf(3)));
2481 		attrs.put("double", Double.valueOf(1.2345));
2482 		attrs.put("double.list", Arrays.asList(Double.valueOf(1.1), Double.valueOf(1.2), Double.valueOf(1.3)));
2483 		attrs.put("uri", "some.uri");
2484 		attrs.put("set", Arrays.asList("s1", "s2", "s3"));
2485 
2486 		// provider with all supported types
2487 		Map<String, String> providerManifest = new HashMap<>();
2488 		providerManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2489 		providerManifest.put(Constants.BUNDLE_SYMBOLICNAME, "provider");
2490 		providerManifest.put(Constants.EXPORT_PACKAGE, "provider; version=1.1; attr1=attr1; attr2=attr2; dir1:=dir1; dir2:=dir2");
2491 		providerManifest.put(Constants.PROVIDE_CAPABILITY, "provider.cap;"//
2492 				+ " string=sValue;"//
2493 				+ " string.list1:List=\"v1,v2,v3\";"//
2494 				+ " string.list2:List<String>=\"v4,v5,v6\";"//
2495 				+ " version:Version=1.1;"//
2496 				+ " version.list:List<Version>=\"1.0,2.0,3.0\";"//
2497 				+ " long:Long=12345;"//
2498 				+ " long.list:List<Long>=\"1,2,3\";"//
2499 				+ " double:Double=1.2345;"//
2500 				+ " double.list:List<Double>=\"1.1,1.2,1.3\";"//
2501 				+ " uri:uri=some.uri;" //
2502 				+ " set:set=\"s1,s2,s3\"");
2503 		Module providerModule = installDummyModule(providerManifest, "provider", container);
2504 		Map<String, Object> providerAttrs = providerModule.getCurrentRevision().getCapabilities("provider.cap").get(0).getAttributes();
2505 		assertEquals("Wrong provider attrs", attrs, providerAttrs);
2506 
2507 		Map<String, String> requirerManifest = new HashMap<>();
2508 		requirerManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2509 		requirerManifest.put(Constants.BUNDLE_SYMBOLICNAME, "requirer");
2510 		requirerManifest.put(Constants.IMPORT_PACKAGE, "provider; version=1.1; attr1=attr1; attr2=attr2; dir1:=dir1; dir2:=dir2");
2511 		requirerManifest.put(Constants.REQUIRE_CAPABILITY, "optional;"//
2512 				+ " resolution:=optional; " //
2513 				+ " string=sValue;"//
2514 				+ " string.list1:List=\"v1,v2,v3\";"//
2515 				+ " string.list2:List<String>=\"v4,v5,v6\";"//
2516 				+ " version:Version=1.1;"//
2517 				+ " version.list:List<Version>=\"1.0,2.0,3.0\";"//
2518 				+ " long:Long=12345;"//
2519 				+ " long.list:List<Long>=\"1,2,3\";"//
2520 				+ " double:Double=1.2345;"//
2521 				+ " double.list:List<Double>=\"1.1,1.2,1.3\";"//
2522 				+ " uri:uri=some.uri;" //
2523 				+ " set:set=\"s1,s2,s3\"," //
2524 				+ "provider.cap; filter:=\"(string=sValue)\"," //
2525 				+ "provider.cap; filter:=\"(string.list1=v2)\"," //
2526 				+ "provider.cap; filter:=\"(string.list2=v5)\"," //
2527 				+ "provider.cap; filter:=\"(string.list2=v5)\"," //
2528 				+ "provider.cap; filter:=\"(&(version>=1.1)(version<=1.1.1))\"," //
2529 				+ "provider.cap; filter:=\"(&(version.list=1)(version.list=2))\"," //
2530 				+ "provider.cap; filter:=\"(long>=12344)\"," //
2531 				+ "provider.cap; filter:=\"(long.list=2)\"," //
2532 				+ "provider.cap; filter:=\"(double>=1.2)\"," //
2533 				+ "provider.cap; filter:=\"(double.list=1.2)\"," //
2534 				+ "provider.cap; filter:=\"(uri=some.uri)\"," //
2535 				+ "provider.cap; filter:=\"(set=s2)\"" //
2536 				+ "");
2537 		Module requirerModule = installDummyModule(requirerManifest, "requirer", container);
2538 		Map<String, Object> requirerAttrs = requirerModule.getCurrentRevision().getRequirements("optional").get(0).getAttributes();
2539 		assertEquals("Wrong requirer attrs", attrs, requirerAttrs);
2540 		ResolutionReport report = container.resolve(Collections.singleton(requirerModule), true);
2541 		assertNull("Error resolving.", report.getResolutionException());
2542 
2543 		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
2544 		DataOutputStream data = new DataOutputStream(bytes);
2545 		adaptor.getDatabase().store(data, true);
2546 
2547 		// reload into a new container
2548 		adaptor = createDummyAdaptor();
2549 		container = adaptor.getContainer();
2550 		adaptor.getDatabase().load(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray())));
2551 
2552 		providerModule = container.getModule("provider");
2553 		providerAttrs = providerModule.getCurrentRevision().getCapabilities("provider.cap").get(0).getAttributes();
2554 		assertEquals("Wrong provider attrs", attrs, providerAttrs);
2555 		assertNotNull("No provider found.", providerModule);
2556 
2557 		requirerModule = container.getModule("requirer");
2558 		assertNotNull("No requirer found.", requirerModule);
2559 		requirerAttrs = requirerModule.getCurrentRevision().getRequirements("optional").get(0).getAttributes();
2560 		assertEquals("Wrong requirer attrs", attrs, requirerAttrs);
2561 	}
2562 
2563 	@Test
testInvalidAttributes()2564 	public void testInvalidAttributes() throws IOException, BundleException {
2565 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2566 		ModuleContainer container = adaptor.getContainer();
2567 
2568 		// install the system.bundle
2569 		installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2570 
2571 		// provider with all supported types
2572 		Map<String, String> invalidAttrManifest = new HashMap<>();
2573 		invalidAttrManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2574 		invalidAttrManifest.put(Constants.BUNDLE_SYMBOLICNAME, "invalid");
2575 
2576 		invalidAttrManifest.put(Constants.PROVIDE_CAPABILITY, "provider.cap; invalid:Boolean=true");
2577 		checkInvalidManifest(invalidAttrManifest, container);
2578 
2579 		invalidAttrManifest.put(Constants.PROVIDE_CAPABILITY, "provider.cap; invalid:Integer=1");
2580 		checkInvalidManifest(invalidAttrManifest, container);
2581 
2582 		invalidAttrManifest.put(Constants.PROVIDE_CAPABILITY, "provider.cap; invalid:List<Boolean>=true");
2583 		checkInvalidManifest(invalidAttrManifest, container);
2584 
2585 		invalidAttrManifest.put(Constants.PROVIDE_CAPABILITY, "provider.cap; invalid:List<Integer>=1");
2586 		checkInvalidManifest(invalidAttrManifest, container);
2587 	}
2588 
checkInvalidManifest(Map<String, String> invalidAttrManifest, ModuleContainer container)2589 	private void checkInvalidManifest(Map<String, String> invalidAttrManifest, ModuleContainer container) {
2590 		try {
2591 			installDummyModule(invalidAttrManifest, "invalid", container);
2592 			fail("Expected to get a BundleException with MANIFEST_ERROR");
2593 		} catch (BundleException e) {
2594 			// find expected type
2595 			assertEquals("Wrong type.", BundleException.MANIFEST_ERROR, e.getType());
2596 		}
2597 	}
2598 
2599 	@Test
testStoreInvalidAttributes()2600 	public void testStoreInvalidAttributes() throws BundleException, IOException {
2601 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2602 		ModuleContainer container = adaptor.getContainer();
2603 
2604 		// install the system.bundle
2605 		installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2606 
2607 		Integer testInt = Integer.valueOf(1);
2608 		List<Integer> testIntList = Collections.singletonList(testInt);
2609 		ModuleRevisionBuilder builder = new ModuleRevisionBuilder();
2610 		builder.setSymbolicName("invalid.attr");
2611 		builder.setVersion(Version.valueOf("1.0.0"));
2612 		builder.addCapability("test", Collections.<String, String> emptyMap(), Collections.singletonMap("test", (Object) testInt));
2613 		builder.addCapability("test.list", Collections.<String, String> emptyMap(), Collections.singletonMap("test.list", (Object) testIntList));
2614 		Module invalid = container.install(null, builder.getSymbolicName(), builder, null);
2615 
2616 		Object testAttr = invalid.getCurrentRevision().getCapabilities("test").get(0).getAttributes().get("test");
2617 		assertEquals("Wrong test attr", testInt, testAttr);
2618 
2619 		Object testAttrList = invalid.getCurrentRevision().getCapabilities("test.list").get(0).getAttributes().get("test.list");
2620 		assertEquals("Wrong test list attr", testIntList, testAttrList);
2621 
2622 		ByteArrayOutputStream bytes = new ByteArrayOutputStream();
2623 		DataOutputStream data = new DataOutputStream(bytes);
2624 		adaptor.getDatabase().store(data, true);
2625 
2626 		List<DummyContainerEvent> events = adaptor.getDatabase().getContainerEvents();
2627 		// make sure we see the errors
2628 		assertEquals("Wrong number of events.", 2, events.size());
2629 		for (DummyContainerEvent event : events) {
2630 			assertEquals("Wrong type of event.", ContainerEvent.ERROR, event.type);
2631 			assertTrue("Wrong type of exception.", event.error instanceof BundleException);
2632 		}
2633 
2634 		// reload into a new container
2635 		adaptor = createDummyAdaptor();
2636 		container = adaptor.getContainer();
2637 		adaptor.getDatabase().load(new DataInputStream(new ByteArrayInputStream(bytes.toByteArray())));
2638 
2639 		invalid = container.getModule("invalid.attr");
2640 		assertNotNull("Could not find module.", invalid);
2641 
2642 		String testIntString = String.valueOf(testInt);
2643 		List<String> testIntStringList = Collections.singletonList(testIntString);
2644 		testAttr = invalid.getCurrentRevision().getCapabilities("test").get(0).getAttributes().get("test");
2645 		assertEquals("Wrong test attr", testIntString, testAttr);
2646 
2647 		testAttrList = invalid.getCurrentRevision().getCapabilities("test.list").get(0).getAttributes().get("test.list");
2648 		assertEquals("Wrong test list attr", testIntStringList, testAttrList);
2649 	}
2650 
2651 	@Test
testBug483849()2652 	public void testBug483849() throws BundleException, IOException {
2653 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2654 		ModuleContainer container = adaptor.getContainer();
2655 
2656 		// install and resolve host bundle
2657 		Module host = installDummyModule("bug483849.host.MF", "host", container);
2658 		ResolutionReport report = container.resolve(Arrays.asList(host), true);
2659 		Assert.assertNull("Failed to resolve host.", report.getResolutionException());
2660 
2661 		// install and dynamically attach a fragment that exports a package and resolve an importer
2662 		Module frag = installDummyModule("bug483849.frag.MF", "frag", container);
2663 		Module importer = installDummyModule("bug483849.importer.MF", "importer", container);
2664 		report = container.resolve(Arrays.asList(frag, importer), true);
2665 		Assert.assertNull("Failed to resolve test fragment and importer.", report.getResolutionException());
2666 		// get the count of package exports
2667 		ModuleWiring wiring = host.getCurrentRevision().getWiring();
2668 		int originalPackageCnt = wiring.getCapabilities(PackageNamespace.PACKAGE_NAMESPACE).size();
2669 
2670 		// update the host to generate a new revision
2671 		Map<String, String> updateManifest = getManifest("bug483849.host.MF");
2672 		ModuleRevisionBuilder updateBuilder = OSGiManifestBuilderFactory.createBuilder(updateManifest);
2673 		container.update(host, updateBuilder, null);
2674 		// refresh host which should force the importer to re-resolve to the new revision
2675 		report = container.refresh(Collections.singleton(host));
2676 
2677 		ModuleWiring importerWiring = importer.getCurrentRevision().getWiring();
2678 		Assert.assertNotNull("No wiring for importer.", importerWiring);
2679 		List<ModuleWire> importerPackageWires = importerWiring.getRequiredModuleWires(PackageNamespace.PACKAGE_NAMESPACE);
2680 		Assert.assertEquals("Wrong number of importer package Wires.", 1, importerPackageWires.size());
2681 
2682 		Assert.assertEquals("Wrong provider wiring.", host.getCurrentRevision().getWiring(), importerPackageWires.iterator().next().getProviderWiring());
2683 		Assert.assertEquals("Wrong provider revision.", host.getCurrentRevision(), importerPackageWires.iterator().next().getProviderWiring().getRevision());
2684 
2685 		wiring = host.getCurrentRevision().getWiring();
2686 		List<BundleCapability> packages = wiring.getCapabilities(PackageNamespace.PACKAGE_NAMESPACE);
2687 		Assert.assertEquals("Wrong number of host packages.", originalPackageCnt, packages.size());
2688 	}
2689 
2690 	@Test
testStartLevelDeadlock()2691 	public void testStartLevelDeadlock() throws BundleException, IOException {
2692 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2693 		ModuleContainer container = adaptor.getContainer();
2694 		container.getFrameworkStartLevel().setInitialBundleStartLevel(2);
2695 
2696 		// install the system.bundle
2697 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2698 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
2699 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2700 		systemBundle.start();
2701 
2702 		// install a module
2703 		Map<String, String> manifest = new HashMap<>();
2704 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2705 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, "module.test");
2706 		Module module = installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
2707 		adaptor.setSlowdownEvents(true);
2708 		module.setStartLevel(1);
2709 		module.start();
2710 
2711 		List<DummyContainerEvent> events = adaptor.getDatabase().getContainerEvents();
2712 		for (DummyContainerEvent event : events) {
2713 			Assert.assertNotEquals("Found an error: " + event.error, ContainerEvent.ERROR, event.type);
2714 		}
2715 	}
2716 
2717 	@Test
testSystemBundleOnDemandFragments()2718 	public void testSystemBundleOnDemandFragments() throws BundleException, IOException {
2719 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2720 		ModuleContainer container = adaptor.getContainer();
2721 
2722 		// install the system.bundle
2723 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2724 
2725 		// install an equinox fragment
2726 		Map<String, String> equinoxFragManifest = new HashMap<>();
2727 		equinoxFragManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2728 		equinoxFragManifest.put(Constants.BUNDLE_SYMBOLICNAME, "equinoxFrag");
2729 		equinoxFragManifest.put(Constants.FRAGMENT_HOST, "org.eclipse.osgi");
2730 		Module equinoxFrag = installDummyModule(equinoxFragManifest, "equinoxFrag", container);
2731 
2732 		// install a system.bundle fragment
2733 		Map<String, String> systemFragManifest = new HashMap<>();
2734 		systemFragManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2735 		systemFragManifest.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag");
2736 		systemFragManifest.put(Constants.FRAGMENT_HOST, "system.bundle");
2737 		Module systemFrag = installDummyModule(systemFragManifest, "systemFrag", container);
2738 
2739 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
2740 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2741 
2742 		List<ModuleWire> hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
2743 		assertEquals("Wrong number of fragments.", 2, hostWires.size());
2744 		Set<ModuleRevision> fragmentRevisions = new HashSet(Arrays.asList(equinoxFrag.getCurrentRevision(), systemFrag.getCurrentRevision()));
2745 		for (ModuleWire hostWire : hostWires) {
2746 			if (!fragmentRevisions.remove(hostWire.getRequirer())) {
2747 				Assert.fail("Unexpected fragment revision: " + hostWire.getRequirer());
2748 			}
2749 		}
2750 	}
2751 
2752 	@Test
testUnresolvedHostWithFragmentCycle()2753 	public void testUnresolvedHostWithFragmentCycle() throws BundleException {
2754 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2755 		ModuleContainer container = adaptor.getContainer();
2756 
2757 		// install a host
2758 		Map<String, String> hostManifest = new HashMap<>();
2759 		hostManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2760 		hostManifest.put(Constants.BUNDLE_SYMBOLICNAME, "host");
2761 		hostManifest.put(Constants.BUNDLE_VERSION, "1.0");
2762 		hostManifest.put(Constants.EXPORT_PACKAGE, "host");
2763 		hostManifest.put(Constants.IMPORT_PACKAGE, "host.impl");
2764 		installDummyModule(hostManifest, "host10", container);
2765 		hostManifest.put(Constants.BUNDLE_VERSION, "1.1");
2766 		installDummyModule(hostManifest, "host11", container);
2767 		hostManifest.put(Constants.BUNDLE_VERSION, "1.2");
2768 		installDummyModule(hostManifest, "host12", container);
2769 		//hostManifest.put(Constants.BUNDLE_VERSION, "1.3");
2770 		//installDummyModule(hostManifest, "host13", container);
2771 
2772 		// install a host.impl fragment
2773 		Map<String, String> hostImplManifest = new HashMap<>();
2774 		hostImplManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2775 		hostImplManifest.put(Constants.BUNDLE_SYMBOLICNAME, "host.impl");
2776 		hostImplManifest.put(Constants.EXPORT_PACKAGE, "host.impl");
2777 		hostImplManifest.put(Constants.IMPORT_PACKAGE, "host");
2778 		hostImplManifest.put(Constants.FRAGMENT_HOST, "host");
2779 		installDummyModule(hostImplManifest, "hostImpl", container);
2780 
2781 		// install an importer of host package
2782 		Map<String, String> hostImporterManifest = new HashMap<>();
2783 		hostImporterManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2784 		hostImporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "host.importer");
2785 		hostImporterManifest.put(Constants.IMPORT_PACKAGE, "host");
2786 		Module hostImporter = installDummyModule(hostImporterManifest, "hostImporter", container);
2787 
2788 		ResolutionReport report = container.resolve(Arrays.asList(hostImporter), true);
2789 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
2790 	}
2791 
2792 	@Test
testMultiHostFragmentWithOverlapImport()2793 	public void testMultiHostFragmentWithOverlapImport() throws BundleException {
2794 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2795 		ModuleContainer container = adaptor.getContainer();
2796 
2797 		// install an exporter
2798 		Map<String, String> exporterManifest = new HashMap<>();
2799 		exporterManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2800 		exporterManifest.put(Constants.BUNDLE_SYMBOLICNAME, "exporter");
2801 		exporterManifest.put(Constants.BUNDLE_VERSION, "1.0");
2802 		exporterManifest.put(Constants.EXPORT_PACKAGE, "exporter");
2803 		installDummyModule(exporterManifest, "exporter", container);
2804 
2805 		// install a fragment to the exporter
2806 		Map<String, String> exporterFragManifest = new HashMap<>();
2807 		exporterFragManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2808 		exporterFragManifest.put(Constants.BUNDLE_SYMBOLICNAME, "exporter.frag");
2809 		exporterFragManifest.put(Constants.EXPORT_PACKAGE, "exporter.frag");
2810 		exporterFragManifest.put(Constants.FRAGMENT_HOST, "exporter");
2811 		installDummyModule(exporterFragManifest, "exporter.frag", container);
2812 
2813 		// install a host that imports the exporter
2814 		Map<String, String> hostManifest = new HashMap<>();
2815 		hostManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2816 		hostManifest.put(Constants.BUNDLE_SYMBOLICNAME, "host");
2817 		hostManifest.put(Constants.BUNDLE_VERSION, "1.0");
2818 		hostManifest.put(Constants.IMPORT_PACKAGE, "exporter");
2819 		installDummyModule(hostManifest, "host10", container);
2820 		hostManifest.put(Constants.BUNDLE_VERSION, "1.1");
2821 		installDummyModule(hostManifest, "host11", container);
2822 		hostManifest.put(Constants.BUNDLE_VERSION, "1.2");
2823 		installDummyModule(hostManifest, "host12", container);
2824 
2825 		// install a fragment that also imports the exporter
2826 		Map<String, String> hostFragManifest = new HashMap<>();
2827 		hostFragManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2828 		hostFragManifest.put(Constants.BUNDLE_SYMBOLICNAME, "host.frag");
2829 		hostFragManifest.put(Constants.FRAGMENT_HOST, "host");
2830 		hostFragManifest.put(Constants.IMPORT_PACKAGE, "exporter; version=0.0");
2831 		Module hostFrag = installDummyModule(hostFragManifest, "host.frag", container);
2832 
2833 		ResolutionReport report = container.resolve(Arrays.asList(hostFrag), true);
2834 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
2835 	}
2836 
2837 	@Test
testModuleWiringToString()2838 	public void testModuleWiringToString() throws BundleException {
2839 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2840 		ModuleContainer container = adaptor.getContainer();
2841 
2842 		// install a test module
2843 		Map<String, String> testManifest = new HashMap<>();
2844 		testManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2845 		testManifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.name");
2846 		testManifest.put(Constants.BUNDLE_VERSION, "1.0");
2847 		Module testModule = installDummyModule(testManifest, "host10", container);
2848 
2849 		ResolutionReport report = container.resolve(Arrays.asList(testModule), true);
2850 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
2851 
2852 		ModuleRevision revision = testModule.getCurrentRevision();
2853 		ModuleWiring wiring = revision.getWiring();
2854 		Assert.assertEquals("Unexpected wiring.toString()", revision.toString(), wiring.toString());
2855 	}
2856 
2857 	@Test
testStartOnResolve()2858 	public void testStartOnResolve() throws BundleException, IOException {
2859 		doTestStartOnResolve(true);
2860 	}
2861 
2862 	@Test
testDisableStartOnResolve()2863 	public void testDisableStartOnResolve() throws BundleException, IOException {
2864 		doTestStartOnResolve(false);
2865 	}
2866 
doTestStartOnResolve(boolean enabled)2867 	private void doTestStartOnResolve(boolean enabled) throws BundleException, IOException {
2868 		Map<String, String> configuration = new HashMap<>();
2869 		if (!enabled) {
2870 			configuration.put(EquinoxConfiguration.PROP_MODULE_AUTO_START_ON_RESOLVE, Boolean.toString(false));
2871 		}
2872 		DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(false), configuration);
2873 		ModuleContainer container = adaptor.getContainer();
2874 
2875 		// install the system.bundle
2876 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2877 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
2878 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2879 		systemBundle.start();
2880 
2881 		// install a bunch of modules
2882 		Map<String, String> manifest = new HashMap<>();
2883 		List<Module> modules = new ArrayList<>();
2884 		for (int i = 0; i < 5; i++) {
2885 			manifest.clear();
2886 			manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2887 			manifest.put(Constants.BUNDLE_SYMBOLICNAME, "module." + i);
2888 			manifest.put(Constants.IMPORT_PACKAGE, "export");
2889 			Module module = installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
2890 			try {
2891 				module.start();
2892 				fail("expected a bundle exception.");
2893 			} catch (BundleException e) {
2894 				// do nothing
2895 			}
2896 			modules.add(module);
2897 		}
2898 
2899 		manifest.clear();
2900 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2901 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, "exporter");
2902 		manifest.put(Constants.EXPORT_PACKAGE, "export");
2903 		installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
2904 
2905 		report = container.resolve(Collections.<Module> emptySet(), false);
2906 		Assert.assertNull("Found a error.", report.getResolutionException());
2907 
2908 		State expectedState = enabled ? State.ACTIVE : State.RESOLVED;
2909 		for (Module module : modules) {
2910 			Assert.assertEquals("Wrong state.", expectedState, module.getState());
2911 		}
2912 	}
2913 
2914 	@Test
testResolveDeadlock()2915 	public void testResolveDeadlock() throws BundleException, IOException, InterruptedException {
2916 		DummyContainerAdaptor adaptor = createDummyAdaptor();
2917 		ModuleContainer container = adaptor.getContainer();
2918 
2919 		// install the system.bundle
2920 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
2921 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
2922 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
2923 		systemBundle.start();
2924 
2925 		// install a bunch of modules
2926 		Map<String, String> manifest = new HashMap<>();
2927 		List<Module> modules = new ArrayList<>();
2928 		for (int i = 0; i < 5; i++) {
2929 			manifest.clear();
2930 			manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2931 			manifest.put(Constants.BUNDLE_SYMBOLICNAME, "module." + i);
2932 			modules.add(installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container));
2933 		}
2934 		adaptor.setSlowdownEvents(true);
2935 		final ConcurrentLinkedQueue<BundleException> startErrors = new ConcurrentLinkedQueue<>();
2936 		final ExecutorService executor = Executors.newFixedThreadPool(5);
2937 		try {
2938 			for (final Module module : modules) {
2939 
2940 				executor.execute(new Runnable() {
2941 
2942 					@Override
2943 					public void run() {
2944 						try {
2945 							module.start();
2946 						} catch (BundleException e) {
2947 							startErrors.offer(e);
2948 							e.printStackTrace();
2949 						}
2950 					}
2951 				});
2952 			}
2953 		} finally {
2954 			executor.shutdown();
2955 			executor.awaitTermination(5, TimeUnit.MINUTES);
2956 			systemBundle.stop();
2957 		}
2958 
2959 		Assert.assertNull("Found a error.", startErrors.poll());
2960 		List<DummyContainerEvent> events = adaptor.getDatabase().getContainerEvents();
2961 		for (DummyContainerEvent event : events) {
2962 			Assert.assertNotEquals("Found an error.", ContainerEvent.ERROR, event.type);
2963 		}
2964 	}
2965 
2966 	class RecurseResolverHook implements ResolverHook {
2967 		volatile ModuleContainer container;
2968 		volatile Module dynamicImport;
2969 		final AtomicInteger id = new AtomicInteger();
2970 		List<IllegalStateException> expectedErrors = Collections.synchronizedList(new ArrayList<IllegalStateException>());
2971 
2972 		@Override
filterResolvable(Collection<BundleRevision> candidates)2973 		public void filterResolvable(Collection<BundleRevision> candidates) {
2974 			ModuleContainer current = container;
2975 			if (current != null) {
2976 				int nextId = id.incrementAndGet();
2977 				if (nextId >= 2) {
2978 					// Don't do this again
2979 					return;
2980 				}
2981 				Map<String, String> manifest = new HashMap<>();
2982 				manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
2983 				manifest.put(Constants.BUNDLE_SYMBOLICNAME, "module.recurse." + nextId);
2984 				try {
2985 					Module m = installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), current);
2986 					ResolutionReport report = current.resolve(Collections.singleton(m), false);
2987 					report.getResolutionException();
2988 				} catch (IllegalStateException e) {
2989 					expectedErrors.add(e);
2990 				} catch (BundleException e) {
2991 					// TODO Auto-generated catch block
2992 					e.printStackTrace();
2993 				}
2994 
2995 				Module curDynamicImport = dynamicImport;
2996 				if (curDynamicImport != null) {
2997 					try {
2998 						current.resolveDynamic("org.osgi.framework", curDynamicImport.getCurrentRevision());
2999 					} catch (IllegalStateException e) {
3000 						expectedErrors.add(e);
3001 					}
3002 				}
3003 			}
3004 		}
3005 
3006 		@Override
filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates)3007 		public void filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates) {
3008 			// nothing
3009 		}
3010 
3011 		@Override
filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates)3012 		public void filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates) {
3013 			// nothing
3014 		}
3015 
3016 		@Override
end()3017 		public void end() {
3018 			// nothing
3019 		}
3020 
getExpectedErrors()3021 		List<IllegalStateException> getExpectedErrors() {
3022 			return new ArrayList<>(expectedErrors);
3023 		}
3024 	}
3025 
3026 	@Test
testRecurseResolutionPermits()3027 	public void testRecurseResolutionPermits() throws BundleException, IOException {
3028 		RecurseResolverHook resolverHook = new RecurseResolverHook();
3029 		DummyContainerAdaptor adaptor = createDummyAdaptor(resolverHook);
3030 		final ModuleContainer container = adaptor.getContainer();
3031 
3032 		// install the system.bundle
3033 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
3034 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
3035 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
3036 		systemBundle.start();
3037 
3038 		// install a bundle to do dynamic resolution from
3039 		Map<String, String> manifest = new HashMap<>();
3040 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3041 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, "dynamicImport");
3042 		manifest.put(Constants.DYNAMICIMPORT_PACKAGE, "*");
3043 		final Module dynamicImport = installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
3044 		dynamicImport.start();
3045 		resolverHook.dynamicImport = dynamicImport;
3046 		resolverHook.container = container;
3047 
3048 		final AtomicReference<ModuleWire> dynamicWire = new AtomicReference<>();
3049 		Runnable runForEvents = new Runnable() {
3050 			@Override
3051 			public void run() {
3052 				dynamicWire.set(container.resolveDynamic("org.osgi.framework", dynamicImport.getCurrentRevision()));
3053 			}
3054 		};
3055 		adaptor.setRunForEvents(runForEvents);
3056 		// install a bundle to resolve
3057 		manifest.clear();
3058 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3059 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, "initial");
3060 		Module m = installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
3061 		m.start();
3062 
3063 		assertNotNull("No Dynamic Wire", dynamicWire.get());
3064 		assertEquals("Wrong number of exected errors.", 2, resolverHook.getExpectedErrors().size());
3065 	}
3066 
3067 	@Test
testSystemBundleFragmentsPackageImport()3068 	public void testSystemBundleFragmentsPackageImport() throws BundleException, IOException {
3069 		// install the system.bundle
3070 		Module systemBundle = createContainerWithSystemBundle(true);
3071 		ModuleContainer container = systemBundle.getContainer();
3072 
3073 		// install an system.bundle fragment that imports framework package
3074 		Map<String, String> systemFragManifest = new HashMap<>();
3075 		systemFragManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3076 		systemFragManifest.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag");
3077 		systemFragManifest.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3078 		systemFragManifest.put(Constants.IMPORT_PACKAGE, "org.osgi.framework");
3079 
3080 		Module systemFrag = installDummyModule(systemFragManifest, "systemFrag", container);
3081 
3082 		ResolutionReport report = container.resolve(Arrays.asList(systemFrag), true);
3083 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
3084 
3085 		List<ModuleWire> hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3086 		assertEquals("Wrong number of fragments.", 1, hostWires.size());
3087 		Assert.assertEquals("Unexpected fragment revision: " + hostWires, systemFrag.getCurrentRevision(), hostWires.get(0).getRequirer());
3088 
3089 		List<ModuleWire> systemBundleRequiredWires = systemBundle.getCurrentRevision().getWiring().getRequiredModuleWires(null);
3090 		assertEquals("No required wires expected.", 0, systemBundleRequiredWires.size());
3091 	}
3092 
3093 	@Test
testSystemBundleFragmentsNonPayloadRequirements()3094 	public void testSystemBundleFragmentsNonPayloadRequirements() throws BundleException, IOException {
3095 		// install the system.bundle
3096 		Module systemBundle = createContainerWithSystemBundle(true);
3097 		ModuleContainer container = systemBundle.getContainer();
3098 
3099 		// install an system.bundle fragment that imports framework package
3100 		Map<String, String> systemFragManifest = new HashMap<>();
3101 		systemFragManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3102 		systemFragManifest.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag");
3103 		systemFragManifest.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3104 		systemFragManifest.put(Constants.REQUIRE_CAPABILITY, "osgi.ee; filter:=\"(osgi.ee=JavaSE)\"");
3105 
3106 		Module systemFrag = installDummyModule(systemFragManifest, "systemFrag", container);
3107 
3108 		ResolutionReport report = container.resolve(Arrays.asList(systemFrag), true);
3109 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
3110 
3111 		List<ModuleWire> hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3112 		assertEquals("Wrong number of fragments.", 1, hostWires.size());
3113 		Assert.assertEquals("Unexpected fragment revision: " + hostWires, systemFrag.getCurrentRevision(), hostWires.get(0).getRequirer());
3114 
3115 		List<ModuleWire> systemBundleRequiredWires = systemBundle.getCurrentRevision().getWiring().getRequiredModuleWires(null);
3116 		assertEquals("No required wires expected.", 0, systemBundleRequiredWires.size());
3117 
3118 		List<ModuleWire> fragRequiredWires = systemFrag.getCurrentRevision().getWiring().getRequiredModuleWires(null);
3119 		assertEquals("Wrong number of required wires.", 2, fragRequiredWires.size());
3120 		assertWires(fragRequiredWires, systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(null));
3121 	}
3122 
3123 	@Test
testSystemBundleFragmentsWithPayloadRequirements()3124 	public void testSystemBundleFragmentsWithPayloadRequirements() throws BundleException, IOException {
3125 		// install the system.bundle
3126 		Module systemBundle = createContainerWithSystemBundle(true);
3127 		ModuleContainer container = systemBundle.getContainer();
3128 
3129 		// install an system.bundle fragment that requires a payload requirement from system.bundle
3130 		Map<String, String> systemFragManifest = new HashMap<>();
3131 		systemFragManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3132 		systemFragManifest.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag");
3133 		systemFragManifest.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3134 		systemFragManifest.put(Constants.REQUIRE_CAPABILITY, "equinox.test; filter:=\"(equinox.test=system)\"");
3135 
3136 		Module systemFrag = installDummyModule(systemFragManifest, "systemFrag", container);
3137 
3138 		ResolutionReport report = container.resolve(Arrays.asList(systemFrag), true);
3139 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
3140 
3141 		List<ModuleWire> hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3142 		assertEquals("Wrong number of fragments.", 1, hostWires.size());
3143 		Assert.assertEquals("Unexpected fragment revision: " + hostWires, systemFrag.getCurrentRevision(), hostWires.get(0).getRequirer());
3144 
3145 		List<ModuleWire> systemBundleRequiredWires = systemBundle.getCurrentRevision().getWiring().getRequiredModuleWires(null);
3146 		assertEquals("Wrong number of wires.", 1, systemBundleRequiredWires.size());
3147 		assertEquals("Wrong requirer.", systemBundle.getCurrentRevision(), systemBundleRequiredWires.get(0).getRequirer());
3148 		assertEquals("Wrong requirement.", systemFrag.getCurrentRevision(), systemBundleRequiredWires.get(0).getRequirement().getRevision());
3149 
3150 		List<ModuleWire> fragRequiredWires = systemFrag.getCurrentRevision().getWiring().getRequiredModuleWires(null);
3151 		assertEquals("Wrong number of required wires.", 1, fragRequiredWires.size());
3152 		assertWires(fragRequiredWires, hostWires);
3153 	}
3154 
3155 	@Test
testSystemBundleFragmentRequiresOtherFragment()3156 	public void testSystemBundleFragmentRequiresOtherFragment() throws BundleException, IOException {
3157 		// install the system.bundle
3158 		Module systemBundle = createContainerWithSystemBundle(true);
3159 		ModuleContainer container = systemBundle.getContainer();
3160 
3161 		// install an system.bundle fragment that provides a capability
3162 		Map<String, String> systemFragManifest1 = new HashMap<>();
3163 		systemFragManifest1.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3164 		systemFragManifest1.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag1");
3165 		systemFragManifest1.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3166 		systemFragManifest1.put(Constants.PROVIDE_CAPABILITY, "fragment.capability; fragment.capability=test");
3167 		Module systemFrag1 = installDummyModule(systemFragManifest1, "systemFrag1", container);
3168 
3169 		// install an system.bundle fragment that requires a fragment capability
3170 		Map<String, String> systemFragManifest2 = new HashMap<>();
3171 		systemFragManifest2.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3172 		systemFragManifest2.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag2");
3173 		systemFragManifest2.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3174 		systemFragManifest2.put(Constants.REQUIRE_CAPABILITY, "fragment.capability; filter:=\"(fragment.capability=test)\"");
3175 		Module systemFrag2 = installDummyModule(systemFragManifest2, "systemFrag2", container);
3176 
3177 		ResolutionReport report = container.resolve(Arrays.asList(systemFrag2), true);
3178 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
3179 
3180 		List<ModuleWire> hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3181 		assertEquals("Wrong number of fragments.", 2, hostWires.size());
3182 
3183 		List<ModuleWire> systemBundleRequiredWires = systemBundle.getCurrentRevision().getWiring().getRequiredModuleWires(null);
3184 		assertEquals("Wrong number of wires.", 1, systemBundleRequiredWires.size());
3185 		assertEquals("Wrong requirer.", systemBundle.getCurrentRevision(), systemBundleRequiredWires.get(0).getRequirer());
3186 		assertEquals("Wrong requirement.", systemFrag2.getCurrentRevision(), systemBundleRequiredWires.get(0).getRequirement().getRevision());
3187 		assertEquals("Wrong provider.", systemBundle.getCurrentRevision(), systemBundleRequiredWires.get(0).getProvider());
3188 		assertEquals("Wrong capability.", systemFrag1.getCurrentRevision(), systemBundleRequiredWires.get(0).getCapability().getRevision());
3189 
3190 		List<ModuleWire> fragRequiredWires = systemFrag2.getCurrentRevision().getWiring().getRequiredModuleWires(null);
3191 		assertEquals("Wrong number of required wires.", 1, fragRequiredWires.size());
3192 		assertWires(fragRequiredWires, hostWires);
3193 	}
3194 
3195 	@Test
testSystemBundleFragmentRequiresOtherFragmentFailResolution()3196 	public void testSystemBundleFragmentRequiresOtherFragmentFailResolution() throws BundleException, IOException {
3197 		// install the system.bundle
3198 		Module systemBundle = createContainerWithSystemBundle(true);
3199 		ModuleContainer container = systemBundle.getContainer();
3200 
3201 		// install an system.bundle fragment that provides a capability
3202 		Map<String, String> systemFragManifest1 = new HashMap<>();
3203 		systemFragManifest1.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3204 		systemFragManifest1.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag1");
3205 		systemFragManifest1.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3206 		systemFragManifest1.put(Constants.PROVIDE_CAPABILITY, "fragment.capability; fragment.capability=test1");
3207 		Module systemFrag1 = installDummyModule(systemFragManifest1, "systemFrag1", container);
3208 
3209 		// install an system.bundle fragment that requires a fragment capability, but fails to match
3210 		Map<String, String> systemFragManifest2 = new HashMap<>();
3211 		systemFragManifest2.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3212 		systemFragManifest2.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag2");
3213 		systemFragManifest2.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3214 		systemFragManifest2.put(Constants.REQUIRE_CAPABILITY, "fragment.capability; filter:=\"(fragment.capability=test4)\"");
3215 		systemFragManifest2.put(Constants.PROVIDE_CAPABILITY, "fragment.capability; fragment.capability=test2");
3216 		Module systemFrag2 = installDummyModule(systemFragManifest2, "systemFrag2", container);
3217 
3218 		// install an system.bundle fragment that requires a fragment capability from a fragment that fails to resolve
3219 		Map<String, String> systemFragManifest3 = new HashMap<>();
3220 		systemFragManifest3.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3221 		systemFragManifest3.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag3");
3222 		systemFragManifest3.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3223 		systemFragManifest3.put(Constants.REQUIRE_CAPABILITY, "fragment.capability; filter:=\"(fragment.capability=test2)\"");
3224 		systemFragManifest3.put(Constants.PROVIDE_CAPABILITY, "fragment.capability; fragment.capability=test3");
3225 		Module systemFrag3 = installDummyModule(systemFragManifest3, "systemFrag3", container);
3226 
3227 		ResolutionReport report = container.resolve(Arrays.asList(systemFrag3), true);
3228 		Assert.assertNotNull("Expected failure message", report.getResolutionException());
3229 
3230 		List<ModuleWire> hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3231 		assertEquals("Wrong number of fragments.", 1, hostWires.size());
3232 		List<ModuleWire> systemFrag1HostWires = systemFrag1.getCurrentRevision().getWiring().getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
3233 		assertWires(systemFrag1HostWires, hostWires);
3234 
3235 		// install a bundle that can satisfy the failed requirement, but it should not be allowed since it is not a fragment
3236 		Map<String, String> provideCapabilityManifest1 = new HashMap<>();
3237 		provideCapabilityManifest1.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3238 		provideCapabilityManifest1.put(Constants.BUNDLE_SYMBOLICNAME, "provideCapabilityBundle1");
3239 		provideCapabilityManifest1.put(Constants.PROVIDE_CAPABILITY, "fragment.capability; fragment.capability=test4");
3240 		installDummyModule(provideCapabilityManifest1, "provideCapabilityBundle1", container);
3241 
3242 		hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3243 		assertEquals("Wrong number of fragments.", 1, hostWires.size());
3244 		systemFrag1HostWires = systemFrag1.getCurrentRevision().getWiring().getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
3245 		assertWires(systemFrag1HostWires, hostWires);
3246 
3247 		// install a fragment that satisfies the failed requirement
3248 		Map<String, String> systemFragManifest4 = new HashMap<>();
3249 		systemFragManifest4.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3250 		systemFragManifest4.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag4");
3251 		systemFragManifest4.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3252 		systemFragManifest4.put(Constants.PROVIDE_CAPABILITY, "fragment.capability; fragment.capability=test4");
3253 		Module systemFrag4 = installDummyModule(systemFragManifest4, "systemFrag4", container);
3254 
3255 		report = container.resolve(Arrays.asList(systemFrag3), true);
3256 		Assert.assertNull("Failed to resolve.", report.getResolutionException());
3257 
3258 		hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3259 		assertEquals("Wrong number of fragments.", 4, hostWires.size());
3260 		systemFrag1HostWires = systemFrag1.getCurrentRevision().getWiring().getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
3261 		List<ModuleWire> systemFrag2HostWires = systemFrag2.getCurrentRevision().getWiring().getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
3262 		List<ModuleWire> systemFrag3HostWires = systemFrag3.getCurrentRevision().getWiring().getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
3263 		List<ModuleWire> systemFrag4HostWires = systemFrag4.getCurrentRevision().getWiring().getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
3264 		assertWires(systemFrag1HostWires, hostWires);
3265 		assertWires(systemFrag2HostWires, hostWires);
3266 		assertWires(systemFrag3HostWires, hostWires);
3267 		assertWires(systemFrag4HostWires, hostWires);
3268 
3269 		List<ModuleCapability> fragmentCapabilities = systemBundle.getCurrentRevision().getWiring().getModuleCapabilities("fragment.capability");
3270 		assertEquals("Wrong number of fragment capabilities.", 4, fragmentCapabilities.size());
3271 		// Use set since the order of required and provided wires will be different
3272 		Set<ModuleWire> hostRequiredFragmentCapWires = new HashSet<>(systemBundle.getCurrentRevision().getWiring().getRequiredModuleWires("fragment.capability"));
3273 		Set<ModuleWire> hostProvidedFragmentCapWires = new HashSet<>(systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires("fragment.capability"));
3274 		assertEquals("Wrong number of wires.", 2, hostProvidedFragmentCapWires.size());
3275 		assertEquals("Wrong wires found from host.", hostRequiredFragmentCapWires, hostProvidedFragmentCapWires);
3276 	}
3277 
3278 	@Test
testMultipleSystemBundleFragmentsWithSameName()3279 	public void testMultipleSystemBundleFragmentsWithSameName() throws BundleException, IOException {
3280 		// install the system.bundle
3281 		Module systemBundle = createContainerWithSystemBundle(true);
3282 		ModuleContainer container = systemBundle.getContainer();
3283 
3284 		// install multiple versions of the same fragment
3285 		Map<String, String> systemFragManifest1 = new HashMap<>();
3286 		systemFragManifest1.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3287 		systemFragManifest1.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag");
3288 		systemFragManifest1.put(Constants.BUNDLE_VERSION, "1.0");
3289 		systemFragManifest1.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3290 		Module systemFrag1 = installDummyModule(systemFragManifest1, "systemFrag1", container);
3291 
3292 		// first attempt to resolve the lowest version before installing the others
3293 		ResolutionReport report = container.resolve(Arrays.asList(systemFrag1), true);
3294 		Assert.assertNull("Unexpected failure message", report.getResolutionException());
3295 
3296 		List<ModuleWire> hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3297 		assertEquals("Wrong number of fragments.", 1, hostWires.size());
3298 		List<ModuleWire> systemFrag1HostWires = systemFrag1.getCurrentRevision().getWiring().getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
3299 		assertWires(systemFrag1HostWires, hostWires);
3300 
3301 		Map<String, String> systemFragManifest2 = new HashMap<>();
3302 		systemFragManifest2.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3303 		systemFragManifest2.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag");
3304 		systemFragManifest2.put(Constants.BUNDLE_VERSION, "2.0");
3305 		systemFragManifest2.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3306 		Module systemFrag2 = installDummyModule(systemFragManifest2, "systemFrag2", container);
3307 
3308 		Map<String, String> systemFragManifest3 = new HashMap<>();
3309 		systemFragManifest3.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3310 		systemFragManifest3.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag");
3311 		systemFragManifest3.put(Constants.BUNDLE_VERSION, "3.0");
3312 		systemFragManifest3.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3313 		Module systemFrag3 = installDummyModule(systemFragManifest3, "systemFrag3", container);
3314 
3315 		report = container.resolve(Arrays.asList(systemFrag2), true);
3316 		Assert.assertNotNull("Expected failure message", report.getResolutionException());
3317 		report = container.resolve(Arrays.asList(systemFrag3), true);
3318 		Assert.assertNotNull("Expected failure message", report.getResolutionException());
3319 
3320 		hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3321 		assertEquals("Wrong number of fragments.", 1, hostWires.size());
3322 		systemFrag1HostWires = systemFrag1.getCurrentRevision().getWiring().getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
3323 		assertWires(systemFrag1HostWires, hostWires);
3324 
3325 		// uninstall the fragments so we can start over
3326 		container.uninstall(systemFrag1);
3327 		container.uninstall(systemFrag2);
3328 		container.uninstall(systemFrag3);
3329 
3330 		// refresh the system bundle to get only it resolved
3331 		report = container.refresh(Collections.singleton(systemBundle));
3332 		Assert.assertNull("Unexpected failure message", report.getResolutionException());
3333 		hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3334 		assertEquals("Wrong number of fragments.", 0, hostWires.size());
3335 
3336 		// install the fragments again
3337 		systemFrag1 = installDummyModule(systemFragManifest1, "systemFrag1", container);
3338 		systemFrag2 = installDummyModule(systemFragManifest2, "systemFrag2", container);
3339 		systemFrag3 = installDummyModule(systemFragManifest3, "systemFrag3", container);
3340 
3341 		report = container.resolve(Arrays.asList(systemFrag1), true);
3342 		Assert.assertNotNull("Expected failure message", report.getResolutionException());
3343 		report = container.resolve(Arrays.asList(systemFrag2), true);
3344 		Assert.assertNotNull("Expected failure message", report.getResolutionException());
3345 		report = container.resolve(Arrays.asList(systemFrag3), true);
3346 		Assert.assertNull("Unexpected failure message", report.getResolutionException());
3347 
3348 		hostWires = systemBundle.getCurrentRevision().getWiring().getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3349 		List<ModuleWire> systemFrag3HostWires = systemFrag3.getCurrentRevision().getWiring().getRequiredModuleWires(HostNamespace.HOST_NAMESPACE);
3350 		assertWires(systemFrag3HostWires, hostWires);
3351 	}
3352 
3353 	@Test
testSystemBundleFragmentsWithNonEffectiveCapsReqs()3354 	public void testSystemBundleFragmentsWithNonEffectiveCapsReqs() throws BundleException, IOException {
3355 		// install the system.bundle
3356 		Module systemBundle = createContainerWithSystemBundle(true);
3357 		ModuleContainer container = systemBundle.getContainer();
3358 
3359 		ModuleWiring systemWiring = systemBundle.getCurrentRevision().getWiring();
3360 
3361 		// install an system.bundle fragment with activator
3362 		Map<String, String> systemFragManifest = new HashMap<>();
3363 		systemFragManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3364 		systemFragManifest.put(Constants.BUNDLE_SYMBOLICNAME, "systemFrag");
3365 		systemFragManifest.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3366 		systemFragManifest.put(Constants.EXTENSION_BUNDLE_ACTIVATOR, "systemFrag.Activator");
3367 		systemFragManifest.put(Constants.REQUIRE_CAPABILITY,
3368 				"does.not.exist; effective:=never; filter:=\"(never=true)\"");
3369 		systemFragManifest.put(Constants.PROVIDE_CAPABILITY,
3370 				"non.effective.cap; non.effective.cap=test; effective:=never");
3371 
3372 		Module systemFrag = installDummyModule(systemFragManifest, "systemFrag", container);
3373 
3374 		ResolutionReport report = container.resolve(Arrays.asList(systemFrag), true);
3375 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
3376 
3377 		List<ModuleWire> hostWires = systemWiring.getProvidedModuleWires(HostNamespace.HOST_NAMESPACE);
3378 		assertEquals("Wrong number of fragments.", 1, hostWires.size());
3379 		Assert.assertEquals("Unexpected fragment revision: " + hostWires, systemFrag.getCurrentRevision(),
3380 				hostWires.get(0).getRequirer());
3381 
3382 		List<ModuleCapability> dataCaps = systemWiring
3383 				.getModuleCapabilities(EquinoxModuleDataNamespace.MODULE_DATA_NAMESPACE);
3384 		assertTrue("Unexpected module data capabilities: " + dataCaps, dataCaps.isEmpty());
3385 
3386 		List<ModuleCapability> nonEffectiveCaps = systemBundle.getCurrentRevision().getWiring()
3387 				.getModuleCapabilities("non.effective.cap");
3388 		assertTrue("Unexpected non-effective capabilities: " + nonEffectiveCaps, nonEffectiveCaps.isEmpty());
3389 
3390 		List<ModuleRequirement> nonEffectiveReqs = systemWiring.getModuleRequirements("does.not.exist");
3391 		assertTrue("Unexpected non-effective requirements: " + nonEffectiveReqs, nonEffectiveReqs.isEmpty());
3392 
3393 		Map<String, String> failResolutionManifest = new HashMap<>();
3394 		failResolutionManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3395 		failResolutionManifest.put(Constants.BUNDLE_SYMBOLICNAME, "failResolution");
3396 		failResolutionManifest.put(Constants.FRAGMENT_HOST, Constants.SYSTEM_BUNDLE_SYMBOLICNAME);
3397 		failResolutionManifest.put(Constants.REQUIRE_CAPABILITY,
3398 				"non.effective.cap; filter:=\"(non.effective.cap=test)\"");
3399 		Module failResolution = installDummyModule(failResolutionManifest, "failResolution", container);
3400 		report = container.resolve(Arrays.asList(failResolution), false);
3401 		String resolutionMsg = report.getResolutionReportMessage(failResolution.getCurrentRevision());
3402 		assertTrue("Wrong resolution message:" + resolutionMsg, resolutionMsg.contains("non.effective.cap"));
3403 	}
3404 
createContainerWithSystemBundle(boolean resolveSystemBundle)3405 	private Module createContainerWithSystemBundle(boolean resolveSystemBundle) throws BundleException, IOException {
3406 		DummyContainerAdaptor adaptor = createDummyAdaptor();
3407 		ModuleContainer container = adaptor.getContainer();
3408 
3409 		// install the system.bundle
3410 		String systemCapability = "osgi.ee; osgi.ee=\"JavaSE\"; version:List<Version>=\"1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6\", equinox.test; equinox.test=system, osgi.native; osgi.native.osname=test";
3411 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, systemCapability, container);
3412 		if (resolveSystemBundle) {
3413 			ResolutionReport report = container.resolve(Collections.singleton(systemBundle), true);
3414 			Assert.assertNull("Found resolution exception.", report.getResolutionException());
3415 			Assert.assertEquals("System is not resolved.", State.RESOLVED, systemBundle.getState());
3416 		}
3417 
3418 		return systemBundle;
3419 	}
3420 
3421 	@Test
testSplitPackageUses01()3422 	public void testSplitPackageUses01() throws BundleException {
3423 		DummyContainerAdaptor adaptor = createDummyAdaptor();
3424 		ModuleContainer container = adaptor.getContainer();
3425 
3426 		// install a split exporter core that substitutes
3427 		Map<String, String> coreManifest = new HashMap<>();
3428 		coreManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3429 		coreManifest.put(Constants.BUNDLE_SYMBOLICNAME, "core");
3430 		coreManifest.put(Constants.EXPORT_PACKAGE, "pkg1; core=split; mandatory:=core");
3431 		coreManifest.put(Constants.IMPORT_PACKAGE, "pkg1; core=split");
3432 
3433 		// install a split exporter misc that requires core and substitutes
3434 		Map<String, String> miscManifest = new HashMap<>();
3435 		miscManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3436 		miscManifest.put(Constants.BUNDLE_SYMBOLICNAME, "misc");
3437 		miscManifest.put(Constants.EXPORT_PACKAGE, "pkg1; misc=split; mandatory:=misc");
3438 		miscManifest.put(Constants.REQUIRE_BUNDLE, "core");
3439 
3440 		// install a bundle that imports core and exports pkg2 that uses pkg1 from core
3441 		Map<String, String> importsCoreManifest = new HashMap<>();
3442 		importsCoreManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3443 		importsCoreManifest.put(Constants.BUNDLE_SYMBOLICNAME, "importsCore");
3444 		importsCoreManifest.put(Constants.EXPORT_PACKAGE, "pkg2; uses:=pkg1");
3445 		importsCoreManifest.put(Constants.IMPORT_PACKAGE, "pkg1; core=split");
3446 
3447 		// install a bundle that imports pkg2, but requires misc
3448 		Map<String, String> requiresMiscManifest = new HashMap<>();
3449 		requiresMiscManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3450 		requiresMiscManifest.put(Constants.BUNDLE_SYMBOLICNAME, "requiresMisc");
3451 		requiresMiscManifest.put(Constants.IMPORT_PACKAGE, "pkg2");
3452 		requiresMiscManifest.put(Constants.REQUIRE_BUNDLE, "misc");
3453 
3454 		installDummyModule(coreManifest, "core", container);
3455 		installDummyModule(miscManifest, "misc", container);
3456 		installDummyModule(importsCoreManifest, "importsCore", container);
3457 		Module requireMisc = installDummyModule(requiresMiscManifest, "requireMisc", container);
3458 
3459 		ResolutionReport report = container.resolve(Arrays.asList(requireMisc), true);
3460 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
3461 
3462 		// now test by resolving the split exporters first
3463 		adaptor = createDummyAdaptor();
3464 		container = adaptor.getContainer();
3465 
3466 		installDummyModule(coreManifest, "core", container);
3467 		Module misc = installDummyModule(miscManifest, "misc", container);
3468 		report = container.resolve(Arrays.asList(misc), true);
3469 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
3470 
3471 		installDummyModule(importsCoreManifest, "importsCore", container);
3472 		requireMisc = installDummyModule(requiresMiscManifest, "requireMisc", container);
3473 		report = container.resolve(Arrays.asList(requireMisc), true);
3474 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
3475 
3476 		// now test by resolving the split exporters first with a real substitution
3477 		adaptor = createDummyAdaptor();
3478 		container = adaptor.getContainer();
3479 
3480 		// install a exporter that substitutes core's export
3481 		Map<String, String> substitutesCoreManifest = new HashMap<>();
3482 		substitutesCoreManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3483 		substitutesCoreManifest.put(Constants.BUNDLE_SYMBOLICNAME, "substitutesCore");
3484 		substitutesCoreManifest.put(Constants.EXPORT_PACKAGE, "pkg1; substitutesCore=true; mandatory:=substitutesCore");
3485 
3486 		// change core's import to force it to the substitute
3487 		coreManifest.put(Constants.IMPORT_PACKAGE, "pkg1; substitutesCore=true");
3488 		importsCoreManifest.put(Constants.IMPORT_PACKAGE, "pkg1; substitutesCore=true");
3489 
3490 		installDummyModule(substitutesCoreManifest, "substitutesCore", container);
3491 		installDummyModule(coreManifest, "core", container);
3492 		misc = installDummyModule(miscManifest, "misc", container);
3493 		report = container.resolve(Arrays.asList(misc), true);
3494 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
3495 
3496 		installDummyModule(importsCoreManifest, "importsCore", container);
3497 		requireMisc = installDummyModule(requiresMiscManifest, "requireMisc", container);
3498 		report = container.resolve(Arrays.asList(requireMisc), true);
3499 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
3500 
3501 		// not test by doing a full resolve with real substitution
3502 		adaptor = createDummyAdaptor();
3503 		container = adaptor.getContainer();
3504 
3505 		installDummyModule(substitutesCoreManifest, "substitutesCore", container);
3506 		installDummyModule(coreManifest, "core", container);
3507 		installDummyModule(miscManifest, "misc", container);
3508 		installDummyModule(importsCoreManifest, "importsCore", container);
3509 		requireMisc = installDummyModule(requiresMiscManifest, "requireMisc", container);
3510 
3511 		report = container.resolve(Arrays.asList(requireMisc), true);
3512 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
3513 	}
3514 
3515 	List<String> HTTPCOMPS_AND_EATHER = Arrays.asList( //
3516 			"org.apache.commons.codec_1.9.0.v20170208-1614.MF", //
3517 			"org.apache.commons.logging_1.1.1.v201101211721.MF", //
3518 			"org.apache.httpcomponents.httpclient_4.3.6.v201511171540.MF", //
3519 			"org.apache.httpcomponents.httpclient_4.5.2.v20170208-1614.MF", //
3520 			"org.apache.httpcomponents.httpclient_4.5.2.v20170210-0925.MF", //
3521 			"org.apache.httpcomponents.httpcore_4.3.3.v201411290715.MF", //
3522 			"org.apache.httpcomponents.httpcore_4.4.4.v20161115-1643.MF", //
3523 			"org.apache.httpcomponents.httpcore_4.4.6.v20170210-0925.MF", //
3524 			"org.eclipse.aether.api_1.0.1.v20141111.MF", //
3525 			"org.eclipse.aether.spi_1.0.1.v20141111.MF", //
3526 			"org.eclipse.aether.transport.http_1.0.1.v20141111.MF", //
3527 			"org.eclipse.aether.util_1.0.1.v20141111.MF");
3528 
3529 	@Test
testSubstitutionWithMoreThan2Providers()3530 	public void testSubstitutionWithMoreThan2Providers() throws BundleException, IOException {
3531 		DummyContainerAdaptor adaptor = createDummyAdaptor();
3532 		ModuleContainer container = adaptor.getContainer();
3533 
3534 		Module systemBundle = installDummyModule( //
3535 				"system.bundle.MF", //
3536 				Constants.SYSTEM_BUNDLE_LOCATION, //
3537 				Constants.SYSTEM_BUNDLE_SYMBOLICNAME, //
3538 				"javax.crypto, javax.crypto.spec, javax.net, javax.net.ssl, javax.security.auth.x500, org.ietf.jgss", //
3539 				"osgi.ee; osgi.ee=JavaSE; version:List<Version>=\"1.3, 1.4, 1.5, 1.6, 1.7\"", //
3540 				container);
3541 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
3542 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
3543 
3544 		List<Module> modules = new ArrayList<>();
3545 		for (String manifest : HTTPCOMPS_AND_EATHER) {
3546 			modules.add(installDummyModule(manifest, manifest, container));
3547 		}
3548 		report = container.resolve(modules, true);
3549 		Assert.assertNull("Failed to resolve test.", report.getResolutionException());
3550 	}
3551 
3552 	@Test
testModuleIDSetting()3553 	public void testModuleIDSetting() throws BundleException, IOException {
3554 		DummyContainerAdaptor adaptor = createDummyAdaptor();
3555 		ModuleContainer container = adaptor.getContainer();
3556 
3557 		// install the system.bundle
3558 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
3559 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
3560 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
3561 
3562 		Map<String, String> manifest = new HashMap<>();
3563 
3564 		// test by installing bundles with decreasing IDs
3565 		List<Module> modules = new ArrayList<>();
3566 		for (int i = 5; i > 0; i--) {
3567 			manifest.clear();
3568 			manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3569 			manifest.put(Constants.BUNDLE_SYMBOLICNAME, String.valueOf(i));
3570 			modules.add(installDummyModule(manifest, i, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container));
3571 		}
3572 
3573 		// test that the modules have decreasing ID starting at 5
3574 		long id = 5;
3575 		for (Module module : modules) {
3576 			Assert.assertEquals("Wrong ID found.", id--, module.getId().longValue());
3577 		}
3578 
3579 		// test that error occurs when trying to use an existing ID
3580 		manifest.clear();
3581 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3582 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, String.valueOf("test.dup.id"));
3583 		try {
3584 			installDummyModule(manifest, 5, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
3585 			fail("Expected to fail installation with duplicate ID.");
3586 		} catch (IllegalStateException e) {
3587 			// expected
3588 		}
3589 	}
3590 
3591 	@Test
testAliasBundleNameReport()3592 	public void testAliasBundleNameReport() throws BundleException, IOException {
3593 		DummyContainerAdaptor adaptor = createDummyAdaptor();
3594 		ModuleContainer container = adaptor.getContainer();
3595 
3596 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, container);
3597 		container.resolve(Collections.singleton(systemBundle), true);
3598 
3599 		Map<String, String> b1Manifest = new HashMap<>();
3600 		b1Manifest.put(Constants.BUNDLE_SYMBOLICNAME, "b1");
3601 		b1Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3602 		b1Manifest.put(Constants.IMPORT_PACKAGE, "doesnotexist");
3603 		ModuleRevisionBuilder b1Builder = OSGiManifestBuilderFactory.createBuilder(b1Manifest, "alias.name", "", "");
3604 		container.install(systemBundle, "b1", b1Builder, null);
3605 
3606 		Map<String, String> b2Manifest = new HashMap<>();
3607 		b2Manifest.put(Constants.BUNDLE_SYMBOLICNAME, "b2");
3608 		b2Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3609 		b2Manifest.put(Constants.REQUIRE_BUNDLE, "b1");
3610 		ModuleRevisionBuilder b2Builder = OSGiManifestBuilderFactory.createBuilder(b2Manifest);
3611 		Module b2 = container.install(systemBundle, "b2", b2Builder, null);
3612 
3613 		ResolutionReport report = container.resolve(Collections.singleton(b2), true);
3614 		String message = report.getResolutionReportMessage(b2.getCurrentRevision());
3615 		assertTrue("Wrong error message: " + message, message.contains("b1") && message.contains("alias.name"));
3616 	}
3617 
3618 	@Test
testStartDeadLock()3619 	public void testStartDeadLock() throws BundleException, InterruptedException, IOException {
3620 		CountDownLatch startLatch = new CountDownLatch(1);
3621 		CountDownLatch stopLatch = new CountDownLatch(1);
3622 
3623 		DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(false), Collections.singletonMap(EquinoxConfiguration.PROP_MODULE_LOCK_TIMEOUT, "1"));
3624 		adaptor.setStartLatch(startLatch);
3625 		adaptor.setStopLatch(stopLatch);
3626 
3627 		ModuleContainer container = adaptor.getContainer();
3628 
3629 		// install the system.bundle
3630 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
3631 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
3632 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
3633 		systemBundle.start();
3634 
3635 		// install a module
3636 		Map<String, String> manifest = new HashMap<>();
3637 		manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3638 		manifest.put(Constants.BUNDLE_SYMBOLICNAME, "lock.test");
3639 		final Module module = installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
3640 
3641 		final ArrayBlockingQueue<BundleException> startExceptions = new ArrayBlockingQueue<>(2);
3642 		Runnable start = new Runnable() {
3643 			@Override
3644 			public void run() {
3645 				try {
3646 					module.start();
3647 				} catch (BundleException e) {
3648 					startExceptions.offer(e);
3649 				}
3650 			}
3651 		};
3652 		Thread t1 = new Thread(start);
3653 		Thread t2 = new Thread(start);
3654 		t1.start();
3655 		t2.start();
3656 
3657 		BundleException startError = startExceptions.poll(10, TimeUnit.SECONDS);
3658 		startLatch.countDown();
3659 
3660 		Assert.assertEquals("Wrong cause.", TimeoutException.class, startError.getCause().getClass());
3661 		Assert.assertEquals("Wrong cause.", ThreadInfoReport.class, startError.getCause().getCause().getClass());
3662 		startError.printStackTrace();
3663 
3664 		final ArrayBlockingQueue<BundleException> stopExceptions = new ArrayBlockingQueue<>(2);
3665 		Runnable stop = new Runnable() {
3666 			@Override
3667 			public void run() {
3668 				try {
3669 					module.stop();
3670 				} catch (BundleException e) {
3671 					stopExceptions.offer(e);
3672 				}
3673 			}
3674 		};
3675 		Thread tStop1 = new Thread(stop);
3676 		Thread tStop2 = new Thread(stop);
3677 		tStop1.start();
3678 		tStop2.start();
3679 
3680 		BundleException stopError = stopExceptions.poll(10, TimeUnit.SECONDS);
3681 		stopLatch.countDown();
3682 
3683 		Assert.assertEquals("Wrong cause.", TimeoutException.class, stopError.getCause().getClass());
3684 		Assert.assertEquals("Wrong cause.", ThreadInfoReport.class, stopError.getCause().getCause().getClass());
3685 		stopError.printStackTrace();
3686 	}
3687 
3688 	@Test
testUsesWithRequireReexport()3689 	public void testUsesWithRequireReexport() throws BundleException, IOException {
3690 		DummyContainerAdaptor adaptor = createDummyAdaptor();
3691 		ModuleContainer container = adaptor.getContainer();
3692 
3693 		// install the system.bundle
3694 		Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
3695 		ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
3696 		Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
3697 
3698 		// install and resolve used.pkg exporter to force substitution
3699 		Map<String, String> usedPkgExportManifest = new HashMap<>();
3700 		usedPkgExportManifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3701 		usedPkgExportManifest.put(Constants.BUNDLE_SYMBOLICNAME, "used.pkg");
3702 		usedPkgExportManifest.put(Constants.EXPORT_PACKAGE, "used.pkg");
3703 		Module moduleUsedPkg = installDummyModule(usedPkgExportManifest, "usedPkg", container);
3704 		report = container.resolve(Arrays.asList(moduleUsedPkg), true);
3705 		Assert.assertNull("Failed to resolve usedPkg.", report.getResolutionException());
3706 
3707 		// install part 1 (ui.workbench)
3708 		Map<String, String> split1Manifest = new HashMap<>();
3709 		split1Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3710 		split1Manifest.put(Constants.BUNDLE_SYMBOLICNAME, "split1");
3711 		split1Manifest.put(Constants.EXPORT_PACKAGE, "split.pkg; uses:=used.pkg, used.pkg");
3712 		split1Manifest.put(Constants.IMPORT_PACKAGE, "used.pkg");
3713 		Module moduleSplit1 = installDummyModule(split1Manifest, "split1", container);
3714 
3715 		// install part 2 (e4.ui.ide)
3716 		Map<String, String> split2Manifest = new HashMap<>();
3717 		split2Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3718 		split2Manifest.put(Constants.BUNDLE_SYMBOLICNAME, "split2");
3719 		split2Manifest.put(Constants.EXPORT_PACKAGE, "split.pkg");
3720 		Module moduleSplit2 = installDummyModule(split2Manifest, "split2", container);
3721 
3722 		// install part 3 which requires part 1 and 2, reexports 1 and 2 (ui.ide)
3723 		Map<String, String> split3Manifest = new HashMap<>();
3724 		split3Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3725 		split3Manifest.put(Constants.BUNDLE_SYMBOLICNAME, "split3");
3726 		split3Manifest.put(Constants.EXPORT_PACKAGE, "split.pkg");
3727 		// the reexport here are not necessary; but cause issues for the resolver
3728 		split3Manifest.put(Constants.REQUIRE_BUNDLE, "split1; visibility:=reexport, split2; visibility:=reexport");
3729 		Module moduleSplit3 = installDummyModule(split3Manifest, "split3", container);
3730 
3731 		// install reexporter of part1 (ui)
3732 		Map<String, String> reexporterPart1Manifest = new HashMap<>();
3733 		reexporterPart1Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3734 		reexporterPart1Manifest.put(Constants.BUNDLE_SYMBOLICNAME, "reexport1");
3735 		reexporterPart1Manifest.put(Constants.REQUIRE_BUNDLE, "split1; visibility:=reexport");
3736 		Module moduleReexport1 = installDummyModule(reexporterPart1Manifest, "reexport1", container);
3737 
3738 		// install reexporter of split3
3739 		Map<String, String> reexporterSplit3Manifest = new HashMap<>();
3740 		reexporterSplit3Manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3741 		reexporterSplit3Manifest.put(Constants.BUNDLE_SYMBOLICNAME, "reexportSplit3");
3742 		reexporterSplit3Manifest.put(Constants.REQUIRE_BUNDLE, "split3; visibility:=reexport");
3743 		Module moduleReexportSplit3 = installDummyModule(reexporterSplit3Manifest, "reexportSplit3", container);
3744 
3745 		// install test export that requires reexportSplit3 (should get access to all 3 parts)
3746 		Map<String, String> testExporterUses = new HashMap<>();
3747 		testExporterUses.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3748 		testExporterUses.put(Constants.BUNDLE_SYMBOLICNAME, "test.exporter");
3749 		testExporterUses.put(Constants.REQUIRE_BUNDLE, "reexportSplit3");
3750 		testExporterUses.put(Constants.EXPORT_PACKAGE, "export.pkg; uses:=split.pkg");
3751 		Module testExporter = installDummyModule(testExporterUses, "test.exporter", container);
3752 
3753 		// install test requirer that requires the exporter and reexport1 (should get access to only part 1)
3754 		// part 1 is a subset of what the exporter has access to so it should resolve
3755 		Map<String, String> testRequireUses = new HashMap<>();
3756 		testRequireUses.put(Constants.BUNDLE_MANIFESTVERSION, "2");
3757 		testRequireUses.put(Constants.BUNDLE_SYMBOLICNAME, "test.requirer");
3758 		testRequireUses.put(Constants.REQUIRE_BUNDLE, "test.exporter, reexport1");
3759 		Module testRequirer = installDummyModule(testRequireUses, "test.requirer", container);
3760 
3761 		report = container.resolve(Arrays.asList(moduleSplit1, moduleSplit2, moduleSplit3, moduleReexport1, moduleReexportSplit3, testExporter, testRequirer), true);
3762 		Assert.assertNull("Failed to resolve", report.getResolutionException());
3763 	}
3764 
assertWires(List<ModuleWire> required, List<ModuleWire>... provided)3765 	private static void assertWires(List<ModuleWire> required, List<ModuleWire>... provided) {
3766 		for (ModuleWire requiredWire : required) {
3767 			for (List<ModuleWire> providedList : provided) {
3768 				if (providedList.contains(requiredWire)) {
3769 					return;
3770 				}
3771 			}
3772 			Assert.fail("Could not find required wire in expected provider wires: " + requiredWire);
3773 		}
3774 	}
3775 
assertEvents(List<DummyModuleEvent> expected, List<DummyModuleEvent> actual, boolean orderMatters)3776 	private void assertEvents(List<DummyModuleEvent> expected, List<DummyModuleEvent> actual, boolean orderMatters) {
3777 		for (List<DummyModuleEvent> expectedCommon = removeFirstListOfCommonEvents(expected); !expectedCommon.isEmpty(); expectedCommon = removeFirstListOfCommonEvents(expected)) {
3778 			List<DummyModuleEvent> actualCommon = removeFirstListOfCommonEvents(actual);
3779 			if (expectedCommon.size() != actualCommon.size()) {
3780 				Assert.assertEquals("Wrong number of events found in: " + actualCommon, expectedCommon.size(), actualCommon.size());
3781 			}
3782 			if (orderMatters) {
3783 				Assert.assertEquals("Wrong events found.", expectedCommon, actualCommon);
3784 			} else {
3785 				for (DummyModuleEvent expectedEvent : expectedCommon) {
3786 					Assert.assertTrue("Missing expected event: " + expectedEvent + " : from " + actualCommon, actualCommon.contains(expectedEvent));
3787 				}
3788 				for (DummyModuleEvent actualEvent : actualCommon) {
3789 					Assert.assertTrue("Found unexpected event: " + actualEvent + " : from " + actualCommon, expectedCommon.contains(actualEvent));
3790 				}
3791 			}
3792 		}
3793 	}
3794 
removeFirstListOfCommonEvents(List<DummyModuleEvent> events)3795 	private List<DummyModuleEvent> removeFirstListOfCommonEvents(List<DummyModuleEvent> events) {
3796 		List<DummyModuleEvent> result = new ArrayList<>();
3797 		if (events.isEmpty()) {
3798 			return result;
3799 		}
3800 		ModuleEvent commonEvent = events.get(0).event;
3801 		for (Iterator<DummyModuleEvent> iEvents = events.iterator(); iEvents.hasNext();) {
3802 			DummyModuleEvent current = iEvents.next();
3803 			if (commonEvent.equals(current.event)) {
3804 				iEvents.remove();
3805 				result.add(current);
3806 			} else {
3807 				break;
3808 			}
3809 		}
3810 		return result;
3811 	}
3812 }
3813