Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.virgo.kernel.userregion/src/test')
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/InitialArtifactDeployerTests.java156
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/ServiceScopingStrategyTests.java259
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/AbstractOsgiFrameworkLaunchingTests.java196
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/BundleInstallationTests.java199
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/BundleUpdateTests.java75
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/EquinoxBootDelegationHelperTests.java48
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/EquinoxOsgiFrameworkTests.java103
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/KernelBundleClassLoaderTests.java111
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/LoadTimeWeavingTests.java131
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/ManifestUtils.java94
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/ResolutionStateDumperTests.java116
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/StubHashGenerator.java25
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/TestUtils.java32
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/UsesAnalyserTests.java162
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/importexpansion/ImportExpansionHandlerTests.java751
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/importexpansion/TrackedPackageImportsTests.java405
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/BundleDescriptionComparatorTests.java208
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiBundleTests.java152
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiExportPackageTests.java88
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiImportPackageTests.java120
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiRequiredBundleTests.java107
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBaseDescription.java57
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBundleDescription.java348
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBundleSpecification.java103
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubExportPackageDescription.java75
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubImportPackageSpecification.java109
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubParameterised.java41
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubStateHelper.java118
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/EquinoxOsgiFrameworkTests/faulty/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/KernelBundleClassLoaderTests/dependant.jarbin0 -> 871 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/KernelBundleClassLoaderTests/depender.jarbin0 -> 737 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/eight/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/error/missingimport/bundle/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/five/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/four/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/fragments/unresolvable/bundle/META-INF/MANIFEST.MF2
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/fragments/unresolvable/fragment/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/a/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/b/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/bundle/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/nine/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/one/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatindep/bundle/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatindep/dep/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatisfied/bundle/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/outsiderepo/bundle/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/seven/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/six/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/three/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/two/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/bundle/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/hibernate325/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/hibernate326/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/spring/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/x/high/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/x/low/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/bit/standalone/META-INF/MANIFEST.MF3
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/config/BundleInstallationTests/repository.properties43
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/config/BundleUpdateTests/repository.properties43
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/config/EquinoxOsgiFrameworkTests/repository.properties4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/config/ImportExpansionHandlerTests/repository.properties13
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/config/InstallFromLocationTests/repository.properties4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/config/KernelBundleClassLoaderTests/repository.properties13
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/config/LoadTimeWeavingTests/repository.properties4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/config/ResolutionStateDumperTests/repository.properties4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/config/UsesAnalyserTests/repository.properties4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/config/repository.properties7
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/java5-server.profile152
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/java6-server.profile216
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/org.eclipse.osgi-3.4.0.v20080529-1200.jarbin0 -> 994119 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/server.profile146
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/fail/child/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/fail/parent/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/frag/child/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/frag/host/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/four/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/one/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/three/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/two/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/jars/dummy.jarbin0 -> 774 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/jars/mockbundle.jarbin0 -> 450 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-domain.jarbin0 -> 801 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-em.jarbin0 -> 801 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-include.jarbin0 -> 1704 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiapp-1.0.0.jarbin0 -> 59309 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiapp-2.0.0.jarbin0 -> 59542 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiservice-1.0.0.jarbin0 -> 4710 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiservice-2.0.0.jarbin0 -> 5142 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/rfd-other/other/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/a/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/app/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/b/META-INF/MANIFEST.MF7
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/c/META-INF/MANIFEST.MF7
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/hibernate/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/hibernate2/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/spring/META-INF/MANIFEST.MF7
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/web/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentOne/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentTwo/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentwithnoexports/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/host/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/multi-version-export/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/noexports/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/overlapper/META-INF/MANIFEST.MF4
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/com.foo.libd3
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/missing.optional.bundle.libd3
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/spring.libd5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/p/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/q/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/r1/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/r2/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/s1/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/s2/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/p/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/q/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/r1/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/r2/META-INF/MANIFEST.MF6
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/s1/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/s2/META-INF/MANIFEST.MF5
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmA.jarbin0 -> 527 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmB.jarbin0 -> 360 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmC.jarbin0 -> 356 bytes
-rw-r--r--org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmD.jarbin0 -> 352 bytes
123 files changed, 5350 insertions, 0 deletions
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/InitialArtifactDeployerTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/InitialArtifactDeployerTests.java
new file mode 100644
index 00000000..ab9e6854
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/InitialArtifactDeployerTests.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.reset;
+import static org.easymock.EasyMock.verify;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+
+
+import org.eclipse.virgo.kernel.core.Shutdown;
+import org.eclipse.virgo.kernel.deployer.core.ApplicationDeployer;
+import org.eclipse.virgo.kernel.deployer.core.DeployUriNormaliser;
+import org.eclipse.virgo.kernel.deployer.core.DeploymentException;
+import org.eclipse.virgo.kernel.deployer.core.ApplicationDeployer.DeploymentOptions;
+import org.eclipse.virgo.kernel.userregion.internal.InitialArtifactDeployer;
+import org.eclipse.virgo.kernel.userregion.internal.KernelStartedAwaiter;
+import org.eclipse.virgo.medic.test.eventlog.MockEventLogger;
+
+public class InitialArtifactDeployerTests {
+
+ private ApplicationDeployer deployer = createMock(ApplicationDeployer.class);
+
+ private KernelStartedAwaiter startedAwaiter = new KernelStartedAwaiter();
+
+ private StubEventAdmin eventAdmin = new StubEventAdmin();
+
+ private MockEventLogger eventLogger = new MockEventLogger();
+
+ private Shutdown shutdown = createMock(Shutdown.class);
+
+ @Test
+ public void basicEventingWithNoArtifactDeployment() throws InterruptedException {
+ replay(this.deployer);
+
+ InitialArtifactDeployer initialArtifactDeployer = new InitialArtifactDeployer(this.startedAwaiter, this.deployer, "", "", new StubDeployUriNormaliser(), this.eventAdmin, this.eventLogger, this.shutdown);
+ this.startedAwaiter.handleEvent(new Event("org/eclipse/virgo/kernel/STARTED", null));
+
+ initialArtifactDeployer.deployArtifacts();
+
+ Event eventSystemArtifactsDeployed = new Event("org/eclipse/virgo/kernel/userregion/systemartifacts/DEPLOYED", null);
+ this.eventAdmin.awaitPostingOfEvent(eventSystemArtifactsDeployed);
+
+ initialArtifactDeployer.handleEvent(eventSystemArtifactsDeployed);
+ this.eventAdmin.awaitPostingOfEvent(new Event("org/eclipse/virgo/kernel/userregion/userartifacts/DEPLOYED", null));
+
+ verify(this.deployer);
+ }
+
+ @Test
+ public void artifactDeployment() throws DeploymentException, InterruptedException {
+
+ InitialArtifactDeployer initialArtifactDeployer = new InitialArtifactDeployer(this.startedAwaiter, this.deployer, "repository:alpha/bravo/1, repository:alpha/bravo/2", "repository:charlie/delta,repository:echo/foxtrot/2", new StubDeployUriNormaliser(), this.eventAdmin, this.eventLogger, this.shutdown);
+
+ expect(this.deployer.deploy(URI.create("repository:alpha/bravo/1"), new DeploymentOptions(false, false, true))).andReturn(null);
+ expect(this.deployer.deploy(URI.create("repository:alpha/bravo/2"), new DeploymentOptions(false, false, true))).andReturn(null);
+ replay(this.deployer);
+
+ this.startedAwaiter.handleEvent(new Event("org/eclipse/virgo/kernel/STARTED", null));
+ initialArtifactDeployer.deployArtifacts();
+
+ Event eventSystemArtifactsDeployed = new Event("org/eclipse/virgo/kernel/userregion/systemartifacts/DEPLOYED", null);
+ this.eventAdmin.awaitPostingOfEvent(eventSystemArtifactsDeployed);
+
+ verify(this.deployer);
+
+ reset(this.deployer);
+
+ expect(this.deployer.deploy(URI.create("repository:charlie/delta"), new DeploymentOptions(false, false, true))).andReturn(null);
+ expect(this.deployer.deploy(URI.create("repository:echo/foxtrot/2"), new DeploymentOptions(false, false, true))).andReturn(null);
+
+ replay(this.deployer);
+
+ initialArtifactDeployer.handleEvent(eventSystemArtifactsDeployed);
+ this.eventAdmin.awaitPostingOfEvent(new Event("org/eclipse/virgo/kernel/userregion/userartifacts/DEPLOYED", null));
+
+ verify(this.deployer);
+ }
+
+ @Test
+ public void failedDeploymentLogsMessageAndTriggersShutdown() throws DeploymentException, InterruptedException {
+ InitialArtifactDeployer initialArtifactDeployer = new InitialArtifactDeployer(this.startedAwaiter, this.deployer, "repository:alpha/bravo/1", null, new StubDeployUriNormaliser(), this.eventAdmin, this.eventLogger, this.shutdown);
+
+ expect(this.deployer.deploy(URI.create("repository:alpha/bravo/1"), new DeploymentOptions(false, false, true))).andThrow(new DeploymentException("Deployment failed"));
+ replay(this.deployer);
+
+ this.shutdown.shutdown();
+ replay(this.shutdown);
+
+ this.startedAwaiter.handleEvent(new Event("org/eclipse/virgo/kernel/STARTED", null));
+
+ initialArtifactDeployer.deployArtifacts();
+
+ while (!this.eventLogger.isLogged("UR0002E")) {
+ Thread.sleep(100);
+ }
+
+ Thread.sleep(100);
+
+ verify(this.deployer, this.shutdown);
+ }
+
+ private final class StubEventAdmin implements EventAdmin {
+
+ private final List<Event> postedEvents = new ArrayList<Event>();
+
+ private final List<Event> sentEvents = new ArrayList<Event>();
+
+ private final Object monitor = new Object();
+
+ public void postEvent(Event event) {
+ synchronized (this.monitor) {
+ this.postedEvents.add(event);
+ }
+ }
+
+ public void sendEvent(Event event) {
+ synchronized (this.monitor) {
+ this.sentEvents.add(event);
+ }
+ }
+
+ public void awaitPostingOfEvent(Event event) {
+ boolean eventSent = false;
+ while (!eventSent) {
+ synchronized (this.monitor) {
+ eventSent = this.postedEvents.contains(event);
+ }
+ }
+ }
+ }
+
+ private final class StubDeployUriNormaliser implements DeployUriNormaliser {
+ public URI normalise(URI uri) throws DeploymentException {
+ return uri;
+ }
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/ServiceScopingStrategyTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/ServiceScopingStrategyTests.java
new file mode 100644
index 00000000..4b21d1b5
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/ServiceScopingStrategyTests.java
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.HashSet;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+import org.eclipse.virgo.kernel.install.artifact.ScopeServiceRepository;
+
+import org.eclipse.virgo.kernel.shim.scope.Scope;
+import org.eclipse.virgo.kernel.shim.scope.ScopeFactory;
+import org.eclipse.virgo.kernel.userregion.internal.ServiceScopingStrategy;
+import org.eclipse.virgo.teststubs.osgi.framework.StubBundleContext;
+
+/**
+ */
+public class ServiceScopingStrategyTests {
+
+ private static final String SCOPE_NAME = "application scope";
+
+ private static final String CLASS_NAME = "Class";
+
+ private static final String FILTER = "Filter";
+
+ private ServiceScopingStrategy serviceScopingStrategy;
+
+ private ScopeFactory scopeFactory;
+
+ private ScopeServiceRepository scopeServiceRepository;
+
+ private Scope globalScope;
+
+ private ServiceReference unscopedServiceReference;
+
+ private StubBundleContext unscopedBundleContext;
+
+ private Scope appScope;
+
+ private ServiceReference scopedServiceReference;
+
+ private StubBundleContext scopedBundleContext;
+
+ @Before
+ public void setUp() throws Exception {
+ this.scopeFactory = createMock(ScopeFactory.class);
+ this.scopeServiceRepository = createMock(ScopeServiceRepository.class);
+ this.serviceScopingStrategy = new ServiceScopingStrategy(this.scopeFactory, this.scopeServiceRepository);
+
+ this.globalScope = createMock(Scope.class);
+ expect(this.globalScope.isGlobal()).andReturn(true).anyTimes();
+ expect(this.scopeFactory.getGlobalScope()).andReturn(this.globalScope).anyTimes();
+
+ this.appScope = createMock(Scope.class);
+ expect(this.appScope.isGlobal()).andReturn(false).anyTimes();
+ expect(this.appScope.getScopeName()).andReturn(SCOPE_NAME).anyTimes();
+
+ replay(this.globalScope, this.appScope);
+ }
+
+ private void setUpScopedBundleContext() {
+ this.scopedBundleContext = new StubBundleContext();
+ expect(this.scopeFactory.getBundleScope(eq(this.scopedBundleContext.getBundle()))).andReturn(this.appScope).anyTimes();
+ }
+
+ private void setUpScopedServiceReference() {
+ this.scopedServiceReference = createMock(ServiceReference.class);
+ expect(this.scopeFactory.getServiceScope(eq(this.scopedServiceReference))).andReturn(this.appScope).anyTimes();
+ }
+
+ private void setUpUnscopedBundleContext() {
+ this.unscopedBundleContext = new StubBundleContext();
+ expect(this.scopeFactory.getBundleScope(eq(this.unscopedBundleContext.getBundle()))).andReturn(this.globalScope).anyTimes();
+ }
+
+ private void setUpUnscopedServiceReference() {
+ this.unscopedServiceReference = createMock(ServiceReference.class);
+ expect(this.scopeFactory.getServiceScope(eq(this.unscopedServiceReference))).andReturn(this.globalScope).anyTimes();
+ }
+
+ @After
+ public void tearDown() {
+ verify(this.globalScope, this.appScope);
+ }
+
+ @Test
+ public void testMatchesScopeUnscopedServiceUnscopedApplication() {
+ setUpUnscopedServiceReference();
+ setUpUnscopedBundleContext();
+ replay(this.scopeFactory, this.scopeServiceRepository, this.unscopedServiceReference);
+ assertTrue(this.serviceScopingStrategy.isPotentiallyVisible(this.unscopedServiceReference, this.unscopedBundleContext));
+ verify(this.scopeFactory, this.scopeServiceRepository, this.unscopedServiceReference);
+ }
+
+ @Test
+ public void testMatchesScopeScopedServiceScopedApplication() {
+ setUpScopedServiceReference();
+ setUpScopedBundleContext();
+ replay(this.scopeFactory, this.scopeServiceRepository, this.scopedServiceReference);
+ assertTrue(this.serviceScopingStrategy.isPotentiallyVisible(this.scopedServiceReference, this.scopedBundleContext));
+ verify(this.scopeFactory, this.scopeServiceRepository, this.scopedServiceReference);
+ }
+
+ @Test
+ public void testMatchesScopeScopedServiceUnscopedApplication() {
+ setUpScopedServiceReference();
+ setUpUnscopedBundleContext();
+ replay(this.scopeFactory, this.scopeServiceRepository, this.scopedServiceReference);
+ assertFalse(this.serviceScopingStrategy.isPotentiallyVisible(this.scopedServiceReference, this.unscopedBundleContext));
+ verify(this.scopeFactory, this.scopeServiceRepository, this.scopedServiceReference);
+ }
+
+ @Test
+ public void testMatchesScopeUnscopedServiceScopedApplication() {
+ setUpUnscopedServiceReference();
+ setUpScopedBundleContext();
+ replay(this.scopeFactory, this.scopeServiceRepository, this.unscopedServiceReference);
+ assertTrue(this.serviceScopingStrategy.isPotentiallyVisible(this.unscopedServiceReference, this.scopedBundleContext));
+ verify(this.scopeFactory, this.scopeServiceRepository, this.unscopedServiceReference);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testScopeReferencesUnscopedServiceUnscopedApplication() throws InvalidSyntaxException {
+ setUpUnscopedServiceReference();
+ setUpUnscopedBundleContext();
+ expect(this.scopeServiceRepository.scopeHasMatchingService(eq(SCOPE_NAME), eq(CLASS_NAME), eq(FILTER))).andReturn(false).anyTimes();
+ replay(this.scopeFactory, this.scopeServiceRepository, this.unscopedServiceReference);
+
+ Collection references = new ShrinkableSet(this.unscopedServiceReference);
+ this.serviceScopingStrategy.scopeReferences(references, this.unscopedBundleContext, CLASS_NAME, FILTER);
+ assertTrue(references.contains(this.unscopedServiceReference));
+
+ verify(this.scopeFactory, this.scopeServiceRepository, this.unscopedServiceReference);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testScopeReferencesScopedServiceUnscopedApplication() throws InvalidSyntaxException {
+ setUpScopedServiceReference();
+ setUpUnscopedBundleContext();
+ expect(this.scopeServiceRepository.scopeHasMatchingService(eq(SCOPE_NAME), eq(CLASS_NAME), eq(FILTER))).andReturn(false).anyTimes();
+ replay(this.scopeFactory, this.scopeServiceRepository, this.scopedServiceReference);
+
+ Collection references = new ShrinkableSet(this.scopedServiceReference);
+ this.serviceScopingStrategy.scopeReferences(references, this.unscopedBundleContext, CLASS_NAME, FILTER);
+ assertFalse(references.contains(this.unscopedServiceReference));
+
+ verify(this.scopeFactory, this.scopeServiceRepository, this.scopedServiceReference);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testScopeReferencesScopedServiceInModelScopedApplication() throws InvalidSyntaxException {
+ setUpScopedServiceReference();
+ setUpScopedBundleContext();
+ expect(this.scopeServiceRepository.scopeHasMatchingService(eq(SCOPE_NAME), eq(CLASS_NAME), eq(FILTER))).andReturn(true).anyTimes();
+ replay(this.scopeFactory, this.scopeServiceRepository, this.scopedServiceReference);
+
+ Collection references = new ShrinkableSet(this.scopedServiceReference);
+ this.serviceScopingStrategy.scopeReferences(references, this.scopedBundleContext, CLASS_NAME, FILTER);
+ assertTrue(references.contains(this.scopedServiceReference));
+
+ verify(this.scopeFactory, this.scopeServiceRepository, this.scopedServiceReference);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testScopeReferencesScopedServiceNotInModelScopedApplication() throws InvalidSyntaxException {
+ setUpScopedServiceReference();
+ setUpScopedBundleContext();
+ expect(this.scopeServiceRepository.scopeHasMatchingService(eq(SCOPE_NAME), eq(CLASS_NAME), eq(FILTER))).andReturn(false).anyTimes();
+ replay(this.scopeFactory, this.scopeServiceRepository, this.scopedServiceReference);
+
+ Collection references = new ShrinkableSet(this.scopedServiceReference);
+ this.serviceScopingStrategy.scopeReferences(references, this.scopedBundleContext, CLASS_NAME, FILTER);
+ assertTrue(references.contains(this.scopedServiceReference));
+
+ verify(this.scopeFactory, this.scopeServiceRepository, this.scopedServiceReference);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testScopeReferencesUnscopedUnshadowedServiceScopedApplication() throws InvalidSyntaxException {
+ setUpUnscopedServiceReference();
+ setUpScopedBundleContext();
+ expect(this.scopeServiceRepository.scopeHasMatchingService(eq(SCOPE_NAME), eq(CLASS_NAME), eq(FILTER))).andReturn(false).anyTimes();
+ replay(this.scopeFactory, this.scopeServiceRepository, this.unscopedServiceReference);
+
+ Collection references = new ShrinkableSet(this.unscopedServiceReference);
+ this.serviceScopingStrategy.scopeReferences(references, this.scopedBundleContext, CLASS_NAME, FILTER);
+ assertTrue(references.contains(this.unscopedServiceReference));
+
+ verify(this.scopeFactory, this.scopeServiceRepository, this.unscopedServiceReference);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testScopeReferencesUnscopedShadowedServiceScopedApplication() throws InvalidSyntaxException {
+ setUpUnscopedServiceReference();
+ setUpScopedBundleContext();
+ expect(this.scopeServiceRepository.scopeHasMatchingService(eq(SCOPE_NAME), eq(CLASS_NAME), eq(FILTER))).andReturn(true).anyTimes();
+ replay(this.scopeFactory, this.scopeServiceRepository, this.unscopedServiceReference);
+
+ Collection references = new ShrinkableSet(this.unscopedServiceReference);
+ this.serviceScopingStrategy.scopeReferences(references, this.scopedBundleContext, CLASS_NAME, FILTER);
+ assertFalse(references.contains(this.unscopedServiceReference));
+
+ verify(this.scopeFactory, this.scopeServiceRepository, this.unscopedServiceReference);
+ }
+
+ /**
+ * This test uses a collection that does not support addition in order to place the
+ * same constraints on the implementation as the service registry find hook.
+ */
+ private final class ShrinkableSet extends HashSet<ServiceReference> {
+
+ private static final long serialVersionUID = 1L;
+
+ public ShrinkableSet(ServiceReference e) {
+ super();
+ super.add(e);
+ }
+
+ @Override
+ public boolean add(ServiceReference e) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends ServiceReference> c) {
+ throw new UnsupportedOperationException();
+ }
+
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/AbstractOsgiFrameworkLaunchingTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/AbstractOsgiFrameworkLaunchingTests.java
new file mode 100644
index 00000000..44374583
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/AbstractOsgiFrameworkLaunchingTests.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileReader;
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.eclipse.osgi.launch.Equinox;
+import org.eclipse.osgi.service.resolver.PlatformAdmin;
+import org.junit.After;
+import org.junit.Before;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+import org.eclipse.virgo.kernel.osgi.framework.ImportExpander;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiFramework;
+import org.eclipse.virgo.kernel.services.repository.internal.RepositoryFactoryBean;
+import org.eclipse.virgo.kernel.userregion.internal.equinox.EquinoxOsgiFramework;
+import org.eclipse.virgo.kernel.userregion.internal.equinox.KernelClassLoaderCreator;
+import org.eclipse.virgo.kernel.userregion.internal.equinox.TransformedManifestProvidingBundleFileWrapper;
+import org.eclipse.virgo.kernel.userregion.internal.importexpansion.ImportExpansionHandler;
+import org.eclipse.virgo.kernel.userregion.internal.quasi.StandardQuasiFrameworkFactory;
+import org.eclipse.virgo.kernel.userregion.internal.quasi.StandardResolutionFailureDetective;
+
+import org.eclipse.virgo.osgi.extensions.equinox.EquinoxLauncherConfiguration;
+import org.eclipse.virgo.osgi.extensions.equinox.ExtendedEquinoxLauncher;
+import org.eclipse.virgo.osgi.extensions.equinox.hooks.PluggableClassLoadingHook;
+import org.eclipse.virgo.kernel.artifact.bundle.BundleBridge;
+import org.eclipse.virgo.kernel.artifact.library.LibraryBridge;
+import org.eclipse.virgo.medic.dump.DumpGenerator;
+import org.eclipse.virgo.medic.eventlog.EventLogger;
+import org.eclipse.virgo.medic.test.eventlog.MockEventLogger;
+import org.eclipse.virgo.repository.ArtifactBridge;
+import org.eclipse.virgo.repository.Repository;
+import org.eclipse.virgo.repository.RepositoryFactory;
+import org.eclipse.virgo.repository.internal.RepositoryBundleActivator;
+import org.eclipse.virgo.util.io.FileSystemUtils;
+
+public abstract class AbstractOsgiFrameworkLaunchingTests {
+
+ protected EquinoxOsgiFramework framework;
+
+ protected PlatformAdmin platformAdmin;
+
+ protected Repository repository;
+
+ private RepositoryBundleActivator repositoryBundleActivator;
+
+ private BundleContext bundleContext;
+
+ private ServiceRegistration repositoryRegistration;
+
+ private ServiceRegistration eventLoggerRegistration;
+
+ private ServiceRegistration dumpGeneratorRegistration;
+
+ private Equinox equinox;
+
+ protected QuasiFramework quasiFramework;
+
+ @Before
+ public void setUp() throws Exception {
+
+ final File workDir = new File("target/work");
+
+ if (workDir.exists()) {
+ assertTrue(FileSystemUtils.deleteRecursively(new File("target/work")));
+ }
+
+ // Uncomment this line to enable Equinox debugging
+ // FrameworkProperties.setProperty("osgi.debug", "src/test/resources/debug.options");
+ EquinoxLauncherConfiguration launcherConfiguration = new EquinoxLauncherConfiguration();
+ launcherConfiguration.setClean(true);
+ URI targetURI = new File("./target").toURI();
+ launcherConfiguration.setConfigPath(targetURI);
+ launcherConfiguration.setInstallPath(targetURI);
+
+ equinox = ExtendedEquinoxLauncher.launch(launcherConfiguration);
+
+ this.bundleContext = equinox.getBundleContext();
+
+ DumpGenerator dumpGenerator = new DumpGenerator() {
+
+ public void generateDump(String cause, Throwable... throwables) {
+ }
+
+ public void generateDump(String cause, Map<String, Object> context, Throwable... throwables) {
+ }
+
+ };
+
+ final EventLogger mockEventLogger = new MockEventLogger();
+
+ eventLoggerRegistration = bundleContext.registerService(EventLogger.class.getName(), mockEventLogger, null);
+ dumpGeneratorRegistration = bundleContext.registerService(DumpGenerator.class.getName(), dumpGenerator, null);
+
+ this.repositoryBundleActivator = new RepositoryBundleActivator();
+ this.repositoryBundleActivator.start(bundleContext);
+
+ ServiceReference serviceReference = bundleContext.getServiceReference(RepositoryFactory.class.getName());
+ RepositoryFactory repositoryFactory = (RepositoryFactory) bundleContext.getService(serviceReference);
+
+ Properties repositoryProperties = new Properties();
+ repositoryProperties.load(new FileReader(new File(getRepositoryConfigDirectory(), "repository.properties")));
+
+ Set<ArtifactBridge> artifactBridges = new HashSet<ArtifactBridge>();
+ artifactBridges.add(new BundleBridge(new StubHashGenerator()));
+ artifactBridges.add(new LibraryBridge(new StubHashGenerator()));
+
+ RepositoryFactoryBean bean = new RepositoryFactoryBean(repositoryProperties, mockEventLogger, repositoryFactory, new File("target/work"),
+ artifactBridges, null);
+ repository = bean.getObject();
+
+ repositoryRegistration = bundleContext.registerService(Repository.class.getName(), repository, null);
+
+ serviceReference = bundleContext.getServiceReference(PlatformAdmin.class.getName());
+ this.platformAdmin = (PlatformAdmin) bundleContext.getService(serviceReference);
+
+ serviceReference = bundleContext.getServiceReference(PackageAdmin.class.getName());
+ PackageAdmin packageAdmin = (PackageAdmin) bundleContext.getService(serviceReference);
+
+ ImportExpander importExpander = createImportExpander(packageAdmin);
+ TransformedManifestProvidingBundleFileWrapper bundleFileWrapper = new TransformedManifestProvidingBundleFileWrapper(importExpander);
+ this.framework = new EquinoxOsgiFramework(equinox.getBundleContext(), packageAdmin, bundleFileWrapper);
+
+ PluggableClassLoadingHook.getInstance().setClassLoaderCreator(new KernelClassLoaderCreator());
+ StandardResolutionFailureDetective detective = new StandardResolutionFailureDetective(platformAdmin);
+ this.quasiFramework = new StandardQuasiFrameworkFactory(bundleContext, detective, repository, bundleFileWrapper).create();
+ }
+
+ private ImportExpander createImportExpander(PackageAdmin packageAdmin) {
+ Set<String> packagesExportedBySystemBundle = new HashSet<String>(30);
+ ExportedPackage[] exportedPackages = packageAdmin.getExportedPackages(bundleContext.getBundle(0));
+
+ for (ExportedPackage exportedPackage : exportedPackages) {
+ packagesExportedBySystemBundle.add(exportedPackage.getName());
+ }
+
+ return new ImportExpansionHandler(repository, bundleContext, packagesExportedBySystemBundle, new MockEventLogger());
+ }
+
+ @After
+ public void stop() throws Exception {
+
+ if (this.repositoryRegistration != null) {
+ this.repositoryRegistration.unregister();
+ this.repositoryRegistration = null;
+ }
+
+ if (this.dumpGeneratorRegistration != null) {
+ this.dumpGeneratorRegistration.unregister();
+ this.dumpGeneratorRegistration = null;
+ }
+
+ if (this.eventLoggerRegistration != null) {
+ this.eventLoggerRegistration.unregister();
+ this.eventLoggerRegistration = null;
+ }
+
+ if (this.repositoryBundleActivator != null) {
+ this.repositoryBundleActivator.stop(this.bundleContext);
+ this.repositoryBundleActivator = null;
+ }
+
+ if (this.framework != null) {
+ this.framework.stop();
+ this.framework = null;
+ }
+
+ if (this.equinox != null) {
+ this.equinox.stop();
+ this.equinox.waitForStop(30000);
+ }
+ }
+
+ protected abstract String getRepositoryConfigDirectory();
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/BundleInstallationTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/BundleInstallationTests.java
new file mode 100644
index 00000000..57c60415
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/BundleInstallationTests.java
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.net.URI;
+
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiBundle;
+import org.eclipse.virgo.util.osgi.VersionRange;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifestFactory;
+
+/**
+ */
+public class BundleInstallationTests extends AbstractOsgiFrameworkLaunchingTests {
+
+ @Override
+ protected String getRepositoryConfigDirectory() {
+ return new File("src/test/resources/config/BundleInstallationTests").getAbsolutePath();
+ }
+
+ @Test(expected = BundleException.class)
+ public void testFailedInstall() throws Exception {
+ installBundle("fail.parent");
+ }
+
+ @Test
+ public void testInstallFragHost() throws Exception {
+ Bundle bundle = installBundle("frag.host");
+ assertNotNull(bundle);
+ assertEquals(Bundle.INSTALLED, bundle.getState());
+
+ Bundle[] bundles = this.framework.getBundleContext().getBundles();
+ boolean foundChild = false;
+ for (Bundle b : bundles) {
+ if ("frag.child".equals(b.getSymbolicName())) {
+ foundChild = true;
+ break;
+ }
+ }
+ assertTrue(foundChild);
+ }
+
+ @Test
+ public void testInstallFragChild() throws Exception {
+ Bundle bundle = installBundle("frag.child");
+ assertNotNull(bundle);
+ assertEquals(Bundle.RESOLVED, bundle.getState());
+ }
+
+ @Test
+ public void testInstallBundleWithNoDependencies() throws Exception {
+ Bundle bundle = installBundle("org.eclipse.virgo.server.mock.bundle");
+ assertNotNull(bundle);
+ bundle.start();
+ assertEquals(Bundle.ACTIVE, bundle.getState());
+ }
+
+ @Test
+ public void testInstallBundleWithMultipleDependencies() throws Exception {
+ Bundle bundle = installBundle("install.three");
+ assertNotNull(bundle);
+ bundle.start();
+ assertEquals(Bundle.ACTIVE, bundle.getState());
+ }
+
+ @Test
+ public void testInstallBundleWithTransitiveDependencies() throws Exception {
+ Bundle bundle = installBundle("install.four");
+ assertNotNull(bundle);
+ assertEquals(Bundle.RESOLVED, bundle.getState());
+ }
+
+ @Test
+ public void testInstallBundleWithRequireBundle() throws Exception {
+ Bundle bundle = installBundle("install.five");
+ assertNotNull(bundle);
+ assertEquals(Bundle.RESOLVED, bundle.getState());
+ }
+
+ @Test
+ public void testInstallBundleWithCircle() throws Exception {
+ Bundle bundle = installBundle("install.six");
+ assertNotNull(bundle);
+ assertEquals(Bundle.RESOLVED, bundle.getState());
+ }
+
+ @Test
+ public void platform170() throws Exception {
+ Bundle b = installBundle(new File("./src/test/resources/platform170/simpleosgiservice-1.0.0.jar"));
+ b.start();
+
+ b = installBundle(new File("./src/test/resources/platform170/simpleosgiservice-2.0.0.jar"));
+ b.start();
+
+ b = installBundle(new File("./src/test/resources/platform170/simpleosgiapp-1.0.0.jar"));
+ b.start();
+
+ assertEquals(Bundle.ACTIVE, b.getState());
+ }
+
+ @Test
+ public void testInstallWithOptionalImportNotSatisfied() throws Exception {
+ Bundle b = installBundle("install.optional.ns");
+ b.start();
+ assertEquals(Bundle.ACTIVE, b.getState());
+ }
+
+ @Test
+ public void testInstallWithOptionalImportWithNotSatisfiedDependencyInOptional() throws Exception {
+ Bundle b = installBundle("install.optional.dep.bundle");
+ b.start();
+ assertEquals(Bundle.ACTIVE, b.getState());
+ }
+
+ @Test
+ public void testMultipleOptionsChoosesOnlyOneOption() throws Exception {
+ Bundle b = installBundle("install.multi.bundle");
+ b.start();
+ assertEquals(Bundle.ACTIVE, b.getState());
+ Bundle[] bundles = b.getBundleContext().getBundles();
+ for (Bundle bundle : bundles) {
+ if ("install.multi.a".equals(bundle.getSymbolicName())) {
+ fail("Bundle install.multi.a should not have been installed into the framework");
+ }
+ }
+ }
+
+ @Test
+ public void testSatisfyAgainstBundleNotInRepo() throws Exception {
+ installBundle(new File("./src/test/resources/bit/standalone"));
+ Bundle bundle = installBundle("install.six");
+ bundle.start();
+ assertEquals(Bundle.ACTIVE, bundle.getState());
+ }
+
+ @Test(expected = BundleException.class)
+ public void testFailedDueToMissingImport() throws Exception {
+ installBundle("install.error.import");
+ }
+
+ @Test
+ public void testUnresolvableFragmentIsIgnored() throws Exception {
+ Bundle b = installBundle("fragments.unresolvable.host");
+ b.start();
+ assertEquals(Bundle.ACTIVE, b.getState());
+ }
+
+ @Test(expected=BundleException.class)
+ public void testFailDueToUses() throws Exception {
+ installBundle("install.uses.hibernate325");
+ installBundle("install.uses.hibernate326");
+ Bundle b = installBundle("install.uses.spring");
+ b.start();
+
+ assertEquals(Bundle.ACTIVE, b.getState());
+
+ installBundle("install.uses.bundle");
+ }
+
+ private Bundle installBundle(String symbolicName) throws BundleException, IOException {
+ URI bundleLocation = this.repository.get("bundle", symbolicName, VersionRange.NATURAL_NUMBER_RANGE).getUri();
+ File bundleFile = new File(bundleLocation);
+ return installBundle(bundleFile);
+ }
+
+ private Bundle installBundle(File bundleFile) throws BundleException, IOException {
+ Reader manifest;
+ if (bundleFile.isDirectory()) {
+ manifest = ManifestUtils.manifestReaderFromExplodedDirectory(bundleFile);
+ } else {
+ manifest = ManifestUtils.manifestReaderFromJar(bundleFile);
+ }
+
+ QuasiBundle quasiBundle = this.quasiFramework.install(bundleFile.toURI(), BundleManifestFactory.createBundleManifest(manifest));
+ this.quasiFramework.resolve();
+ this.quasiFramework.commit();
+ return quasiBundle.getBundle();
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/BundleUpdateTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/BundleUpdateTests.java
new file mode 100644
index 00000000..4d9e482c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/BundleUpdateTests.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+
+import org.eclipse.virgo.util.io.PathReference;
+
+/**
+ */
+public class BundleUpdateTests extends AbstractOsgiFrameworkLaunchingTests {
+
+ @Override
+ protected String getRepositoryConfigDirectory() {
+ return new File("src/test/resources/config/BundleUpdateTests").getAbsolutePath();
+ }
+
+ /*
+ * This test checks the behaviour of class loading during a bundle update operation. The test passes on Mac OS X, but
+ * it seems unlikely to pass on some other operating systems. The basic question is how can classes be loaded from the
+ * old version of a bundle after the bundle has been updated if install by reference is used.
+ *
+ * The test installs two bundles but.B and but.C and starts but.C. but.C loads class but.A which is exported
+ * by but.B and listens synchronously for an update event for bundle but.B. This test method overwrites bundle but.B
+ * and issues an update for the bundle. The new version of but.B contains a new version of class but.A.
+ *
+ * The old version of bundle but.B also contains a class but.B which depends on the class but.A. The new version
+ * of bundle but.B contains a new version of class but.B which depends on the new version of but.A and which will fail
+ * if it is loaded with the old version of but.A.
+ *
+ * When the synchronous bundle listener in bundle but.C is notified of the update of bundle but.B, it loads the class
+ * but.B. This will succeed if it is loads the old version of the class but will fail if it loads the new version of the
+ * class.
+ */
+ @Test
+ @Ignore("See DMS-284")
+ public void testUpdate() throws Exception {
+ PathReference bBeforeSrc = new PathReference("src/test/resources/but/but.B.before.jar");
+ PathReference b = new PathReference("target/but.B.jar");
+ b.delete();
+ bBeforeSrc.copy(b);
+ Bundle bBundle = this.framework.getBundleContext().installBundle(b.toFile().toURI().toString());
+ assertNotNull(bBundle);
+
+ PathReference cSrc = new PathReference("src/test/resources/but/but.C.jar");
+ PathReference c = new PathReference("target/but.C.jar");
+ c.delete();
+ cSrc.copy(c);
+ Bundle cBundle = this.framework.getBundleContext().installBundle(c.toFile().toURI().toString());
+ assertNotNull(cBundle);
+ cBundle.start();
+
+ PathReference bAfterSrc = new PathReference("src/test/resources/but/but.B.after.jar");
+ b.delete();
+ bAfterSrc.copy(b);
+ bBundle.update();
+
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/EquinoxBootDelegationHelperTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/EquinoxBootDelegationHelperTests.java
new file mode 100644
index 00000000..a1db742c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/EquinoxBootDelegationHelperTests.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.virgo.kernel.userregion.internal.equinox.EquinoxBootDelegationHelper;
+import org.junit.Test;
+
+
+/**
+ */
+public class EquinoxBootDelegationHelperTests {
+
+ @Test public void isBootDelegated() {
+ EquinoxBootDelegationHelper helper = new EquinoxBootDelegationHelper("a.b.c.*, d.e.f");
+
+ assertFalse(helper.isBootDelegated("g.h.MyClass"));
+ assertTrue(helper.isBootDelegated("d.e.f.MyClass"));
+ assertFalse(helper.isBootDelegated("d.e.f.g.MyClass"));
+ assertTrue(helper.isBootDelegated("a.b.c.d.MyClass"));
+
+ // I believe there's a bug in Equinox which we need to mirror. The boot delegation is
+ // specified as (e.g.) org.eclipse.virgo.server.osgi.* which should mean that all classes that
+ // reside in a subpackage of org.eclipse.virgo.server.osgi are boot delegated but those
+ // that reside directly in org.eclipse.virgo.server.osgi are not boot delegated. However,
+ // Equinox treats org.eclipse.virgo.server.osgi.* as meaning that everything in
+ // org.eclipse.virgo.server.osgi and its subpackages is boot delegated.
+ assertTrue(helper.isBootDelegated("a.b.c.MyClass"));
+ assertFalse(helper.isBootDelegated("d.e.MyClass"));
+ assertFalse(helper.isBootDelegated("a.b.MyClass"));
+ }
+
+ @Test public void testDelegationOfAllPackages() {
+ EquinoxBootDelegationHelper helper = new EquinoxBootDelegationHelper("a.b.c.*, *");
+ assertTrue(helper.isBootDelegated("d.e.f.MyClass"));
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/EquinoxOsgiFrameworkTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/EquinoxOsgiFrameworkTests.java
new file mode 100644
index 00000000..460cfb60
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/EquinoxOsgiFrameworkTests.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+import org.eclipse.virgo.kernel.osgi.framework.BundleClassLoaderUnavailableException;
+import org.eclipse.virgo.kernel.osgi.framework.InstrumentableClassLoader;
+import org.eclipse.virgo.kernel.userregion.internal.equinox.EquinoxOsgiFramework;
+import org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader;
+
+/**
+ */
+public class EquinoxOsgiFrameworkTests extends AbstractOsgiFrameworkLaunchingTests {
+
+ @Override
+ protected String getRepositoryConfigDirectory() {
+ return new File("src/test/resources/config/EquinoxOsgiFrameworkTests").getAbsolutePath();
+ }
+
+ @Test
+ public void testStartAndStop() throws Exception {
+ assertNotNull(this.framework.getBundleContext());
+ assertEquals(Bundle.ACTIVE, this.framework.getBundleContext().getBundle().getState());
+ }
+
+ @Test
+ public void testGetClassBundle() throws Exception {
+ Class<?> c = this.framework.getBundleContext().getBundle().loadClass("org.osgi.framework.Bundle");
+ assertNotNull(c);
+ Bundle b = this.framework.getClassBundle(c);
+ assertNotNull(b);
+ assertEquals(0, b.getBundleId());
+ }
+
+ @Test(expected = BundleClassLoaderUnavailableException.class)
+ public void testGetClassLoaderFromUnresolved() throws Exception {
+ Bundle faultyBundle = this.framework.getBundleContext().installBundle(new File("src/test/resources/EquinoxOsgiFrameworkTests/faulty").toURI().toString());
+ assertEquals(Bundle.INSTALLED, faultyBundle.getState());
+ this.framework.getBundleClassLoader(faultyBundle);
+ }
+
+ @Test
+ public void testLoadClassAndGetClassLoader() throws Exception {
+ Bundle bundle = installSpringCore(this.framework);
+ assertEquals("incorrect bundle loaded", "org.springframework.core", bundle.getSymbolicName());
+ Class<?> cls = bundle.loadClass("org.springframework.core.JdkVersion");
+ assertNotNull(cls);
+ assertTrue(cls.getClassLoader() instanceof KernelBundleClassLoader);
+ assertTrue("classloader is screwed", cls.getClassLoader().toString().contains("org.springframework.core"));
+ }
+
+ @Test
+ public void testAddClassFileTransformer() throws Exception {
+ Bundle bundle = installSpringCore(this.framework);
+ ClassLoader bundleClassLoader = this.framework.getBundleClassLoader(bundle);
+ assertNotNull(bundleClassLoader);
+ InstrumentableClassLoader icl = (InstrumentableClassLoader) bundleClassLoader;
+ final AtomicInteger count = new AtomicInteger(0);
+ icl.addClassFileTransformer(new ClassFileTransformer() {
+
+ public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
+ byte[] classfileBuffer) throws IllegalClassFormatException {
+ count.incrementAndGet();
+ return null;
+ }
+
+ });
+ bundle.loadClass("org.springframework.core.JdkVersion");
+ assertEquals(1, count.get());
+ }
+
+ /**
+ * @param osgi
+ * @return
+ * @throws BundleException
+ */
+ private Bundle installSpringCore(EquinoxOsgiFramework osgi) throws BundleException {
+ osgi.getBundleContext().installBundle("file:///" + new File("../ivy-cache/repository/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1/com.springsource.org.apache.commons.logging-1.1.1.jar").getAbsolutePath());
+ return osgi.getBundleContext().installBundle("file:///" + new File("../ivy-cache/repository/org.springframework/org.springframework.core/2.5.6.SEC01/org.springframework.core-2.5.6.SEC01.jar").getAbsolutePath());
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/KernelBundleClassLoaderTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/KernelBundleClassLoaderTests.java
new file mode 100644
index 00000000..e871c0b4
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/KernelBundleClassLoaderTests.java
@@ -0,0 +1,111 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+import org.eclipse.virgo.kernel.osgi.framework.UnableToSatisfyDependenciesException;
+
+/**
+ *
+ */
+public class KernelBundleClassLoaderTests extends AbstractOsgiFrameworkLaunchingTests {
+
+ private Bundle dependant;
+
+ @Override
+ protected String getRepositoryConfigDirectory() {
+ return new File("src/test/resources/config/KernelBundleClassLoaderTests").getAbsolutePath();
+ }
+
+ /**
+ * Test method for {@link org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader#getResources(java.lang.String)}.
+ * @throws UnableToSatisfyDependenciesException
+ * @throws Exception
+ */
+ @SuppressWarnings("unchecked")
+ @Test
+ public void testGetResourcesStringFromBundle() throws Exception {
+ Enumeration<URL> resources = this.dependant.getResources("/META-INF/GET_ME");
+
+ assertNotNull(resources);
+ assertTrue(resources.hasMoreElements());
+ assertTrue(resources.nextElement().getPath().endsWith("bundlefile!/META-INF/GET_ME"));
+
+ }
+
+ /**
+ * Test method for {@link org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader#getResource(java.lang.String)}.
+ * @throws UnableToSatisfyDependenciesException
+ * @throws Exception
+ */
+ @Test
+ public void testGetResourceStringFromBundle() throws Exception {
+ URL resource = this.dependant.getResource("/META-INF/GET_ME");
+
+ assertNotNull(resource);
+ assertTrue(resource.getPath().endsWith("bundlefile!/META-INF/GET_ME"));
+ }
+
+ /**
+ * Test method for {@link org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader#getResources(java.lang.String)}.
+ * @throws UnableToSatisfyDependenciesException
+ * @throws Exception
+ */
+ @Test
+ public void testGetResourcesStringFromBundleClassLoader() throws Exception {
+ Bundle bundle = this.dependant;
+ ClassLoader loader = this.framework.getBundleClassLoader(bundle);
+ Enumeration<URL> resources = loader.getResources("/META-INF/GET_ME");
+
+ assertNotNull(resources);
+ assertTrue(resources.hasMoreElements());
+ assertTrue(resources.nextElement().getPath().endsWith("bundlefile!/META-INF/GET_ME"));
+
+ }
+
+ /**
+ * Test method for {@link org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader#getResource(java.lang.String)}.
+ * @throws UnableToSatisfyDependenciesException
+ * @throws Exception
+ */
+ @Test
+ public void testGetResourceStringFromBundleClassLoader() throws Exception {
+ ClassLoader loader = this.framework.getBundleClassLoader(this.dependant);
+ URL resource = loader.getResource("/META-INF/GET_ME");
+
+ assertNotNull(resource);
+ assertTrue(resource.getPath().endsWith("bundlefile!/META-INF/GET_ME"));
+ }
+
+
+ @Before
+ public void installDependant() throws BundleException {
+ this.dependant = this.framework.getBundleContext().installBundle(new File("src/test/resources/KernelBundleClassLoaderTests/dependant.jar").toURI().toString());
+ }
+
+ @After
+ public void uninstallDependant() throws BundleException {
+ this.dependant.uninstall();
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/LoadTimeWeavingTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/LoadTimeWeavingTests.java
new file mode 100644
index 00000000..5570fa02
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/LoadTimeWeavingTests.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+
+import java.io.File;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.eclipse.virgo.kernel.userregion.internal.equinox.KernelBundleClassLoader;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+
+
+/**
+ */
+public class LoadTimeWeavingTests extends AbstractOsgiFrameworkLaunchingTests {
+
+ private static final String DOMAIN_TYPE_NAME = "ltw.domain.DomainType";
+
+ private static final String A_TYPE_NAME = "app.a.A";
+
+ private static final String B_TYPE_NAME = "app.b.B";
+
+ private Bundle emBundle;
+
+ private Bundle includeBundle;
+
+ @Override
+ protected String getRepositoryConfigDirectory() {
+ return new File("src/test/resources/config/LoadTimeWeavingTests").getAbsolutePath();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+
+ this.framework.getBundleContext().installBundle(new File("src/test/resources/ltw/ltw-domain.jar").toURI().toString());
+ this.includeBundle = this.framework.getBundleContext().installBundle(new File("src/test/resources/ltw/ltw-include.jar").toURI().toString());
+ this.emBundle = this.framework.getBundleContext().installBundle(new File("src/test/resources/ltw/ltw-em.jar").toURI().toString());
+ }
+
+ @Test public void instrumentPackageIncludes() throws ClassNotFoundException {
+ KernelBundleClassLoader incClassLoader = (KernelBundleClassLoader) this.framework.getBundleClassLoader(this.includeBundle);
+ assertNotNull(incClassLoader);
+
+ ClassLoader throwAway = incClassLoader.createThrowAway();
+ assertEquals(throwAway, throwAway.loadClass(A_TYPE_NAME).getClassLoader());
+ assertEquals(incClassLoader, throwAway.loadClass(B_TYPE_NAME).getClassLoader());
+ }
+
+ @Test public void throwawayAcrossBundles() throws ClassNotFoundException {
+ KernelBundleClassLoader emClassLoader = (KernelBundleClassLoader) this.framework.getBundleClassLoader(this.emBundle);
+ assertNotNull(emClassLoader);
+ ClassLoader throwAway = emClassLoader.createThrowAway();
+ Class<?> domainTypeClass = throwAway.loadClass(DOMAIN_TYPE_NAME);
+ assertNotNull(domainTypeClass);
+ assertNotSame(emClassLoader.loadClass(DOMAIN_TYPE_NAME), domainTypeClass);
+ assertSame(domainTypeClass, throwAway.loadClass(DOMAIN_TYPE_NAME));
+ }
+
+ @Test public void weaveAcrossBundles() throws ClassNotFoundException {
+ KernelBundleClassLoader emClassLoader = (KernelBundleClassLoader) this.framework.getBundleClassLoader(this.emBundle);
+ assertNotNull(emClassLoader);
+ final AtomicInteger counter = new AtomicInteger(0);
+ emClassLoader.addClassFileTransformer(new ClassFileTransformer() {
+
+ public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
+ byte[] classfileBuffer) throws IllegalClassFormatException {
+ counter.incrementAndGet();
+ return null;
+ }
+
+ });
+ Class<?> domainTypeClass = emClassLoader.loadClass(DOMAIN_TYPE_NAME);
+ assertNotNull(domainTypeClass);
+ assertEquals(1, counter.get());
+ }
+
+ @Test public void testRefreshWithNoPropagation() throws Exception {
+ Class<?> before = this.emBundle.loadClass(DOMAIN_TYPE_NAME);
+ this.framework.refresh(this.emBundle);
+ waitUntilResolved(3000);
+ assertSame(this.emBundle.loadClass(DOMAIN_TYPE_NAME), before);
+ }
+
+ @Test public void testRefreshWithPropagation() throws Exception {
+ KernelBundleClassLoader emClassLoader = (KernelBundleClassLoader) this.framework.getBundleClassLoader(this.emBundle);
+ emClassLoader.addClassFileTransformer(new ClassFileTransformer() {
+
+ public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
+ byte[] classfileBuffer) throws IllegalClassFormatException {
+ return null;
+ }
+
+ });
+ Class<?> before = this.emBundle.loadClass(DOMAIN_TYPE_NAME);
+ this.framework.refresh(this.emBundle);
+ waitUntilResolved(3000);
+ assertNotSame(this.emBundle.loadClass(DOMAIN_TYPE_NAME), before);
+ }
+
+ private void waitUntilResolved(int maxWaitInMillis) {
+ boolean resolved = this.emBundle.getState() == Bundle.RESOLVED;
+ while (!resolved && maxWaitInMillis>0) {
+ try {
+ Thread.sleep(50); maxWaitInMillis-=50;
+ } catch (InterruptedException e) {
+ continue;
+ }
+ resolved = this.emBundle.getState() == Bundle.RESOLVED;
+ }
+ }
+}
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/ManifestUtils.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/ManifestUtils.java
new file mode 100644
index 00000000..48203421
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/ManifestUtils.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.eclipse.virgo.util.io.FileCopyUtils;
+
+/**
+ * Utility class for extracting a {@link Reader} for manifest data in a JAR file and in exploded JAR directories.
+ * <p/>
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * Threadsafe.
+ *
+ */
+public final class ManifestUtils {
+
+ private static final String MANIFEST_DIRECTORY_LOCATION = "META-INF" + File.separator + "MANIFEST.MF";
+
+ private static final String MANIFEST_ENTRY = "META-INF/MANIFEST.MF";
+
+ /**
+ * Creates a {@link Reader} for the manifest in the supplied exploded JAR directory.
+ *
+ * @param directory the exploded JAR directory.
+ * @return the <code>Reader</code> or <code>null</code> if the manifest cannot be found.
+ */
+ public static final Reader manifestReaderFromExplodedDirectory(File directory) {
+ if (directory == null || !directory.isDirectory()) {
+ throw new IllegalArgumentException("Must supply a valid directory");
+ }
+ try {
+ File manifestFile = new File(directory.getAbsolutePath() + File.separator + MANIFEST_DIRECTORY_LOCATION);
+ if (manifestFile.exists()) {
+ return new FileReader(manifestFile);
+ } else {
+ return null;
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to read MANIFEST for exploded directory '" + directory.getAbsolutePath() + "'.", e);
+ }
+ }
+
+ /**
+ * Creates a {@link Reader} for the manifest in the supplied JAR file.
+ *
+ * @param file the JAR file.
+ * @return the <code>Reader</code> or <code>null</code> if the manifest cannot be found.
+ */
+ public static final Reader manifestReaderFromJar(File file) {
+ JarFile jar = null;
+ try {
+ jar = new JarFile(file);
+ JarEntry entry = jar.getJarEntry(MANIFEST_ENTRY);
+ if (entry != null) {
+ StringWriter writer = new StringWriter();
+ FileCopyUtils.copy(new InputStreamReader(jar.getInputStream(entry)), writer);
+ jar.close();
+ return new StringReader(writer.toString());
+ } else {
+ return null;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException("Cannot read MANIFEST.MF from jar '" + file.getAbsolutePath() + "'.", e);
+ } finally {
+ if (jar != null) {
+ try {
+ jar.close();
+ } catch (IOException ioe) {
+ throw new RuntimeException("Failed to close jar '" + file.getAbsolutePath() + "'.", ioe);
+ }
+ }
+ }
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/ResolutionStateDumperTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/ResolutionStateDumperTests.java
new file mode 100644
index 00000000..7e801cd8
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/ResolutionStateDumperTests.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.osgi.service.resolver.State;
+import org.junit.Test;
+
+import org.eclipse.virgo.kernel.userregion.internal.equinox.ResolutionStateDumper;
+import org.eclipse.virgo.kernel.userregion.internal.equinox.StateWriter;
+import org.eclipse.virgo.kernel.userregion.internal.equinox.SystemStateAccessor;
+import org.eclipse.virgo.util.io.PathReference;
+import org.eclipse.virgo.util.io.ZipUtils;
+
+/**
+ */
+public class ResolutionStateDumperTests {
+
+ @Test
+ public void createDump() throws Exception {
+
+ State state = createNiceMock(State.class);
+ StubStateWriter writer = new StubStateWriter();
+
+ byte[] bytes = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ writer.addBytes(state, bytes);
+
+ ResolutionStateDumper dumper = new ResolutionStateDumper(new StubSystemStateAccessor(state), writer);
+
+ File outputFile = new File("./target/dump.zip");
+ if (outputFile.exists()) {
+ assertTrue(outputFile.delete());
+ }
+
+ dumper.dump(outputFile);
+
+ assertTrue(outputFile.exists());
+
+ PathReference unzipLocation = new PathReference("target/dump");
+ if (unzipLocation.exists()) {
+ assertTrue(unzipLocation.delete(true));
+ }
+
+ ZipUtils.unzipTo(new PathReference(outputFile), unzipLocation);
+ File stateFile = new File("target/dump/state/state");
+
+ assertTrue(stateFile.exists());
+ assertEquals(10, stateFile.length());
+
+ byte[] actualBytes = new byte[10];
+
+ new FileInputStream(stateFile).read(actualBytes);
+
+ assertArrayEquals(bytes, actualBytes);
+ }
+
+ private static final class StubSystemStateAccessor implements SystemStateAccessor {
+
+ private final State systemState;
+
+ private StubSystemStateAccessor(State systemState) {
+ this.systemState = systemState;
+ }
+
+ public State getSystemState() {
+ return this.systemState;
+ }
+ }
+
+ private static final class StubStateWriter implements StateWriter {
+
+ private final Map<State, byte[]> stateBytes = new HashMap<State, byte[]>();
+
+ private void addBytes(State state, byte[] bytes) {
+ this.stateBytes.put(state, bytes);
+ }
+
+ public void writeState(State state, File outputDir) throws IOException {
+ byte[] bytes = this.stateBytes.get(state);
+ if (bytes == null) {
+ throw new IOException();
+ } else {
+ FileOutputStream fos = null;
+
+ try {
+ fos = new FileOutputStream(new File(outputDir, "state"));
+ fos.write(bytes);
+ } finally {
+ if (fos != null) {
+ fos.close();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/StubHashGenerator.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/StubHashGenerator.java
new file mode 100644
index 00000000..375d3d3c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/StubHashGenerator.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import java.io.File;
+
+import org.eclipse.virgo.repository.HashGenerator;
+import org.eclipse.virgo.repository.builder.ArtifactDescriptorBuilder;
+
+public class StubHashGenerator implements HashGenerator {
+
+ public void generateHash(ArtifactDescriptorBuilder artifactDescriptorBuilder, File artifactFile) {
+ // Do nothing
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/TestUtils.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/TestUtils.java
new file mode 100644
index 00000000..78eff8bb
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/TestUtils.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import java.io.File;
+
+/**
+ */
+public class TestUtils {
+
+ public static boolean deleteRecursively(File root) {
+ if (root.exists()) {
+ if (root.isDirectory()) {
+ File[] children = root.listFiles();
+ for (File file : children) {
+ deleteRecursively(file);
+ }
+ }
+ return root.delete();
+ }
+ return false;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/UsesAnalyserTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/UsesAnalyserTests.java
new file mode 100644
index 00000000..84701566
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/equinox/UsesAnalyserTests.java
@@ -0,0 +1,162 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.equinox;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+
+import org.eclipse.osgi.internal.baseadaptor.StateManager;
+import org.eclipse.osgi.service.resolver.ResolverError;
+import org.eclipse.osgi.service.resolver.State;
+import org.eclipse.virgo.kernel.userregion.internal.equinox.UsesAnalyser;
+import org.eclipse.virgo.kernel.userregion.internal.equinox.UsesAnalyser.AnalysedUsesConflict;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+import org.osgi.framework.Version;
+
+
+/**
+ */
+public class UsesAnalyserTests extends AbstractOsgiFrameworkLaunchingTests {
+
+ @Override
+ protected String getRepositoryConfigDirectory() {
+ return new File("src/test/resources/config/UsesAnalyserTests").getAbsolutePath();
+ }
+
+ @Test
+ public void testDependentConstraints() throws Exception {
+ Bundle p = install("dependent/bundles/p");
+ install("dependent/bundles/q");
+ install("dependent/bundles/r1");
+ install("dependent/bundles/r2");
+ install("dependent/bundles/s1");
+ install("dependent/bundles/s2");
+
+ try {
+ p.start();
+ } catch (BundleException ex) {
+ }
+
+ State systemState = ((StateManager) this.platformAdmin).getSystemState();
+
+ UsesAnalyser analyser = new UsesAnalyser();
+
+ ResolverError[] resolverErrors = analyser.getUsesResolverErrors(systemState, systemState.getBundle(p.getBundleId()));
+ assertNotNull("No uses errors found for bundle '" + p + "'.", resolverErrors);
+
+ AnalysedUsesConflict[] usesConflicts = analyser.getUsesConflicts(systemState, resolverErrors[0]);
+ assertNotNull("No conflicts found for bundle '" + p + "'.", usesConflicts);
+ printUsesConflicts(usesConflicts);
+
+ assertEquals("No, or more than one conflict discovered.", 1, usesConflicts.length);
+
+ assertEquals("q",usesConflicts[0].getUsesRootPackage().getName());
+
+ assertEquals("r",usesConflicts[0].getPackage().getName());
+ assertEquals(new Version("1.1.0"), usesConflicts[0].getPackage().getVersion());
+
+ assertEquals("r",usesConflicts[0].getConflictingPackage().getName());
+ assertEquals(new Version("1.0.0"), usesConflicts[0].getConflictingPackage().getVersion());
+ }
+
+ @Test
+ public void testInstallOrder() throws Exception {
+ install("install/bundles/s1");
+ install("install/bundles/s2");
+ Bundle q = install("install/bundles/q");
+ install("install/bundles/r1");
+ q.start();
+
+ Bundle p = install("install/bundles/p");
+ install("install/bundles/r2");
+ try {
+ p.start();
+ } catch (BundleException ex) {
+ }
+
+ State systemState = ((StateManager) this.platformAdmin).getSystemState();
+ UsesAnalyser analyser = new UsesAnalyser();
+
+ ResolverError[] resolverErrors = analyser.getUsesResolverErrors(systemState, systemState.getBundle(p.getBundleId()));
+ assertNotNull("No uses errors found for bundle '" + p + "'.", resolverErrors);
+
+ AnalysedUsesConflict[] usesConflicts = analyser.getUsesConflicts(systemState, resolverErrors[0]);
+
+ assertNotNull("No conflicts found for bundle '" + p + "'.", usesConflicts);
+ printUsesConflicts(usesConflicts);
+
+ assertEquals("No, or more than one conflict discovered.", 1, usesConflicts.length);
+
+ assertEquals("q",usesConflicts[0].getUsesRootPackage().getName());
+
+ assertEquals("r",usesConflicts[0].getPackage().getName());
+ assertEquals(new Version("1.1.0"), usesConflicts[0].getPackage().getVersion());
+
+ assertEquals("r",usesConflicts[0].getConflictingPackage().getName());
+ assertEquals(new Version("1.0.0"), usesConflicts[0].getConflictingPackage().getVersion());
+
+ }
+
+ @Test
+ public void transitiveUsesConstraint() throws Exception {
+ install("transitiveconstraint/tmD.jar");
+ install("transitiveconstraint/tmC.jar");
+ install("transitiveconstraint/tmB.jar");
+ Bundle a = install("transitiveconstraint/tmA.jar");
+ try {
+ a.start();
+ } catch (BundleException _) {
+ }
+
+ State systemState = ((StateManager) this.platformAdmin).getSystemState();
+ UsesAnalyser analyser = new UsesAnalyser();
+
+ ResolverError[] resolverErrors = analyser.getUsesResolverErrors(systemState, systemState.getBundle(a.getBundleId()));
+ assertNotNull("No uses errors found for bundle '" + a + "'.", resolverErrors);
+
+ AnalysedUsesConflict[] usesConflicts = analyser.getUsesConflicts(systemState, resolverErrors[0]);
+
+ assertNotNull("No conflicts found for bundle '" + a + "'.", usesConflicts);
+ printUsesConflicts(usesConflicts);
+
+ assertEquals("No, or more than one conflict discovered.", 1, usesConflicts.length);
+
+ assertEquals("p",usesConflicts[0].getUsesRootPackage().getName());
+
+ assertEquals("r",usesConflicts[0].getPackage().getName());
+ assertEquals(new Version("1.0.0"), usesConflicts[0].getPackage().getVersion());
+
+ assertEquals("r",usesConflicts[0].getConflictingPackage().getName());
+ assertEquals(new Version("0.0.0"), usesConflicts[0].getConflictingPackage().getVersion());
+ }
+
+ private static final void printUsesConflicts(AnalysedUsesConflict[] usesConflicts) {
+ int count = 0;
+ for (AnalysedUsesConflict a : usesConflicts) {
+ System.out.println("AnalysedUsesConflict element " + (count++));
+ for (String s : a.getConflictStatement()) {
+ System.out.println(" " + s);
+ }
+ }
+ }
+
+ private Bundle install(String subPath) throws BundleException {
+ String fullPath = "src/test/resources/uat/" + subPath;
+ String location = "reference:file:/" + new File(fullPath).getAbsolutePath();
+ return this.framework.getBundleContext().installBundle(location);
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/importexpansion/ImportExpansionHandlerTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/importexpansion/ImportExpansionHandlerTests.java
new file mode 100644
index 00000000..2fbccb49
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/importexpansion/ImportExpansionHandlerTests.java
@@ -0,0 +1,751 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.importexpansion;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Version;
+
+import org.eclipse.virgo.kernel.osgi.framework.UnableToSatisfyBundleDependenciesException;
+import org.eclipse.virgo.kernel.osgi.framework.UnableToSatisfyDependenciesException;
+import org.eclipse.virgo.kernel.userregion.internal.equinox.StubHashGenerator;
+import org.eclipse.virgo.kernel.userregion.internal.importexpansion.ImportExpansionHandler;
+
+
+import org.eclipse.virgo.kernel.artifact.bundle.BundleBridge;
+import org.eclipse.virgo.kernel.artifact.library.LibraryBridge;
+import org.eclipse.virgo.medic.test.eventlog.MockEventLogger;
+import org.eclipse.virgo.repository.ArtifactDescriptor;
+import org.eclipse.virgo.repository.ArtifactGenerationException;
+import org.eclipse.virgo.repository.Attribute;
+import org.eclipse.virgo.repository.Query;
+import org.eclipse.virgo.repository.Repository;
+import org.eclipse.virgo.repository.RepositoryAwareArtifactDescriptor;
+import org.eclipse.virgo.util.osgi.VersionRange;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifestFactory;
+import org.eclipse.virgo.util.osgi.manifest.ImportedBundle;
+import org.eclipse.virgo.util.osgi.manifest.ImportedLibrary;
+import org.eclipse.virgo.util.osgi.manifest.ImportedPackage;
+import org.eclipse.virgo.util.osgi.manifest.Resolution;
+
+/**
+ */
+public class ImportExpansionHandlerTests {
+
+ private StubRepository repository = new StubRepository();
+
+ private static Set<String> packagesExportedBySystemBundle = new HashSet<String>();
+
+ static {
+ packagesExportedBySystemBundle.add("javax.crypto.spec");
+ packagesExportedBySystemBundle.add("javax.imageio");
+ packagesExportedBySystemBundle.add("javax.imageio.event");
+ }
+
+ @Before
+ public void populateRepository() throws ArtifactGenerationException {
+ BundleBridge bundleBridge = new BundleBridge(new StubHashGenerator());
+ LibraryBridge libraryBridge = new LibraryBridge(new StubHashGenerator());
+
+ this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(new File("../ivy-cache/repository/org.springframework/org.springframework.core/2.5.6.SEC01/org.springframework.core-2.5.6.SEC01.jar")));
+ this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(new File("../ivy-cache/repository/org.springframework/org.springframework.beans/2.5.6.SEC01/org.springframework.beans-2.5.6.SEC01.jar")));
+ this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(new File("src/test/resources/silht/bundles/fragmentOne")));
+ this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(new File("src/test/resources/silht/bundles/fragmentTwo")));
+ this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(new File("src/test/resources/silht/bundles/noexports")));
+ this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(new File("src/test/resources/silht/bundles/fragmentwithnoexports")));
+ this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(new File("src/test/resources/silht/bundles/host")));
+ this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(new File("src/test/resources/silht/bundles/overlapper")));
+ this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(new File("src/test/resources/silht/bundles/multi-version-export")));
+ this.repository.addArtifactDescriptor(libraryBridge.generateArtifactDescriptor(new File("src/test/resources/silht/libraries/spring.libd")));
+ this.repository.addArtifactDescriptor(libraryBridge.generateArtifactDescriptor(new File("src/test/resources/silht/libraries/com.foo.libd")));
+ this.repository.addArtifactDescriptor(libraryBridge.generateArtifactDescriptor(new File("src/test/resources/silht/libraries/missing.optional.bundle.libd")));
+ }
+
+ @Test
+ public void basicImportBundle() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(bundleImport.getBundleSymbolicName()).andReturn("org.springframework.core").atLeastOnce();
+ expect(bundleImport.getVersion()).andReturn(new VersionRange("[2.5,3.0)")).atLeastOnce();
+ expect(bundleImport.isApplicationImportScope()).andReturn(false).atLeastOnce();
+ expect(bundleImport.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+
+ handler.expandImports(new ArrayList<ImportedLibrary>(), Arrays.asList(new ImportedBundle[] { bundleImport }), bundleManifest);
+
+ verifyMocks(mocks);
+
+ assertEquals(19, bundleManifest.getImportPackage().getImportedPackages().size());
+
+ List<ImportedPackage> packageImports = bundleManifest.getImportPackage().getImportedPackages();
+ for (ImportedPackage packageImport : packageImports) {
+ Map<String, String> attributes = packageImport.getAttributes();
+ assertTrue("org.springframework.core".equals(attributes.get("bundle-symbolic-name")));
+ assertEquals(new VersionRange("[2.5.6.SEC01,2.5.6.SEC01]"), new VersionRange(attributes.get("bundle-version")));
+ }
+ }
+
+ @Test
+ public void basicImportLibrary() throws UnableToSatisfyDependenciesException {
+
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks);
+
+ expect(libraryImport.getLibrarySymbolicName()).andReturn("org.springframework").atLeastOnce();
+ expect(libraryImport.getVersion()).andReturn(new VersionRange("[2.5,3.0)")).atLeastOnce();
+ expect(libraryImport.getResolution()).andReturn(Resolution.MANDATORY).anyTimes();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport }), Arrays.asList(new ImportedBundle[0]), bundleManifest);
+
+ verifyMocks(mocks);
+
+ assertEquals(34, bundleManifest.getImportPackage().getImportedPackages().size());
+
+ List<ImportedPackage> packageImports = bundleManifest.getImportPackage().getImportedPackages();
+ for (ImportedPackage packageImport : packageImports) {
+ Map<String, String> attributes = packageImport.getAttributes();
+ if (packageImport.getPackageName().startsWith("org.springframework.beans")) {
+ assertTrue("org.springframework.beans".equals(attributes.get("bundle-symbolic-name")));
+ } else {
+ assertTrue("org.springframework.core".equals(attributes.get("bundle-symbolic-name")));
+ }
+ assertEquals(new VersionRange("[2.5.6.SEC01,2.5.6.SEC01]"), new VersionRange(attributes.get("bundle-version")));
+ }
+
+ }
+
+ @Test
+ public void basicImportFragmentBundle() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(bundleImport.getBundleSymbolicName()).andReturn("com.foo.fragment.one").atLeastOnce();
+ expect(bundleImport.getVersion()).andReturn(new VersionRange("[1,1]")).atLeastOnce();
+ expect(bundleImport.isApplicationImportScope()).andReturn(false).atLeastOnce();
+ expect(bundleImport.getResolution()).andReturn(Resolution.MANDATORY).anyTimes();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+
+ handler.expandImports(Arrays.asList(new ImportedLibrary[0]), Arrays.asList(new ImportedBundle[] { bundleImport }), bundleManifest);
+
+ verifyMocks(mocks);
+
+ assertEquals(1, bundleManifest.getImportPackage().getImportedPackages().size());
+
+ ImportedPackage packageImport = bundleManifest.getImportPackage().getImportedPackages().get(0);
+ Map<String, String> attributes = packageImport.getAttributes();
+ assertEquals("com.foo.host", attributes.get("bundle-symbolic-name"));
+ assertEquals(new VersionRange("[1.0, 2.0)"), new VersionRange(attributes.get("bundle-version")));
+ assertEquals("com.foo.host", packageImport.getPackageName());
+ }
+
+ @Test(expected = UnableToSatisfyBundleDependenciesException.class)
+ public void importLibraryReferringToNonExistentBundle() throws UnableToSatisfyDependenciesException, IOException {
+
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks);
+
+ expect(libraryImport.getLibrarySymbolicName()).andReturn("bad.bundle").atLeastOnce();
+ expect(libraryImport.getVersion()).andReturn(new VersionRange("[9,9]")).atLeastOnce();
+ expect(libraryImport.getResolution()).andReturn(Resolution.MANDATORY).anyTimes();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest(new StringReader(
+ "Manifest-Version: 1.0\nBundle-SymbolicName: test.bundle"));
+
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport }), Arrays.asList(new ImportedBundle[0]), bundleManifest);
+ }
+
+ @Test
+ public void optionalImportBundle() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(bundleImport.getBundleSymbolicName()).andReturn("org.springframework.dosnt.exist").atLeastOnce();
+ expect(bundleImport.getVersion()).andReturn(new VersionRange("[6.5,7.0)")).atLeastOnce();
+ expect(bundleImport.isApplicationImportScope()).andReturn(false).anyTimes();
+ expect(bundleImport.getResolution()).andReturn(Resolution.OPTIONAL).anyTimes();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+
+ handler.expandImports(Arrays.asList(new ImportedLibrary[0]), Arrays.asList(new ImportedBundle[] { bundleImport }), bundleManifest);
+
+ verifyMocks(mocks);
+
+ assertTrue("" + bundleManifest.getImportPackage().getImportedPackages().size(),
+ bundleManifest.getImportPackage().getImportedPackages().size() == 0);
+ }
+
+ @Test
+ public void optionalImportLibrary() throws UnableToSatisfyDependenciesException {
+
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks);
+
+ expect(libraryImport.getLibrarySymbolicName()).andReturn("org.springframework.dosnt.exist").atLeastOnce();
+ expect(libraryImport.getVersion()).andReturn(new VersionRange("[6.5,7.0)")).atLeastOnce();
+ expect(libraryImport.getResolution()).andReturn(Resolution.OPTIONAL).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport }), Arrays.asList(new ImportedBundle[0]), bundleManifest);
+
+ verifyMocks(mocks);
+
+ assertTrue(bundleManifest.getImportPackage().getImportedPackages().size() == 0);
+ }
+
+ @Test(expected = UnableToSatisfyDependenciesException.class)
+ public void optionalImportLibraryException() throws UnableToSatisfyDependenciesException {
+
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks);
+
+ expect(libraryImport.getLibrarySymbolicName()).andReturn("org.springframework.dosnt.exist").atLeastOnce();
+ expect(libraryImport.getVersion()).andReturn(new VersionRange("[6.5,7.0)")).atLeastOnce();
+ expect(libraryImport.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport }), Arrays.asList(new ImportedBundle[0]), bundleManifest);
+ }
+
+ /**
+ * Test the expansion of the following import:
+ *
+ * Import-Library: com.foo;version="[1.0,2.0)"
+ *
+ * @throws UnableToSatisfyDependenciesException
+ */
+ @Test
+ public void importLibraryWithFragment() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks);
+ expect(libraryImport.getLibrarySymbolicName()).andReturn("com.foo").atLeastOnce();
+ expect(libraryImport.getVersion()).andReturn(new VersionRange("[1.0,2.0)")).atLeastOnce();
+ expect(libraryImport.getResolution()).andReturn(Resolution.MANDATORY).anyTimes();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport }), Arrays.asList(new ImportedBundle[0]), bundleManifest);
+
+ verifyMocks(mocks);
+
+ assertImported(bundleManifest, Arrays.asList(new String[] { "com.foo.host", "com.foo.host.a", "com.foo.host.b", "com.foo.fragment.two" }),
+ Arrays.asList(new String[] { "1.5.0", "1.0.0", "1.0.0", "1.0.0" }));
+ }
+
+ @Test(expected = UnableToSatisfyDependenciesException.class)
+ public void incompatibleBundleVersions() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedLibrary libraryImport1 = createAndStoreMock(ImportedLibrary.class, mocks);
+ expect(libraryImport1.getLibrarySymbolicName()).andReturn("org.springframework").atLeastOnce();
+ expect(libraryImport1.getVersion()).andReturn(new VersionRange("[2.5,3.0)")).atLeastOnce();
+ expect(libraryImport1.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportedLibrary libraryImport2 = createAndStoreMock(ImportedLibrary.class, mocks);
+ expect(libraryImport2.getLibrarySymbolicName()).andReturn("org.springframework").atLeastOnce();
+ expect(libraryImport2.getVersion()).andReturn(new VersionRange("[2.0,2.5)")).atLeastOnce();
+ expect(libraryImport2.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+ try {
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport1, libraryImport2 }), Arrays.asList(new ImportedBundle[0]),
+ bundleManifest);
+ } catch (UnableToSatisfyDependenciesException e) {
+ throw e;
+ }
+ }
+
+ @Test(expected = UnableToSatisfyDependenciesException.class)
+ public void incompatibleIntersection() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedLibrary libraryImport1 = createAndStoreMock(ImportedLibrary.class, mocks);
+ expect(libraryImport1.getLibrarySymbolicName()).andReturn("com.intersect.one").atLeastOnce();
+ expect(libraryImport1.getVersion()).andReturn(new VersionRange("[1.0,2.0)")).atLeastOnce();
+ expect(libraryImport1.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportedLibrary libraryImport2 = createAndStoreMock(ImportedLibrary.class, mocks);
+ expect(libraryImport2.getLibrarySymbolicName()).andReturn("com.intersect.two").atLeastOnce();
+ expect(libraryImport2.getVersion()).andReturn(new VersionRange("[1.0,2.0)")).atLeastOnce();
+ expect(libraryImport2.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+ try {
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport1, libraryImport2 }), Arrays.asList(new ImportedBundle[0]),
+ bundleManifest);
+ } catch (UnableToSatisfyDependenciesException e) {
+ throw e;
+ }
+ }
+
+ public void disjointImportedPackageAndImportedLibraryVersionRanges() throws UnableToSatisfyDependenciesException, IOException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks);
+ expect(libraryImport.getLibrarySymbolicName()).andReturn("org.springframework").atLeastOnce();
+ expect(libraryImport.getVersion()).andReturn(new VersionRange("[2.5,3.0)")).atLeastOnce();
+ expect(libraryImport.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest(new StringReader(
+ "Bundle-SymbolicName: B\nImport-Package: org.springframework.core;version=\"[1,2]\""));
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport }), Arrays.asList(new ImportedBundle[0]), bundleManifest);
+ }
+
+ public void disjointImportedPackageAndImportedBundleVersionRanges() throws UnableToSatisfyDependenciesException, IOException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(bundleImport.getBundleSymbolicName()).andReturn("org.springframework.bundle.spring.core").atLeastOnce();
+ expect(bundleImport.getVersion()).andReturn(new VersionRange("[2.5,3.0)")).atLeastOnce();
+ expect(bundleImport.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+ expect(bundleImport.isApplicationImportScope()).andReturn(false);
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest(new StringReader(
+ "Bundle-SymbolicName: B\nImport-Package: org.springframework.core;version=\"[1,2]\""));
+ handler.expandImports(Arrays.asList(new ImportedLibrary[0]), Arrays.asList(new ImportedBundle[] { bundleImport }), bundleManifest);
+ }
+
+ @Test
+ public void packageImportAndImportedBundleVersionRangeIntersection() throws UnableToSatisfyDependenciesException, IOException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(bundleImport.getBundleSymbolicName()).andReturn("org.springframework.core").atLeastOnce();
+ expect(bundleImport.getVersion()).andReturn(new VersionRange("[2.5,3.0)")).atLeastOnce();
+ expect(bundleImport.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+ expect(bundleImport.isApplicationImportScope()).andReturn(false);
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest(new StringReader(
+ "Manifest-Version: 1.0, Bundle-SymbolicName: B\nImport-Package: org.springframework.core;version=\"[2.5,2.6)\""));
+ handler.expandImports(Arrays.asList(new ImportedLibrary[0]), Arrays.asList(new ImportedBundle[] { bundleImport }), bundleManifest);
+
+ verifyMocks(mocks);
+
+ assertEquals(19, bundleManifest.getImportPackage().getImportedPackages().size());
+ }
+
+ @Test
+ public void packageImportAndImportedLibraryVersionRangeIntersection() throws UnableToSatisfyDependenciesException, IOException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks);
+ expect(libraryImport.getLibrarySymbolicName()).andReturn("org.springframework").atLeastOnce();
+ expect(libraryImport.getVersion()).andReturn(new VersionRange("[2.5,3.0)")).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest(new StringReader(
+ "Manifest-Version: 1.0\nBundle-SymbolicName: B\nImport-Package: org.springframework.core;version=\"[2.5,2.6)\""));
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport }), Arrays.asList(new ImportedBundle[0]), bundleManifest);
+
+ verifyMocks(mocks);
+
+ assertEquals(34, bundleManifest.getImportPackage().getImportedPackages().size());
+ }
+
+ @Test(expected = UnableToSatisfyDependenciesException.class)
+ public void disjointImportedBundleVersionRangeIntersection() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedBundle bundleImport1 = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(bundleImport1.getBundleSymbolicName()).andReturn("org.springframework.core").atLeastOnce();
+ expect(bundleImport1.getVersion()).andReturn(new VersionRange("[2.5,3.0)")).atLeastOnce();
+ expect(bundleImport1.isApplicationImportScope()).andReturn(false).atLeastOnce();
+ expect(bundleImport1.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportedBundle bundleImport2 = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(bundleImport2.getBundleSymbolicName()).andReturn("org.springframework.core").atLeastOnce();
+ expect(bundleImport2.getVersion()).andReturn(new VersionRange("[2.0,2.5)")).atLeastOnce();
+ expect(bundleImport2.isApplicationImportScope()).andReturn(false).atLeastOnce();
+ expect(bundleImport2.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+
+ try {
+ handler.expandImports(Arrays.asList(new ImportedLibrary[0]), Arrays.asList(new ImportedBundle[] { bundleImport1, bundleImport2 }),
+ bundleManifest);
+ } catch (UnableToSatisfyDependenciesException utsde) {
+ throw utsde;
+ }
+ }
+
+ @Test
+ public void overlappingBundleAndImportedLibrarys() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(bundleImport.getBundleSymbolicName()).andReturn("org.springframework.core").atLeastOnce();
+ expect(bundleImport.getVersion()).andReturn(new VersionRange("[2.5,3.0)")).atLeastOnce();
+ expect(bundleImport.isApplicationImportScope()).andReturn(false).atLeastOnce();
+ expect(bundleImport.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks);
+ expect(libraryImport.getLibrarySymbolicName()).andReturn("org.springframework").atLeastOnce();
+ expect(libraryImport.getVersion()).andReturn(new VersionRange("[2.5,3.0)")).atLeastOnce();
+ expect(libraryImport.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport }), Arrays.asList(new ImportedBundle[] { bundleImport }),
+ bundleManifest);
+ }
+
+ @Test
+ public void importBundleWithNoExports() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(bundleImport.getBundleSymbolicName()).andReturn("silht.bundles.noexports").atLeastOnce();
+ expect(bundleImport.getVersion()).andReturn(new VersionRange("[1.0,1.0]")).atLeastOnce();
+ expect(bundleImport.isApplicationImportScope()).andReturn(false).atLeastOnce();
+ expect(bundleImport.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+ handler.expandImports(Arrays.asList(new ImportedLibrary[0]), Arrays.asList(new ImportedBundle[] { bundleImport }), bundleManifest);
+ }
+
+ @Test
+ public void importBundleWithFragmentWithNoExports() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedBundle hostImportedBundle = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(hostImportedBundle.getBundleSymbolicName()).andReturn("silht.bundles.noexports").atLeastOnce();
+ expect(hostImportedBundle.getVersion()).andReturn(new VersionRange("[1.0,1.0]")).atLeastOnce();
+ expect(hostImportedBundle.isApplicationImportScope()).andReturn(false).atLeastOnce();
+ expect(hostImportedBundle.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportedBundle fragmentImportedBundle = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(fragmentImportedBundle.getBundleSymbolicName()).andReturn("silht.bundles.fragmentwithnoexports").atLeastOnce();
+ expect(fragmentImportedBundle.getVersion()).andReturn(new VersionRange("[1.0,1.0]")).atLeastOnce();
+ expect(fragmentImportedBundle.isApplicationImportScope()).andReturn(false).atLeastOnce();
+ expect(fragmentImportedBundle.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+ handler.expandImports(Arrays.asList(new ImportedLibrary[0]),
+ Arrays.asList(new ImportedBundle[] { hostImportedBundle, fragmentImportedBundle }), bundleManifest);
+ assertTrue(bundleManifest.getImportPackage().getImportedPackages().size() == 0);
+ }
+
+ @Test
+ public void importBundleBetweenManifests() throws Exception {
+ List<BundleManifest> manifests = new ArrayList<BundleManifest>();
+
+ BundleManifest manifest = BundleManifestFactory.createBundleManifest(new StringReader("Manifest-Version: 1.0\nImport-Bundle: com.foo"));
+ manifests.add(manifest);
+ manifests.add(BundleManifestFactory.createBundleManifest(new StringReader(
+ "Manifest-Version: 1.0\nExport-Package: com.foo;version=1.0\nBundle-SymbolicName: com.foo\n")));
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(this.repository, packagesExportedBySystemBundle, new MockEventLogger());
+ handler.expandImports(manifests);
+ assertImported(manifest, Arrays.asList(new String[] { "com.foo" }), Arrays.asList(new String[] { "1.0.0" }));
+ }
+
+ @Test
+ public void importBundleExportingPackagesExportedBySystemBundle() throws Exception {
+ List<BundleManifest> manifests = new ArrayList<BundleManifest>();
+ BundleManifest manifest = BundleManifestFactory.createBundleManifest(new StringReader("Manifest-Version: 1.0\nImport-Bundle: overlapper"));
+ manifests.add(manifest);
+
+ MockEventLogger eventLogger = new MockEventLogger();
+ ImportExpansionHandler handler = new ImportExpansionHandler(this.repository, packagesExportedBySystemBundle, eventLogger);
+ handler.expandImports(manifests);
+ assertImported(manifest, Arrays.asList(new String[] { "javax.crypto.spec", "javax.imageio", "javax.imageio.event", "overlapper.pkg" }),
+ Arrays.asList(new String[] { "0.0.0", "0.0.0", "0.0.0", "0.0.0" }));
+
+ Assert.assertTrue("No events were logged.", eventLogger.getCalled());
+ Assert.assertTrue("The correct event was not logged.", eventLogger.containsLogged("UR0003W"));
+ }
+
+ @Test
+ public void importLibraryThatImportsMissingOptionalBundle() throws Exception {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks);
+
+ expect(libraryImport.getLibrarySymbolicName()).andReturn("missing.optional.bundle").atLeastOnce();
+ expect(libraryImport.getVersion()).andReturn(new VersionRange("[1.0,1.0]")).atLeastOnce();
+ expect(libraryImport.getResolution()).andReturn(Resolution.MANDATORY).anyTimes();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+
+ handler.expandImports(Arrays.asList(new ImportedLibrary[] { libraryImport }), Arrays.asList(new ImportedBundle[0]), bundleManifest);
+
+ verifyMocks(mocks);
+
+ assertEquals(0, bundleManifest.getImportPackage().getImportedPackages().size());
+ }
+
+ @Test
+ public void importBundleThatExportsPackageAtMultipleVersions() throws UnableToSatisfyDependenciesException {
+ List<Object> mocks = new ArrayList<Object>();
+
+ ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks);
+ expect(bundleImport.getBundleSymbolicName()).andReturn("multi.version.export").atLeastOnce();
+ expect(bundleImport.getVersion()).andReturn(new VersionRange("[1.0,2.0)")).atLeastOnce();
+ expect(bundleImport.isApplicationImportScope()).andReturn(false).atLeastOnce();
+ expect(bundleImport.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce();
+
+ ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger());
+
+ replayMocks(mocks);
+
+ BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest();
+
+ handler.expandImports(Arrays.asList(new ImportedLibrary[0]), Arrays.asList(new ImportedBundle[] { bundleImport }), bundleManifest);
+
+ verifyMocks(mocks);
+
+ assertImported(bundleManifest, Arrays.asList(new String[] { "a" }), Arrays.asList(new String[] { "1.0.0" }));
+ }
+
+ private static <T> T createAndStoreMock(Class<T> classToMock, List<Object> mocks) {
+ T mock = createMock(classToMock);
+ mocks.add(mock);
+ return mock;
+ }
+
+ private static void replayMocks(List<Object> mocks) {
+ Object[] mocksArray = mocks.toArray(new Object[mocks.size()]);
+ replay(mocksArray);
+ }
+
+ private static void verifyMocks(List<Object> mocks) {
+ Object[] mocksArray = mocks.toArray(new Object[mocks.size()]);
+ verify(mocksArray);
+ }
+
+ private static void assertImported(BundleManifest bundleManifest, List<String> packages, List<String> versions) {
+ List<ImportedPackage> packageImports = bundleManifest.getImportPackage().getImportedPackages();
+ List<String> expectedPackages = new ArrayList<String>(packages);
+ List<String> expectedVersions = new ArrayList<String>(versions);
+ for (ImportedPackage packageImport : packageImports) {
+
+ String packageName = packageImport.getPackageName();
+ int index = expectedPackages.indexOf(packageName);
+ if (index > -1) {
+ Version expected = new Version(expectedVersions.get(index));
+ VersionRange actualRange = new VersionRange(packageImport.getAttributes().get("version"));
+
+ if (actualRange.includes(expected)) {
+ expectedPackages.remove(packageName);
+ expectedVersions.remove(index);
+ }
+ }
+ }
+
+ if (expectedPackages.size() > 0) {
+ fail("No import(s) were found for package(s) " + expectedPackages + " with version(s) " + expectedVersions + " in manifest: \n"
+ + bundleManifest);
+ }
+ }
+
+ private static final class StubRepository implements Repository {
+
+ private final List<RepositoryAwareArtifactDescriptor> artifactDescriptors = new ArrayList<RepositoryAwareArtifactDescriptor>();
+
+ /**
+ * {@inheritDoc}
+ */
+ public Query createQuery(String key, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Query createQuery(String key, String value, Map<String, Set<String>> properties) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public RepositoryAwareArtifactDescriptor get(String type, String name, VersionRange versionRange) {
+ RepositoryAwareArtifactDescriptor bestMatch = null;
+
+ for (RepositoryAwareArtifactDescriptor candidate : this.artifactDescriptors) {
+ if (type.equals(candidate.getType()) && name.equals(candidate.getName()) && versionRange.includes(candidate.getVersion())) {
+ if (bestMatch == null || bestMatch.getVersion().compareTo(candidate.getVersion()) < 0) {
+ bestMatch = candidate;
+ }
+ }
+ }
+ return bestMatch;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop() {
+ throw new UnsupportedOperationException();
+ }
+
+ private void addArtifactDescriptor(ArtifactDescriptor descriptor) {
+ this.artifactDescriptors.add(new StubRepositoryAwareArtifactDescriptor(descriptor));
+ }
+
+ private static final class StubRepositoryAwareArtifactDescriptor implements RepositoryAwareArtifactDescriptor {
+
+ private final ArtifactDescriptor delegate;
+
+ /**
+ * @param delegate
+ */
+ private StubRepositoryAwareArtifactDescriptor(ArtifactDescriptor delegate) {
+ this.delegate = delegate;
+ }
+
+ public Set<Attribute> getAttribute(String name) {
+ return delegate.getAttribute(name);
+ }
+
+ public Set<Attribute> getAttributes() {
+ return delegate.getAttributes();
+ }
+
+ public String getFilename() {
+ return delegate.getFilename();
+ }
+
+ public String getName() {
+ return delegate.getName();
+ }
+
+ public String getType() {
+ return delegate.getType();
+ }
+
+ public java.net.URI getUri() {
+ return delegate.getUri();
+ }
+
+ public Version getVersion() {
+ return delegate.getVersion();
+ }
+
+ public String getRepositoryName() {
+ return "Unit test repository";
+ }
+ }
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/importexpansion/TrackedPackageImportsTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/importexpansion/TrackedPackageImportsTests.java
new file mode 100644
index 00000000..ec4e7d4c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/importexpansion/TrackedPackageImportsTests.java
@@ -0,0 +1,405 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.importexpansion;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.eclipse.virgo.kernel.osgi.framework.ImportMergeException;
+import org.eclipse.virgo.kernel.userregion.internal.importexpansion.StandardTrackedPackageImportsFactory;
+import org.eclipse.virgo.kernel.userregion.internal.importexpansion.TrackedPackageImports;
+import org.eclipse.virgo.kernel.userregion.internal.importexpansion.TrackedPackageImportsFactory;
+import org.eclipse.virgo.util.osgi.VersionRange;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifest;
+import org.eclipse.virgo.util.osgi.manifest.BundleManifestFactory;
+import org.eclipse.virgo.util.osgi.manifest.ImportedPackage;
+import org.eclipse.virgo.util.osgi.manifest.Resolution;
+
+/**
+ */
+public class TrackedPackageImportsTests {
+
+ private static final String TEST_SOURCE = "test source";
+
+ private final TrackedPackageImportsFactory trackedPackageImportsFactory = new StandardTrackedPackageImportsFactory();
+
+ @Test public void testTrivialMerge() throws ImportMergeException, IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader("bundle-symbolicname: A\nimport-package: p"));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader("bundle-symbolicname: B\nimport-package: p"));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ TrackedPackageImports empty = this.trackedPackageImportsFactory.createEmpty();
+
+ Assert.assertTrue(empty.isEmpty());
+ Assert.assertFalse(tpiB.isEmpty());
+ Assert.assertTrue(tpiA.isEquivalent(tpiB));
+ Assert.assertFalse(tpiA.isEquivalent(empty));
+
+ tpiB.merge(tpiA);
+ tpiB.merge(empty);
+ Map<String, ImportedPackage> mergedImports = convertImportedPackageListToMap(tpiB.getMergedImports());
+ ImportedPackage pImport = mergedImports.get("p");
+ Assert.assertNotNull("Missing merged import", pImport);
+ }
+
+ @Test public void testOverlappingVersionRanges() throws ImportMergeException, IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;version=\"[1,3]\""));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;version=\"2\""));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ tpiB.merge(tpiA);
+ Map<String, ImportedPackage> mergedImports = convertImportedPackageListToMap(tpiB.getMergedImports());
+ ImportedPackage pImport = mergedImports.get("p");
+ Assert.assertNotNull("Missing merged import", pImport);
+ VersionRange v = new VersionRange(pImport.getAttributes().get("version"));
+ Assert.assertTrue("Incorrectly merged version", v.isFloorInclusive() && v.isCeilingInclusive() && v.getFloor().getMajor() == 2
+ && v.getCeiling().getMajor() == 3);
+ }
+
+ @Test public void testDisjointVersionRanges() throws IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;version=\"[1,2]\""));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;version=\"[3,4]\""));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ try {
+ tpiB.merge(tpiA);
+ Assert.assertTrue("Exception should be thrown", false);
+ } catch (ImportMergeException e) {
+ System.out.println(e);
+ Assert.assertEquals("Incorrect conflicting package name", "p", e.getConflictingPackageName());
+ Assert.assertEquals("Incorrect sources", "bundle B, bundle A", e.getSources());
+ }
+ }
+
+ @Test public void testOverlappingBundleVersionRanges() throws ImportMergeException, IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;bundle-version=\"[1,3]\""));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;bundle-version=\"2\""));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ tpiB.merge(tpiA);
+ Map<String, ImportedPackage> mergedImports = convertImportedPackageListToMap(tpiB.getMergedImports());
+ ImportedPackage pImport = mergedImports.get("p");
+ Assert.assertNotNull("Missing merged import", pImport);
+ VersionRange v = new VersionRange(pImport.getAttributes().get("bundle-version"));
+ Assert.assertTrue("Incorrectly merged version", v.isFloorInclusive() && v.isCeilingInclusive() && v.getFloor().getMajor() == 2
+ && v.getCeiling().getMajor() == 3);
+ }
+
+ @Test public void testDisjointBundleVersionRanges() throws IOException {
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;bundle-version=\"[1,2]\""));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;bundle-version=\"[3,4]\""));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ try {
+ tpiB.merge(tpiA);
+ Assert.assertTrue("Exception should be thrown", false);
+ } catch (ImportMergeException e) {
+ System.out.println(e);
+ Assert.assertEquals("Incorrect conflicting package name", "p", e.getConflictingPackageName());
+ Assert.assertEquals("Incorrect sources", "bundle B, bundle A", e.getSources());
+ }
+ }
+
+ @Test public void testResolution() throws ImportMergeException, IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;resolution:=optional"));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;resolution:=mandatory"));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ tpiB.merge(tpiA);
+ Map<String, ImportedPackage> mergedImports = convertImportedPackageListToMap(tpiB.getMergedImports());
+ ImportedPackage pImport = mergedImports.get("p");
+ Assert.assertNotNull("Missing merged import", pImport);
+ Assert.assertTrue("Incorrectly merged resolution", pImport.getResolution() == Resolution.MANDATORY);
+ }
+
+ @Test public void testConsistentAttributes() throws ImportMergeException, IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;a1=v1;a2=v2"));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;a1=v1;a3=v3"));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ tpiB.merge(tpiA);
+ Map<String, ImportedPackage> mergedImports = convertImportedPackageListToMap(tpiB.getMergedImports());
+ ImportedPackage pImport = mergedImports.get("p");
+ Assert.assertNotNull("Missing merged import", pImport);
+ Map<String, String> pAttrs = pImport.getAttributes();
+ Assert.assertEquals("Incorrectly merged attribute for a1", "v1", pAttrs.get("a1"));
+ Assert.assertEquals("Incorrectly merged attribute for a2", "v2", pAttrs.get("a2"));
+ Assert.assertEquals("Incorrectly merged attribute for a3", "v3", pAttrs.get("a3"));
+ }
+
+ @Test public void testInconsistentAttributes() throws ImportMergeException, IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader("bundle-symbolicname: A\nimport-package: p;a1=v1"));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader("bundle-symbolicname: B\nimport-package: p;a1=v2"));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ BundleManifest manifestC = BundleManifestFactory.createBundleManifest(new StringReader("bundle-symbolicname: C\nimport-package: q"));
+ TrackedPackageImports tpiC = this.trackedPackageImportsFactory.create(manifestC);
+ tpiB.merge(tpiC);
+
+ try {
+ tpiB.merge(tpiA);
+ Assert.assertTrue("Exception should be thrown", false);
+ } catch (ImportMergeException e) {
+ System.out.println(e);
+ Assert.assertEquals("Incorrect conflicting package name", "p", e.getConflictingPackageName());
+ Assert.assertEquals("Incorrect sources", "bundle B, bundle A", e.getSources());
+ }
+ }
+
+ @Test public void testTrivialAddition() throws ImportMergeException, IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader("bundle-symbolicname: A\nimport-package: p"));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ ImportedPackage packageImport = BundleManifestFactory.createBundleManifest().getImportPackage().addImportedPackage("p");
+ List<ImportedPackage> packageImports = new ArrayList<ImportedPackage>();
+ packageImports.add(packageImport);
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(packageImports, TEST_SOURCE);
+
+ tpiA.merge(tpiB);
+ Map<String, ImportedPackage> mergedImports = convertImportedPackageListToMap(tpiA.getMergedImports());
+ ImportedPackage pImport = mergedImports.get("p");
+ Assert.assertNotNull("Missing merged import", pImport);
+ }
+
+ @Test public void testClashingAddition() throws IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;attr=x"));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ ImportedPackage packageImport = BundleManifestFactory.createBundleManifest().getImportPackage().addImportedPackage("p");
+ packageImport.getAttributes().put("attr", "y");
+ List<ImportedPackage> packageImports = new ArrayList<ImportedPackage>();
+ packageImports.add(packageImport);
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(packageImports, TEST_SOURCE);
+
+ try {
+ tpiA.merge(tpiB);
+ Assert.assertTrue("Exception should be thrown", false);
+ } catch (ImportMergeException e) {
+ System.out.println(e);
+ Assert.assertEquals("Incorrect conflicting package name", "p", e.getConflictingPackageName());
+ Assert.assertEquals("Incorrect sources", "bundle A, " + TEST_SOURCE, e.getSources());
+ }
+ }
+
+ @Test public void testOverlappingVersionRangesInCollection() throws ImportMergeException, IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;version=\"[1,3]\""));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;version=\"2\""));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ TrackedPackageImports tpiC = this.trackedPackageImportsFactory.createCollector();
+
+ tpiC.merge(tpiB);
+ tpiC.merge(tpiA);
+
+ Map<String, ImportedPackage> mergedImports = convertImportedPackageListToMap(tpiC.getMergedImports());
+ ImportedPackage pImport = mergedImports.get("p");
+ Assert.assertNotNull("Missing merged import", pImport);
+ VersionRange v = new VersionRange(pImport.getAttributes().get("version"));
+ Assert.assertTrue("Incorrectly merged version", v.isFloorInclusive() && v.isCeilingInclusive() && v.getFloor().getMajor() == 2
+ && v.getCeiling().getMajor() == 3);
+ }
+
+ @Test public void testDisjointVersionRangesInCollection() throws IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;version=\"[1,2]\""));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;version=\"[3,4]\""));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ TrackedPackageImports tpiC = this.trackedPackageImportsFactory.createCollector();
+
+ try {
+ tpiC.merge(tpiB);
+ tpiC.merge(tpiA);
+ Assert.assertTrue("Exception should be thrown", false);
+ } catch (ImportMergeException e) {
+ System.out.println(e);
+ Assert.assertEquals("Incorrect conflicting package name", "p", e.getConflictingPackageName());
+ Assert.assertEquals("Incorrect sources", "bundle B, bundle A", e.getSources());
+ }
+ }
+
+ @Test public void testThreeWayClash() throws IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;version=\"[1,2]\""));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;version=\"[2,3]\""));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ TrackedPackageImports tpiC = this.trackedPackageImportsFactory.createCollector();
+
+ BundleManifest manifestD = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: D\nimport-package: p;version=\"[3,3]\""));
+ TrackedPackageImports tpiD = this.trackedPackageImportsFactory.create(manifestD);
+
+ try {
+ tpiC.merge(tpiB);
+ tpiC.merge(tpiA);
+ tpiD.merge(tpiC);
+ Assert.assertTrue("Exception should be thrown", false);
+ } catch (ImportMergeException e) {
+ System.out.println(e);
+ Assert.assertEquals("Incorrect conflicting package name", "p", e.getConflictingPackageName());
+ /*
+ * Note that in a N-way clash of version ranges, there must be a pair of version ranges that clash, but the
+ * current implementation simply reports all N.
+ */
+ Assert.assertEquals("Incorrect sources", "bundle D, bundle B, bundle A", e.getSources());
+ }
+ }
+
+ @Test public void testThreeWayNestedClash() throws IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;version=\"[1,2]\""));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;version=\"[2,3]\""));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ BundleManifest manifestD = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: D\nimport-package: p;version=\"[3,3]\""));
+ TrackedPackageImports tpiD = this.trackedPackageImportsFactory.create(manifestD);
+
+ TrackedPackageImports tpiContainer = this.trackedPackageImportsFactory.createContainer("container");
+
+ try {
+ tpiContainer.merge(tpiA);
+ tpiContainer.merge(tpiB);
+ tpiD.merge(tpiContainer);
+ Assert.assertTrue("Exception should be thrown", false);
+ } catch (ImportMergeException e) {
+ System.out.println(e);
+ Assert.assertEquals("Incorrect conflicting package name", "p", e.getConflictingPackageName());
+ /*
+ * Note that in a N-way clash of version ranges, there must be a pair of version ranges that clash, but the
+ * current implementation simply reports all N.
+ */
+ Assert.assertEquals("Incorrect sources", "bundle D, container(bundle A, bundle B)", e.getSources());
+ }
+ }
+
+ @Test public void testFourWayNestedClashInACollector() throws IOException {
+
+ BundleManifest manifestA = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: A\nimport-package: p;version=\"[1,2]\""));
+ TrackedPackageImports tpiA = this.trackedPackageImportsFactory.create(manifestA);
+
+ BundleManifest manifestB = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: B\nimport-package: p;version=\"[2,3]\""));
+ TrackedPackageImports tpiB = this.trackedPackageImportsFactory.create(manifestB);
+
+ BundleManifest manifestC = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: C\nimport-package: p;version=\"[3,4]\""));
+ TrackedPackageImports tpiC = this.trackedPackageImportsFactory.create(manifestC);
+
+ BundleManifest manifestD = BundleManifestFactory.createBundleManifest(new StringReader(
+ "bundle-symbolicname: D\nimport-package: p;version=\"[4,5]\""));
+ TrackedPackageImports tpiD = this.trackedPackageImportsFactory.create(manifestD);
+
+ TrackedPackageImports tpiContainerX = this.trackedPackageImportsFactory.createContainer("containerX");
+
+ TrackedPackageImports tpiContainerY = this.trackedPackageImportsFactory.createContainer("containerY");
+
+ TrackedPackageImports tpiCollector = this.trackedPackageImportsFactory.createCollector();
+
+ try {
+ tpiContainerX.merge(tpiA);
+ tpiContainerX.merge(tpiB);
+ tpiContainerY.merge(tpiC);
+ tpiContainerY.merge(tpiD);
+ tpiCollector.merge(tpiContainerX);
+ tpiCollector.merge(tpiContainerY);
+ Assert.assertTrue("Exception should be thrown", false);
+ } catch (ImportMergeException e) {
+ System.out.println(e);
+ Assert.assertEquals("Incorrect conflicting package name", "p", e.getConflictingPackageName());
+ /*
+ * Note that in a N-way clash of version ranges, there must be a pair of version ranges that clash, but the
+ * current implementation simply reports all N.
+ */
+ Assert.assertEquals("Incorrect sources", "containerX(bundle A, bundle B), containerY(bundle C, bundle D)", e.getSources());
+ }
+ }
+
+ /**
+ * Convert a given list of package imports with no duplicate package names to a map of package name to
+ * {@link ImportedPackage}.
+ *
+ * @param importedPackages a list of <code>PackageImport</code>
+ * @return a map of package name to <code>PackageImport</code>
+ */
+ private static Map<String, ImportedPackage> convertImportedPackageListToMap(List<ImportedPackage> importedPackages) {
+ Map<String, ImportedPackage> initialPackageImports = new HashMap<String, ImportedPackage>();
+ for (ImportedPackage importedPackage : importedPackages) {
+ Assert.assertNull(initialPackageImports.put(importedPackage.getPackageName(), importedPackage));
+ }
+ return initialPackageImports;
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/BundleDescriptionComparatorTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/BundleDescriptionComparatorTests.java
new file mode 100644
index 00000000..ea5f1da6
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/BundleDescriptionComparatorTests.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.BundleSpecification;
+import org.eclipse.osgi.service.resolver.ExportPackageDescription;
+import org.eclipse.osgi.service.resolver.GenericDescription;
+import org.eclipse.osgi.service.resolver.GenericSpecification;
+import org.eclipse.osgi.service.resolver.HostSpecification;
+import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
+import org.eclipse.osgi.service.resolver.NativeCodeSpecification;
+import org.eclipse.osgi.service.resolver.State;
+import org.eclipse.virgo.kernel.userregion.internal.quasi.BundleDescriptionComparator;
+import org.junit.Test;
+import org.osgi.framework.Version;
+
+
+public class BundleDescriptionComparatorTests {
+
+ private final BundleDescriptionComparator bundleDescriptionComparator = new BundleDescriptionComparator();
+
+ @Test
+ public void matchingBundleSymbolicNameAndVersion() {
+ StubBundleDescription bd1 = new StubBundleDescription("foo", new Version(1,2,3));
+ StubBundleDescription bd2 = new StubBundleDescription("foo", new Version(1,2,3));
+ assertEquals(0, bundleDescriptionComparator.compare(bd1, bd2));
+ }
+
+ @Test
+ public void differingBundleSymbolicName() {
+ StubBundleDescription bd1 = new StubBundleDescription("foo", new Version(1,2,3));
+ StubBundleDescription bd2 = new StubBundleDescription("bar", new Version(1,2,3));
+
+ assertDifferent(bd1, bd2);
+ }
+
+ @Test
+ public void differingVersion() {
+ StubBundleDescription bd1 = new StubBundleDescription("foo", new Version(1,2,3));
+ StubBundleDescription bd2 = new StubBundleDescription("foo", new Version(2,3,4));
+
+ assertDifferent(bd1, bd2);
+ }
+
+ @Test
+ public void differingBundleSymbolicNameAndVersion() {
+ StubBundleDescription bd1 = new StubBundleDescription("foo", new Version(1,2,3));
+ StubBundleDescription bd2 = new StubBundleDescription("bar", new Version(2,3,4));
+
+ assertDifferent(bd1, bd2);
+ }
+
+ private void assertDifferent(StubBundleDescription bd1, StubBundleDescription bd2) {
+ int bd1ToBd2Comparison = this.bundleDescriptionComparator.compare(bd1, bd2);
+ assertTrue(bd1ToBd2Comparison != 0);
+
+ int bd2ToBd1Comparison = this.bundleDescriptionComparator.compare(bd2, bd1);
+ assertTrue(bd2ToBd1Comparison != 0);
+
+ assertFalse(bd2ToBd1Comparison < 0 && bd1ToBd2Comparison < 0);
+ }
+
+ private static final class StubBundleDescription implements BundleDescription {
+
+ private final String symbolicName;
+
+ private final Version version;
+
+ StubBundleDescription(String symbolicName, Version version) {
+ this.symbolicName = symbolicName;
+ this.version = version;
+ }
+
+ public boolean attachFragments() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean dynamicFragments() {
+ throw new UnsupportedOperationException();
+ }
+
+ public long getBundleId() {
+ throw new UnsupportedOperationException();
+ }
+
+ public State getContainingState() {
+ throw new UnsupportedOperationException();
+ }
+
+ public BundleDescription[] getDependents() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String[] getExecutionEnvironments() {
+ throw new UnsupportedOperationException();
+ }
+
+ public ExportPackageDescription[] getExportPackages() {
+ throw new UnsupportedOperationException();
+ }
+
+ public BundleDescription[] getFragments() {
+ throw new UnsupportedOperationException();
+ }
+
+ public GenericDescription[] getGenericCapabilities() {
+ throw new UnsupportedOperationException();
+ }
+
+ public GenericSpecification[] getGenericRequires() {
+ throw new UnsupportedOperationException();
+ }
+
+ public HostSpecification getHost() {
+ throw new UnsupportedOperationException();
+ }
+
+ public ImportPackageSpecification[] getImportPackages() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getLocation() {
+ throw new UnsupportedOperationException();
+ }
+
+ public NativeCodeSpecification getNativeCodeSpecification() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getPlatformFilter() {
+ throw new UnsupportedOperationException();
+ }
+
+ public BundleSpecification[] getRequiredBundles() {
+ throw new UnsupportedOperationException();
+ }
+
+ public ExportPackageDescription[] getResolvedImports() {
+ throw new UnsupportedOperationException();
+ }
+
+ public BundleDescription[] getResolvedRequires() {
+ throw new UnsupportedOperationException();
+ }
+
+ public ExportPackageDescription[] getSelectedExports() {
+ throw new UnsupportedOperationException();
+ }
+
+ public ExportPackageDescription[] getSubstitutedExports() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getSymbolicName() {
+ return this.symbolicName;
+ }
+
+ public Object getUserObject() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasDynamicImports() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isRemovalPending() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isResolved() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isSingleton() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setUserObject(Object userObject) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getName() {
+ throw new UnsupportedOperationException();
+ }
+
+ public BundleDescription getSupplier() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Version getVersion() {
+ return this.version;
+ }
+ }
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiBundleTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiBundleTests.java
new file mode 100644
index 00000000..cd61e36e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiBundleTests.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Version;
+
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiBundle;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiExportPackage;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiImportPackage;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiRequiredBundle;
+import org.eclipse.virgo.kernel.userregion.internal.quasi.StandardQuasiBundle;
+
+/**
+ */
+public class StandardQuasiBundleTests {
+
+ private static final String BSN = "bsn";
+
+ private static final Version BV = new Version("4.3.2.ga");
+
+ private static final long BID = 2341341;
+
+ private StubBundleDescription bundleDescription;
+
+ @Before
+ public void setUp() {
+ bundleDescription = new StubBundleDescription();
+ }
+
+ @Test
+ public void testSymbolicName() {
+ bundleDescription.setBundleSymbolicName(BSN);
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ Assert.assertEquals(BSN, qb.getSymbolicName());
+ }
+
+ @Test
+ public void testVersion() {
+ bundleDescription.setVersion(BV);
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ Assert.assertEquals(BV, qb.getVersion());
+ }
+
+ @Test
+ public void testIsResolved() {
+ bundleDescription.setResolved(true);
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ Assert.assertEquals(true, qb.isResolved());
+ }
+
+ @Test
+ public void testBundleId() {
+ bundleDescription.setBundleId(BID);
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ Assert.assertEquals(BID, qb.getBundleId());
+ }
+
+ @Test
+ public void testFragments() {
+ bundleDescription.addFragment(new StubBundleDescription("f1"));
+ bundleDescription.addFragment(new StubBundleDescription("f2"));
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ List<QuasiBundle> fragments = qb.getFragments();
+ Assert.assertEquals(2, fragments.size());
+ Assert.assertEquals("f1", fragments.get(0).getSymbolicName());
+ Assert.assertEquals("f2", fragments.get(1).getSymbolicName());
+ }
+
+ @Test
+ public void testNoFragments() {
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ List<QuasiBundle> fragments = qb.getFragments();
+ Assert.assertEquals(0, fragments.size());
+ }
+
+ @Test
+ public void testHosts() {
+ bundleDescription.addHost(new StubBundleDescription("h1"));
+ bundleDescription.addHost(new StubBundleDescription("h2"));
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ List<QuasiBundle> hosts = qb.getHosts();
+ Assert.assertEquals(2, hosts.size());
+ Assert.assertEquals("h1", hosts.get(0).getSymbolicName());
+ Assert.assertEquals("h2", hosts.get(1).getSymbolicName());
+ }
+
+ @Test
+ public void testNoHosts() {
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ List<QuasiBundle> hosts = qb.getHosts();
+ Assert.assertNull(hosts);
+ }
+
+ @Test
+ public void testExportPackages() {
+ bundleDescription.addExportPackage(new StubExportPackageDescription("e1"));
+ bundleDescription.addExportPackage(new StubExportPackageDescription("e2"));
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ List<QuasiExportPackage> exportPackages = qb.getExportPackages();
+ Assert.assertEquals(2, exportPackages.size());
+ Assert.assertEquals("e1", exportPackages.get(0).getPackageName());
+ Assert.assertEquals("e2", exportPackages.get(1).getPackageName());
+ }
+
+ @Test
+ public void testImportPackages() {
+ bundleDescription.addImportPackage(new StubImportPackageSpecification("i1"));
+ bundleDescription.addImportPackage(new StubImportPackageSpecification("i2"));
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ List<QuasiImportPackage> importPackages = qb.getImportPackages();
+ Assert.assertEquals(2, importPackages.size());
+ Assert.assertEquals("i1", importPackages.get(0).getPackageName());
+ Assert.assertEquals("i2", importPackages.get(1).getPackageName());
+ }
+
+ @Test
+ public void testRequiredBundles() {
+ bundleDescription.addRequiredBundle(new StubBundleSpecification("b1"));
+ bundleDescription.addRequiredBundle(new StubBundleSpecification("b2"));
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ List<QuasiRequiredBundle> requiredBundles = qb.getRequiredBundles();
+ Assert.assertEquals(2, requiredBundles.size());
+ Assert.assertEquals("b1", requiredBundles.get(0).getRequiredBundleName());
+ Assert.assertEquals("b2", requiredBundles.get(1).getRequiredBundleName());
+ }
+
+ @Test
+ public void testDependents() {
+ bundleDescription.addDependent(new StubBundleDescription("b1"));
+ bundleDescription.addDependent(new StubBundleDescription("b2"));
+ QuasiBundle qb = new StandardQuasiBundle(bundleDescription, null, null);
+ List<QuasiBundle> requiredBundles = qb.getDependents();
+ Assert.assertEquals(2, requiredBundles.size());
+ Assert.assertEquals("b1", requiredBundles.get(0).getSymbolicName());
+ Assert.assertEquals("b2", requiredBundles.get(1).getSymbolicName());
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiExportPackageTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiExportPackageTests.java
new file mode 100644
index 00000000..1fb2e508
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiExportPackageTests.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import java.util.List;
+
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.Version;
+
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiBundle;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiExportPackage;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiImportPackage;
+import org.eclipse.virgo.kernel.userregion.internal.quasi.StandardQuasiBundle;
+import org.eclipse.virgo.kernel.userregion.internal.quasi.StandardQuasiExportPackage;
+
+/**
+ */
+public class StandardQuasiExportPackageTests {
+
+ private static final String BSN = "bsn";
+
+ private static final String PN = "p";
+
+ private static final Version VERSION = new Version("5.4.3");
+
+ private StubBundleDescription bundleDescription;
+
+ private StubExportPackageDescription exportPackage;
+
+ private QuasiBundle qb;
+
+ private StubStateHelper stateHelper;
+
+ @Before
+ public void setUp() {
+ this.bundleDescription = new StubBundleDescription();
+ this.bundleDescription.setBundleSymbolicName(BSN);
+ this.stateHelper = new StubStateHelper();
+ this.qb = new StandardQuasiBundle(this.bundleDescription, null, this.stateHelper);
+ this.exportPackage = new StubExportPackageDescription(PN);
+ }
+
+ @Test
+ public void testPackageName() {
+ QuasiExportPackage qep = new StandardQuasiExportPackage(this.exportPackage, this.qb);
+ Assert.assertEquals(PN, qep.getPackageName());
+ }
+
+ @Test
+ public void testVersion() {
+ this.exportPackage.setVersion(VERSION);
+ QuasiExportPackage qep = new StandardQuasiExportPackage(this.exportPackage, this.qb);
+ Assert.assertEquals(PN, qep.getPackageName());
+ }
+
+ @Test
+ public void testExportingBundle() {
+ QuasiExportPackage qep = new StandardQuasiExportPackage(this.exportPackage, this.qb);
+ Assert.assertEquals(BSN, qep.getExportingBundle().getSymbolicName());
+ }
+
+ @Test
+ public void testConsumers() {
+ StubBundleDescription dependentBundle = new StubBundleDescription();
+ StubImportPackageSpecification ips = new StubImportPackageSpecification(PN);
+ dependentBundle.addImportPackage(ips);
+ ips.setSupplier(this.exportPackage);
+ this.stateHelper.setDependentBundles(new BundleDescription[] { dependentBundle });
+ this.exportPackage.setExporter(this.bundleDescription);
+ QuasiExportPackage qep = new StandardQuasiExportPackage(this.exportPackage, this.qb);
+ List<QuasiImportPackage> consumers = qep.getConsumers();
+ Assert.assertEquals(1, consumers.size());
+ Assert.assertEquals(PN, consumers.get(0).getPackageName());
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiImportPackageTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiImportPackageTests.java
new file mode 100644
index 00000000..eac79807
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiImportPackageTests.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiBundle;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiImportPackage;
+import org.eclipse.virgo.kernel.userregion.internal.quasi.StandardQuasiBundle;
+import org.eclipse.virgo.kernel.userregion.internal.quasi.StandardQuasiImportPackage;
+import org.eclipse.virgo.util.osgi.VersionRange;
+
+/**
+ */
+public class StandardQuasiImportPackageTests {
+
+ private static final String STRING_VERSION_RANGE = "[2,4)";
+
+ private static final org.eclipse.osgi.service.resolver.VersionRange RESOLVER_VERSION_RANGE = new org.eclipse.osgi.service.resolver.VersionRange(
+ STRING_VERSION_RANGE);
+
+ private static final VersionRange VERSION_RANGE = new VersionRange(STRING_VERSION_RANGE);
+
+ private static final String BSN = "bsn";
+
+ private static final String PROVIDER_BSN = "provider-bsn";
+
+ private static final String CONSUMER_BSN = "consumer-bsn";
+
+ private static final String PN = "p";
+
+ private StubBundleDescription bundleDescription;
+
+ private StubImportPackageSpecification importPackage;
+
+ private QuasiBundle qb;
+
+ private StubStateHelper stateHelper;
+
+ private StubExportPackageDescription exportPackage;
+
+ @Before
+ public void setUp() {
+ this.bundleDescription = new StubBundleDescription();
+ this.bundleDescription.setBundleSymbolicName(BSN);
+ this.stateHelper = new StubStateHelper();
+ this.qb = new StandardQuasiBundle(this.bundleDescription, null, this.stateHelper);
+ this.importPackage = new StubImportPackageSpecification(PN);
+ this.exportPackage = new StubExportPackageDescription(PN);
+ }
+
+ @Test
+ public void testPackageName() {
+ QuasiImportPackage qip = new StandardQuasiImportPackage(this.importPackage, this.qb);
+ Assert.assertEquals(PN, qip.getPackageName());
+ }
+
+ @Test
+ public void testVersionConstraint() {
+ org.eclipse.osgi.service.resolver.VersionRange versionRange = RESOLVER_VERSION_RANGE;
+ this.importPackage.setVersionRange(versionRange);
+ QuasiImportPackage qip = new StandardQuasiImportPackage(this.importPackage, qb);
+ Assert.assertEquals(VERSION_RANGE, qip.getVersionConstraint());
+ }
+
+ @Test
+ public void testResolved() {
+ this.importPackage.setResolved(true);
+ QuasiImportPackage qip = new StandardQuasiImportPackage(this.importPackage, this.qb);
+ Assert.assertTrue(qip.isResolved());
+ }
+
+ @Test
+ public void testNotResolved() {
+ QuasiImportPackage qip = new StandardQuasiImportPackage(this.importPackage, this.qb);
+ Assert.assertFalse(qip.isResolved());
+ }
+
+ @Test
+ public void testResolvedProvider() {
+ StubBaseDescription supplier = new StubBaseDescription();
+ StubBundleDescription bundleSupplier = new StubBundleDescription();
+ bundleSupplier.setBundleSymbolicName(PROVIDER_BSN);
+ supplier.setSupplier(bundleSupplier);
+ this.importPackage.setSupplier(supplier);
+ this.importPackage.setResolved(true);
+ StubBundleDescription bundleConsumer = new StubBundleDescription();
+ bundleConsumer.setBundleSymbolicName(CONSUMER_BSN);
+ this.importPackage.setBundle(bundleConsumer);
+ this.importPackage.setSupplier(this.exportPackage);
+ QuasiImportPackage qip = new StandardQuasiImportPackage(this.importPackage, qb);
+ this.exportPackage.setExporter(bundleSupplier);
+ Assert.assertEquals(PN, qip.getProvider().getPackageName());
+ }
+
+ @Test
+ public void testUnresolvedProvider() {
+ QuasiImportPackage qip = new StandardQuasiImportPackage(this.importPackage, qb);
+ Assert.assertNull(qip.getProvider());
+ }
+
+ @Test
+ public void testImportingBundle() {
+ QuasiImportPackage qip = new StandardQuasiImportPackage(this.importPackage, qb);
+ Assert.assertEquals(qb, qip.getImportingBundle());
+ }
+
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiRequiredBundleTests.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiRequiredBundleTests.java
new file mode 100644
index 00000000..1d8b7bfb
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StandardQuasiRequiredBundleTests.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiBundle;
+import org.eclipse.virgo.kernel.osgi.quasi.QuasiRequiredBundle;
+import org.eclipse.virgo.kernel.userregion.internal.quasi.StandardQuasiBundle;
+import org.eclipse.virgo.kernel.userregion.internal.quasi.StandardQuasiRequiredBundle;
+import org.eclipse.virgo.util.osgi.VersionRange;
+
+/**
+ */
+public class StandardQuasiRequiredBundleTests {
+
+ private static final String STRING_VERSION_RANGE = "[2,4)";
+
+ private static final org.eclipse.osgi.service.resolver.VersionRange RESOLVER_VERSION_RANGE = new org.eclipse.osgi.service.resolver.VersionRange(
+ STRING_VERSION_RANGE);
+
+ private static final VersionRange VERSION_RANGE = new VersionRange(STRING_VERSION_RANGE);
+
+ private static final String BSN = "bsn";
+
+ private static final String REQUIRED_BSN = "required-bsn";
+
+ private StubBundleDescription bundleDescription;
+
+ private QuasiBundle qb;
+
+ private StubStateHelper stateHelper;
+
+ private StubBundleSpecification bundleSpecification;
+
+ @Before
+ public void setUp() {
+ this.bundleDescription = new StubBundleDescription();
+ this.bundleDescription.setBundleSymbolicName(BSN);
+ this.bundleSpecification = new StubBundleSpecification(REQUIRED_BSN);
+ this.stateHelper = new StubStateHelper();
+ this.qb = new StandardQuasiBundle(this.bundleDescription, null, this.stateHelper);
+ }
+
+ @Test
+ public void testRequiredBundleName() {
+ QuasiRequiredBundle qrb = new StandardQuasiRequiredBundle(this.bundleSpecification, this.qb);
+ Assert.assertEquals(REQUIRED_BSN, qrb.getRequiredBundleName());
+ }
+
+ @Test
+ public void testVersionConstraint() {
+ this.bundleSpecification.setVersionRange(RESOLVER_VERSION_RANGE);
+ QuasiRequiredBundle qrb = new StandardQuasiRequiredBundle(this.bundleSpecification, this.qb);
+ Assert.assertEquals(VERSION_RANGE, qrb.getVersionConstraint());
+ }
+
+ @Test
+ public void testResolved() {
+ this.bundleSpecification.setResolved(true);
+ QuasiRequiredBundle qrb = new StandardQuasiRequiredBundle(this.bundleSpecification, this.qb);
+ Assert.assertTrue(qrb.isResolved());
+ }
+
+ @Test
+ public void testUnresolved() {
+ QuasiRequiredBundle qrb = new StandardQuasiRequiredBundle(this.bundleSpecification, this.qb);
+ Assert.assertFalse(qrb.isResolved());
+ }
+
+ @Test
+ public void testUnresolvedProvider() {
+ QuasiRequiredBundle qrb = new StandardQuasiRequiredBundle(this.bundleSpecification, this.qb);
+ Assert.assertNull(qrb.getProvider());
+ }
+
+ @Test
+ public void testResolvedProvider() {
+ StubBundleDescription requiredBundleDescription = new StubBundleDescription();
+ requiredBundleDescription.setBundleSymbolicName(REQUIRED_BSN);
+ QuasiBundle rqb = new StandardQuasiBundle(requiredBundleDescription, null, this.stateHelper);
+ QuasiRequiredBundle qrb = new StandardQuasiRequiredBundle(this.bundleSpecification, this.qb);
+ this.bundleSpecification.setResolved(true);
+ StubBaseDescription supplier = new StubBaseDescription();
+ supplier.setSupplier(requiredBundleDescription);
+ this.bundleSpecification.setSupplier(supplier);
+ Assert.assertEquals(rqb, qrb.getProvider());
+ }
+
+ @Test
+ public void testRequiringBundle() {
+ QuasiRequiredBundle qrb = new StandardQuasiRequiredBundle(this.bundleSpecification, this.qb);
+ Assert.assertEquals(this.qb, qrb.getRequiringBundle());
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBaseDescription.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBaseDescription.java
new file mode 100644
index 00000000..e7a6479b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBaseDescription.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import org.eclipse.osgi.service.resolver.BaseDescription;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.osgi.framework.Version;
+
+
+/**
+ * TODO Document StubBaseDescription
+ * <p />
+ *
+ * <strong>Concurrent Semantics</strong><br />
+ *
+ * TODO Document concurrent semantics of StubBaseDescription
+ *
+ */
+public class StubBaseDescription implements BaseDescription {
+
+ private BundleDescription supplier;
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription getSupplier() {
+ return this.supplier;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Version getVersion() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setSupplier(BundleDescription supplier) {
+ this.supplier = supplier;
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBundleDescription.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBundleDescription.java
new file mode 100644
index 00000000..a5834a95
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBundleDescription.java
@@ -0,0 +1,348 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.osgi.service.resolver.BaseDescription;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.BundleSpecification;
+import org.eclipse.osgi.service.resolver.ExportPackageDescription;
+import org.eclipse.osgi.service.resolver.GenericDescription;
+import org.eclipse.osgi.service.resolver.GenericSpecification;
+import org.eclipse.osgi.service.resolver.HostSpecification;
+import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
+import org.eclipse.osgi.service.resolver.NativeCodeSpecification;
+import org.eclipse.osgi.service.resolver.State;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
+
+/**
+ */
+public class StubBundleDescription implements BundleDescription {
+
+ private String bsn;
+
+ private Version bv;
+
+ private boolean resolved;
+
+ private long bid;
+
+ private List<BundleDescription> fragments = new ArrayList<BundleDescription>();
+
+ private List<BundleDescription> hosts = null;
+
+ private List<ExportPackageDescription> epds = new ArrayList<ExportPackageDescription>();
+
+ private List<ImportPackageSpecification> ipss = new ArrayList<ImportPackageSpecification>();
+
+ private List<BundleSpecification> rbs = new ArrayList<BundleSpecification>();
+
+ private List<BundleDescription> dependents = new ArrayList<BundleDescription>();
+
+ public StubBundleDescription() {
+ }
+
+ public StubBundleDescription(String bsn) {
+ this.bsn = bsn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean attachFragments() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean dynamicFragments() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public long getBundleId() {
+ return this.bid;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public State getContainingState() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription[] getDependents() {
+ return this.dependents.toArray(new BundleDescription[this.dependents.size()]);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String[] getExecutionEnvironments() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ExportPackageDescription[] getExportPackages() {
+ return this.epds.toArray(new ExportPackageDescription[this.epds.size()]);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription[] getFragments() {
+ return this.fragments.toArray(new BundleDescription[this.fragments.size()]);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public GenericDescription[] getGenericCapabilities() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public GenericSpecification[] getGenericRequires() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public HostSpecification getHost() {
+ return StubBundleDescription.this.hosts == null ? null : new HostSpecification() {
+
+ public BundleDescription[] getHosts() {
+ return StubBundleDescription.this.hosts.toArray(new BundleDescription[StubBundleDescription.this.hosts.size()]);
+ }
+
+ public boolean isMultiHost() {
+ throw new UnsupportedOperationException();
+ }
+
+ public BundleDescription getBundle() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getName() {
+ throw new UnsupportedOperationException();
+ }
+
+ public BaseDescription getSupplier() {
+ throw new UnsupportedOperationException();
+ }
+
+ public VersionRange getVersionRange() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isResolved() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isSatisfiedBy(BaseDescription supplier) {
+ throw new UnsupportedOperationException();
+ }
+
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ImportPackageSpecification[] getImportPackages() {
+ return this.ipss.toArray(new ImportPackageSpecification[this.ipss.size()]);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getLocation() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public NativeCodeSpecification getNativeCodeSpecification() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getPlatformFilter() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleSpecification[] getRequiredBundles() {
+ return this.rbs.toArray(new BundleSpecification[this.rbs.size()]);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ExportPackageDescription[] getResolvedImports() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription[] getResolvedRequires() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ExportPackageDescription[] getSelectedExports() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ExportPackageDescription[] getSubstitutedExports() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getSymbolicName() {
+ return this.bsn;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object getUserObject() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasDynamicImports() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isRemovalPending() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isResolved() {
+ return this.resolved;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isSingleton() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setUserObject(Object userObject) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription getSupplier() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Version getVersion() {
+ return this.bv;
+ }
+
+ public void setBundleSymbolicName(String bsn) {
+ this.bsn = bsn;
+ }
+
+ public void setVersion(Version bv) {
+ this.bv = bv;
+ }
+
+ public void setResolved(boolean resolved) {
+ this.resolved = resolved;
+ }
+
+ public void setBundleId(long bid) {
+ this.bid = bid;
+ }
+
+ public void addFragment(BundleDescription f) {
+ this.fragments.add(f);
+ }
+
+ public void addHost(StubBundleDescription bd) {
+ if (this.hosts == null) {
+ this.hosts = new ArrayList<BundleDescription>();
+ }
+ this.hosts.add(bd);
+ }
+
+ public void addExportPackage(ExportPackageDescription epd) {
+ this.epds.add(epd);
+ }
+
+ public void addImportPackage(ImportPackageSpecification ips) {
+ this.ipss.add(ips);
+ }
+
+ public void addRequiredBundle(BundleSpecification bs) {
+ this.rbs.add(bs);
+ }
+
+ public void addDependent(BundleDescription d) {
+ this.dependents.add(d);
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBundleSpecification.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBundleSpecification.java
new file mode 100644
index 00000000..23aacf92
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubBundleSpecification.java
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import org.eclipse.osgi.service.resolver.BaseDescription;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.BundleSpecification;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+/**
+ */
+public class StubBundleSpecification implements BundleSpecification {
+
+ private String name;
+
+ private VersionRange versionRange;
+
+ private boolean resolved = false;
+
+ private BaseDescription supplier;
+
+ public StubBundleSpecification(String name) {
+ this.name = name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isExported() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isOptional() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription getBundle() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BaseDescription getSupplier() {
+ return this.supplier;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public VersionRange getVersionRange() {
+ return this.versionRange;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isResolved() {
+ return this.resolved;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isSatisfiedBy(BaseDescription supplier) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setVersionRange(VersionRange versionRange) {
+ this.versionRange = versionRange;
+ }
+
+ public void setResolved(boolean resolved) {
+ this.resolved = resolved;
+ }
+
+ public void setSupplier(BaseDescription supplier) {
+ this.supplier = supplier;
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubExportPackageDescription.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubExportPackageDescription.java
new file mode 100644
index 00000000..c09bcaf0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubExportPackageDescription.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.ExportPackageDescription;
+import org.osgi.framework.Version;
+
+/**
+ */
+public class StubExportPackageDescription extends StubParameterised implements ExportPackageDescription {
+
+ private String name;
+
+ private Version version;
+
+ private BundleDescription exporter;
+
+ public StubExportPackageDescription(String name) {
+ this.name = name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription getExporter() {
+ return this.exporter;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isRoot() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription getSupplier() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Version getVersion() {
+ return this.version;
+ }
+
+ public void setVersion(Version version) {
+ this.version = version;
+ }
+
+ public void setExporter(BundleDescription exporter) {
+ this.exporter = exporter;
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubImportPackageSpecification.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubImportPackageSpecification.java
new file mode 100644
index 00000000..bb1c3edc
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubImportPackageSpecification.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import org.eclipse.osgi.service.resolver.BaseDescription;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
+import org.eclipse.osgi.service.resolver.VersionRange;
+
+/**
+ */
+public class StubImportPackageSpecification extends StubParameterised implements ImportPackageSpecification {
+
+ private String name;
+
+ private VersionRange versionRange;
+
+ private boolean resolved = false;
+
+ private BaseDescription supplier;
+
+ private BundleDescription bundle;
+
+ public StubImportPackageSpecification(String name) {
+ this.name = name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getBundleSymbolicName() {
+ return "supplierBundle";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public VersionRange getBundleVersionRange() {
+ return new VersionRange("[2.0.0, 4.0.0)");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription getBundle() {
+ return this.bundle;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BaseDescription getSupplier() {
+ return this.supplier;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public VersionRange getVersionRange() {
+ return this.versionRange;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isResolved() {
+ return this.resolved ;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isSatisfiedBy(BaseDescription supplier) {
+ return this.name.equals(supplier.getName());
+ }
+
+ public void setVersionRange(VersionRange versionRange) {
+ this.versionRange = versionRange;
+ }
+
+ public void setResolved(boolean b) {
+ this.resolved = b;
+ }
+
+ public void setBundle(BundleDescription bundle) {
+ this.bundle = bundle;
+ }
+
+ public void setSupplier(BaseDescription supplier) {
+ this.supplier = supplier;
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubParameterised.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubParameterised.java
new file mode 100644
index 00000000..437fbdaa
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubParameterised.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ */
+public abstract class StubParameterised {
+
+ @SuppressWarnings("unchecked")
+ Map attributes = new HashMap();
+
+ @SuppressWarnings("unchecked")
+ Map directives = new HashMap();
+
+ @SuppressWarnings("unchecked")
+ public Map getAttributes() {
+ return this.attributes;
+ }
+
+ public Object getDirective(String key) {
+ return this.directives.get(key);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Map getDirectives() {
+ return this.directives;
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubStateHelper.java b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubStateHelper.java
new file mode 100644
index 00000000..9b4fdae5
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/java/org/eclipse/virgo/kernel/userregion/internal/quasi/StubStateHelper.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2008, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VMware Inc. - initial contribution
+ *******************************************************************************/
+
+package org.eclipse.virgo.kernel.userregion.internal.quasi;
+
+import org.eclipse.osgi.service.resolver.BundleDescription;
+import org.eclipse.osgi.service.resolver.BundleSpecification;
+import org.eclipse.osgi.service.resolver.ExportPackageDescription;
+import org.eclipse.osgi.service.resolver.HostSpecification;
+import org.eclipse.osgi.service.resolver.ImportPackageSpecification;
+import org.eclipse.osgi.service.resolver.StateHelper;
+import org.eclipse.osgi.service.resolver.VersionConstraint;
+
+/**
+ */
+public class StubStateHelper implements StateHelper {
+
+ private BundleDescription[] dependentBundles;
+
+ private ExportPackageDescription[] visiblePackages;
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getAccessCode(BundleDescription bundle, ExportPackageDescription export) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription[] getDependentBundles(BundleDescription[] bundles) {
+ return this.dependentBundles;
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BundleDescription[] getPrerequisites(BundleDescription[] bundles) {
+ throw new UnsupportedOperationException();
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public VersionConstraint[] getUnsatisfiedConstraints(BundleDescription bundle) {
+ throw new UnsupportedOperationException();
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public VersionConstraint[] getUnsatisfiedLeaves(BundleDescription[] bundles) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ExportPackageDescription[] getVisiblePackages(BundleDescription bundle) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ExportPackageDescription[] getVisiblePackages(BundleDescription bundle, int options) {
+ return this.visiblePackages;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isResolvable(ImportPackageSpecification specification) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isResolvable(BundleSpecification specification) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isResolvable(HostSpecification specification) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object[][] sortBundles(BundleDescription[] toSort) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setDependentBundles(BundleDescription[] dependentBundles) {
+ this.dependentBundles = dependentBundles;
+ }
+
+ public void setVisiblePackages(ExportPackageDescription[] visiblePackages) {
+ this.visiblePackages = visiblePackages;
+ }
+
+}
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/EquinoxOsgiFrameworkTests/faulty/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/EquinoxOsgiFrameworkTests/faulty/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..ba572dfe
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/EquinoxOsgiFrameworkTests/faulty/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Bundle-SymbolicName: faulty
+Bundle-ManifestVersion: 2
+Bundle-Version: 1
+Import-Package: alpha
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/KernelBundleClassLoaderTests/dependant.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/KernelBundleClassLoaderTests/dependant.jar
new file mode 100644
index 00000000..54b40064
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/KernelBundleClassLoaderTests/dependant.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/KernelBundleClassLoaderTests/depender.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/KernelBundleClassLoaderTests/depender.jar
new file mode 100644
index 00000000..e522f570
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/KernelBundleClassLoaderTests/depender.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/eight/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/eight/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..b0b00a3c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/eight/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.eight
+Export-Package: install.eight
+Import-Package: install.six, install.seven
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/error/missingimport/bundle/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/error/missingimport/bundle/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..e34088cc
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/error/missingimport/bundle/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.error.import
+Import-Package: does.not.exist
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/five/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/five/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..30bb1e39
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/five/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.five
+Export-Package: install.five
+Require-Bundle: install.three
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/four/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/four/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..cd43c08c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/four/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Import-Package: install.three
+Bundle-SymbolicName: install.four
+Export-Package: install.four
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/fragments/unresolvable/bundle/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/fragments/unresolvable/bundle/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..9b7951f0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/fragments/unresolvable/bundle/META-INF/MANIFEST.MF
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: fragments.unresolvable.host
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/fragments/unresolvable/fragment/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/fragments/unresolvable/fragment/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..8f3a9850
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/fragments/unresolvable/fragment/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: fragments.unresolvable.frag
+Fragment-Host: fragments.unresolvable.host
+Import-Package: no.chance
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/a/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/a/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..002aa5b4
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/a/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.multi.a
+Export-Package: multi;version="1.2"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/b/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/b/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..a2397014
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/b/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.multi.b
+Export-Package: multi;version="1.3"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/bundle/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/bundle/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..214cb9cf
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/multi/bundle/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.multi.bundle
+Import-Package: multi;version="[1.2,1.4)"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/nine/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/nine/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..9b7affdf
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/nine/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Import-Package: install.one
+Bundle-SymbolicName: install.nine
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/one/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/one/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..7eccd98e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/one/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.one
+Export-Package: install.one
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatindep/bundle/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatindep/bundle/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..3545444f
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatindep/bundle/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.optional.dep.bundle
+Import-Package: pqr;resolution:=optional
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatindep/dep/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatindep/dep/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..15c08075
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatindep/dep/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.optional.dep.dep
+Export-Package: pqr
+Import-Package: foo
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatisfied/bundle/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatisfied/bundle/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..f8f126c8
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/optional/notsatisfied/bundle/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.optional.ns
+Import-Package: p;resolution:=optional
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/outsiderepo/bundle/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/outsiderepo/bundle/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..42820160
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/outsiderepo/bundle/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.outsiderepo
+Import-Package: install.standalone
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/seven/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/seven/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..18490ccf
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/seven/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.seven
+Export-Package: install.seven
+Import-Package: install.six
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/six/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/six/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..e5ff528f
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/six/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Import-Package: install.seven,install.eight
+Bundle-SymbolicName: install.six
+Export-Package: install.six
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/three/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/three/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..c5a43e25
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/three/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Import-Package: install.two,install.one
+Bundle-SymbolicName: install.three
+Export-Package: install.three
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/two/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/two/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..1573224d
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/two/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.two
+Export-Package: install.two
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/bundle/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/bundle/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..fd0eb33a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/bundle/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.uses.bundle
+Import-Package: uses.spring;version="[2.5.5, 2.5.5]",uses.hibernate;version="[3.2.6, 3.2.6]"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/hibernate325/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/hibernate325/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..e68b24a7
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/hibernate325/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: install.uses.hibernate325
+Export-Package: uses.hibernate;version="3.2.5"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/hibernate326/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/hibernate326/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..53d31a25
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/hibernate326/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: install.uses.hibernate326
+Export-Package: uses.hibernate;version="3.2.6"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/spring/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/spring/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..365df33d
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/uses/spring/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: install.uses.spring
+Export-Package: uses.spring;version="2.5.5";uses:="uses.hibernate"
+Import-Package: uses.hibernate;version="[3.2.5, 3.2.5]"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/x/high/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/x/high/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..f48164d0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/x/high/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.x
+Bundle-Version: 1.4.6
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/x/low/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/x/low/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..195710c2
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/install/x/low/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.x
+Bundle-Version: 1.4.7
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/standalone/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/standalone/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..b703d84a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/bit/standalone/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: install.standalone
+Export-Package: install.standalone
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/config/BundleInstallationTests/repository.properties b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/BundleInstallationTests/repository.properties
new file mode 100644
index 00000000..55c3ddbc
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/BundleInstallationTests/repository.properties
@@ -0,0 +1,43 @@
+bundles.type=external
+bundles.searchPattern=../{bundle}/target/classes
+
+ivy-cache-bundles.type=external
+ivy-cache-bundles.searchPattern=../${ivy.cache::ivy-cache}/repository/{org}/{name}/{version}/{bundle}.jar
+
+ivy-cache-libraries.type=external
+ivy-cache-libraries.searchPattern=../${ivy.cache::ivy-cache}/repository/{org}/{name}/{version}/{library}.libd
+
+src-test-resources-frag.type=external
+src-test-resources-frag.searchPattern=src/test/resources/frag/*
+
+src-test-resources-jars.type=external
+src-test-resources-jars.searchPattern=src/test/resources/jars/*.jar
+
+src-test-resources-bit-install-x.type=external
+src-test-resources-bit-install-x.searchPattern=src/test/resources/bit/install/x/*
+
+src-test-resources-bit-install.type=external
+src-test-resources-bit-install.searchPattern=src/test/resources/bit/install/*
+
+src-test-resources-fail.type=external
+src-test-resources-fail.searchPattern=src/test/resources/fail/*
+
+src-test-resources-bit-install-optional.type=external
+src-test-resources-bit-install-optional.searchPattern=src/test/resources/bit/install/optional/*/*
+
+src-test-resources-bit-install-error.type=external
+src-test-resources-bit-install-error.searchPattern=src/test/resources/bit/install/error/*/*
+
+src-test-resources-bit-install-fragments.type=external
+src-test-resources-bit-install-fragments.searchPattern=src/test/resources/bit/install/fragments/*/*
+
+src-test-resources-bit-install-outsiderepo.type=external
+src-test-resources-bit-install-outsiderepo.searchPattern=src/test/resources/bit/install/outsiderepo/*
+
+src-test-resources-bit-install-multi.type=external
+src-test-resources-bit-install-multi.searchPattern=src/test/resources/bit/install/multi/*
+
+src-test-resources-bit-install-uses.type=external
+src-test-resources-bit-install-uses.searchPattern=src/test/resources/bit/install/uses/*
+
+chain=bundles,ivy-cache-bundles,ivy-cache-libraries,src-test-resources-frag,src-test-resources-jars,src-test-resources-bit-install-x,src-test-resources-bit-install,src-test-resources-fail,src-test-resources-bit-install-optional,src-test-resources-bit-install-error,src-test-resources-bit-install-fragments,src-test-resources-bit-install-outsiderepo,src-test-resources-bit-install-multi,src-test-resources-bit-install-uses
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/config/BundleUpdateTests/repository.properties b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/BundleUpdateTests/repository.properties
new file mode 100644
index 00000000..55c3ddbc
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/BundleUpdateTests/repository.properties
@@ -0,0 +1,43 @@
+bundles.type=external
+bundles.searchPattern=../{bundle}/target/classes
+
+ivy-cache-bundles.type=external
+ivy-cache-bundles.searchPattern=../${ivy.cache::ivy-cache}/repository/{org}/{name}/{version}/{bundle}.jar
+
+ivy-cache-libraries.type=external
+ivy-cache-libraries.searchPattern=../${ivy.cache::ivy-cache}/repository/{org}/{name}/{version}/{library}.libd
+
+src-test-resources-frag.type=external
+src-test-resources-frag.searchPattern=src/test/resources/frag/*
+
+src-test-resources-jars.type=external
+src-test-resources-jars.searchPattern=src/test/resources/jars/*.jar
+
+src-test-resources-bit-install-x.type=external
+src-test-resources-bit-install-x.searchPattern=src/test/resources/bit/install/x/*
+
+src-test-resources-bit-install.type=external
+src-test-resources-bit-install.searchPattern=src/test/resources/bit/install/*
+
+src-test-resources-fail.type=external
+src-test-resources-fail.searchPattern=src/test/resources/fail/*
+
+src-test-resources-bit-install-optional.type=external
+src-test-resources-bit-install-optional.searchPattern=src/test/resources/bit/install/optional/*/*
+
+src-test-resources-bit-install-error.type=external
+src-test-resources-bit-install-error.searchPattern=src/test/resources/bit/install/error/*/*
+
+src-test-resources-bit-install-fragments.type=external
+src-test-resources-bit-install-fragments.searchPattern=src/test/resources/bit/install/fragments/*/*
+
+src-test-resources-bit-install-outsiderepo.type=external
+src-test-resources-bit-install-outsiderepo.searchPattern=src/test/resources/bit/install/outsiderepo/*
+
+src-test-resources-bit-install-multi.type=external
+src-test-resources-bit-install-multi.searchPattern=src/test/resources/bit/install/multi/*
+
+src-test-resources-bit-install-uses.type=external
+src-test-resources-bit-install-uses.searchPattern=src/test/resources/bit/install/uses/*
+
+chain=bundles,ivy-cache-bundles,ivy-cache-libraries,src-test-resources-frag,src-test-resources-jars,src-test-resources-bit-install-x,src-test-resources-bit-install,src-test-resources-fail,src-test-resources-bit-install-optional,src-test-resources-bit-install-error,src-test-resources-bit-install-fragments,src-test-resources-bit-install-outsiderepo,src-test-resources-bit-install-multi,src-test-resources-bit-install-uses
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/config/EquinoxOsgiFrameworkTests/repository.properties b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/EquinoxOsgiFrameworkTests/repository.properties
new file mode 100644
index 00000000..58341ec0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/EquinoxOsgiFrameworkTests/repository.properties
@@ -0,0 +1,4 @@
+src-test-resources-faulty.type=external
+src-test-resources-faulty.searchPattern=src/test/resources/faulty/*.jar
+
+chain=src-test-resources-faulty
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/config/ImportExpansionHandlerTests/repository.properties b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/ImportExpansionHandlerTests/repository.properties
new file mode 100644
index 00000000..f5854cdf
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/ImportExpansionHandlerTests/repository.properties
@@ -0,0 +1,13 @@
+bundles.type=external
+bundles.searchPattern=../{bundle}/target/classes
+
+src-test-resources-silht-libraries.type=external
+src-test-resources-silht-libraries.searchPattern=src/test/resources/silht/libraries/{name}.libd
+
+src-test-resources-silht-bundles.type=external
+src-test-resources-silht-bundles.searchPattern=src/test/resources/silht/bundles/{name}
+
+src-test-resources-ieh.type=external
+src-test-resources-ieh.searchPattern=src/test/resources/ieh/*
+
+chain=bundles,src-test-resources-silht-libraries,src-test-resources-silht-bundles,src-test-resources-ieh
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/config/InstallFromLocationTests/repository.properties b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/InstallFromLocationTests/repository.properties
new file mode 100644
index 00000000..4b83bd7d
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/InstallFromLocationTests/repository.properties
@@ -0,0 +1,4 @@
+src-test-resources-empty.type=external
+src-test-resources-empty.searchPattern=src/test/resources/empty
+
+chain=src-test-resources-empty
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/config/KernelBundleClassLoaderTests/repository.properties b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/KernelBundleClassLoaderTests/repository.properties
new file mode 100644
index 00000000..a5e712c4
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/KernelBundleClassLoaderTests/repository.properties
@@ -0,0 +1,13 @@
+bundles.type=external
+bundles.searchPattern=../{bundle}/target/classes
+
+ivy-cache-bundles.type=external
+ivy-cache-bundles.searchPattern=../${ivy.cache::ivy-cache}/repository/{org}/{name}/{version}/{bundle}.jar
+
+ivy-cache-libraries.type=external
+ivy-cache-libraries.searchPattern=../${ivy.cache::ivy-cache}/repository/{org}/{name}/{version}/{library}.libd
+
+src-test-resources-resources.type=external
+src-test-resources-resources.searchPattern=src/test/resources/KernelBundleClassLoaderTests/*
+
+chain=bundles,ivy-cache-bundles,ivy-cache-libraries,src-test-resources-resources
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/config/LoadTimeWeavingTests/repository.properties b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/LoadTimeWeavingTests/repository.properties
new file mode 100644
index 00000000..611e33e5
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/LoadTimeWeavingTests/repository.properties
@@ -0,0 +1,4 @@
+src-test-resources-ltw.type=external
+src-test-resources-ltw.searchPattern=src/test/resources/ltw/{bundle}.jar
+
+chain=src-test-resources-ltw
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/config/ResolutionStateDumperTests/repository.properties b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/ResolutionStateDumperTests/repository.properties
new file mode 100644
index 00000000..ca067ea3
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/ResolutionStateDumperTests/repository.properties
@@ -0,0 +1,4 @@
+src-test-resources-rfd.type=external
+src-test-resources-rfd.searchPattern=src/test/resources/rfd/{name}
+
+chain=src-test-resources-rfd
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/config/UsesAnalyserTests/repository.properties b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/UsesAnalyserTests/repository.properties
new file mode 100644
index 00000000..ca067ea3
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/config/UsesAnalyserTests/repository.properties
@@ -0,0 +1,4 @@
+src-test-resources-rfd.type=external
+src-test-resources-rfd.searchPattern=src/test/resources/rfd/{name}
+
+chain=src-test-resources-rfd
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/config/repository.properties b/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/config/repository.properties
new file mode 100644
index 00000000..22f6874e
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/config/repository.properties
@@ -0,0 +1,7 @@
+bundles.type=external
+bundles.searchPattern=src/test/resources/dependency-locator/repository/bundles/{bundle}
+
+libraries.type=external
+libraries.searchPattern=src/test/resources/dependency-locator/repository/libraries/{library}
+
+chain=bundles,libraries
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/java5-server.profile b/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/java5-server.profile
new file mode 100644
index 00000000..4fc9e2bb
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/java5-server.profile
@@ -0,0 +1,152 @@
+org.osgi.framework.system.packages = \
+ org.eclipse.virgo.server.serviceability.logging;version="1.0",\
+ org.eclipse.virgo.server.serviceability.output;version="1.0",\
+ org.eclipse.virgo.server.serviceability.tracing;version="1.0",\
+ javax.accessibility,\
+ javax.activity,\
+ javax.crypto,\
+ javax.crypto.interfaces,\
+ javax.crypto.spec,\
+ javax.imageio,\
+ javax.imageio.event,\
+ javax.imageio.metadata,\
+ javax.imageio.plugins.bmp,\
+ javax.imageio.plugins.jpeg,\
+ javax.imageio.spi,\
+ javax.imageio.stream,\
+ javax.management,\
+ javax.management.loading,\
+ javax.management.modelmbean,\
+ javax.management.monitor,\
+ javax.management.openmbean,\
+ javax.management.relation,\
+ javax.management.remote,\
+ javax.management.remote.rmi,\
+ javax.management.timer,\
+ javax.naming,\
+ javax.naming.directory,\
+ javax.naming.event,\
+ javax.naming.ldap,\
+ javax.naming.spi,\
+ javax.net,\
+ javax.net.ssl,\
+ javax.print,\
+ javax.print.attribute,\
+ javax.print.attribute.standard,\
+ javax.print.event,\
+ javax.rmi,\
+ javax.rmi.CORBA,\
+ javax.rmi.ssl,\
+ javax.security.auth,\
+ javax.security.auth.callback,\
+ javax.security.auth.kerberos,\
+ javax.security.auth.login,\
+ javax.security.auth.spi,\
+ javax.security.auth.x500,\
+ javax.security.cert,\
+ javax.security.sasl,\
+ javax.sound.midi,\
+ javax.sound.midi.spi,\
+ javax.sound.sampled,\
+ javax.sound.sampled.spi,\
+ javax.sql,\
+ javax.sql.rowset,\
+ javax.sql.rowset.serial,\
+ javax.sql.rowset.spi,\
+ javax.swing,\
+ javax.swing.border,\
+ javax.swing.colorchooser,\
+ javax.swing.event,\
+ javax.swing.filechooser,\
+ javax.swing.plaf,\
+ javax.swing.plaf.basic,\
+ javax.swing.plaf.metal,\
+ javax.swing.plaf.multi,\
+ javax.swing.plaf.synth,\
+ javax.swing.table,\
+ javax.swing.text,\
+ javax.swing.text.html,\
+ javax.swing.text.html.parser,\
+ javax.swing.text.rtf,\
+ javax.swing.tree,\
+ javax.swing.undo,\
+ javax.transaction,\
+ javax.transaction.xa,\
+ javax.xml,\
+ javax.xml.datatype,\
+ javax.xml.namespace,\
+ javax.xml.parsers,\
+ javax.xml.transform,\
+ javax.xml.transform.dom,\
+ javax.xml.transform.sax,\
+ javax.xml.transform.stream,\
+ javax.xml.validation,\
+ javax.xml.xpath,\
+ org.apache.commons.logging;version="1.1.1",\
+ org.apache.commons.logging.impl;version="1.1.1",\
+ org.ietf.jgss,\
+ org.omg.CORBA,\
+ org.omg.CORBA_2_3,\
+ org.omg.CORBA_2_3.portable,\
+ org.omg.CORBA.DynAnyPackage,\
+ org.omg.CORBA.ORBPackage,\
+ org.omg.CORBA.portable,\
+ org.omg.CORBA.TypeCodePackage,\
+ org.omg.CosNaming,\
+ org.omg.CosNaming.NamingContextExtPackage,\
+ org.omg.CosNaming.NamingContextPackage,\
+ org.omg.Dynamic,\
+ org.omg.DynamicAny,\
+ org.omg.DynamicAny.DynAnyFactoryPackage,\
+ org.omg.DynamicAny.DynAnyPackage,\
+ org.omg.IOP,\
+ org.omg.IOP.CodecFactoryPackage,\
+ org.omg.IOP.CodecPackage,\
+ org.omg.Messaging,\
+ org.omg.PortableInterceptor,\
+ org.omg.PortableInterceptor.ORBInitInfoPackage,\
+ org.omg.PortableServer,\
+ org.omg.PortableServer.CurrentPackage,\
+ org.omg.PortableServer.POAManagerPackage,\
+ org.omg.PortableServer.POAPackage,\
+ org.omg.PortableServer.portable,\
+ org.omg.PortableServer.ServantLocatorPackage,\
+ org.omg.SendingContext,\
+ org.omg.stub.java.rmi,\
+ org.slf4j;version="1.5.0",\
+ org.slf4j.helpers;version="1.5.0",\
+ org.slf4j.impl;version="1.5.0",\
+ org.slf4j.spi;version="1.5.0",\
+ org.w3c.dom,\
+ org.w3c.dom.bootstrap,\
+ org.w3c.dom.css,\
+ org.w3c.dom.events,\
+ org.w3c.dom.html,\
+ org.w3c.dom.ls,\
+ org.w3c.dom.ranges,\
+ org.w3c.dom.stylesheets,\
+ org.w3c.dom.traversal,\
+ org.w3c.dom.views ,\
+ org.xml.sax,\
+ org.xml.sax.ext,\
+ org.xml.sax.helpers
+org.osgi.framework.bootdelegation = \
+ com_cenqua_clover,\
+ com.cenqua.*,\
+ com.yourkit.*,\
+ org.eclipse.virgo.server.bootstrap,\
+ org.eclipse.virgo.server.kernel.bootstrap,\
+ org.eclipse.virgo.server.osgi.*,\
+ com.sun.*,\
+ javax.xml.*,\
+ org.apache.xerces.jaxp.*,\
+ org.w3c.*,\
+ org.xml.*,\
+ sun.*
+org.osgi.framework.executionenvironment = \
+ OSGi/Minimum-1.0,\
+ OSGi/Minimum-1.1,\
+ J2SE-1.3,\
+ J2SE-1.4,\
+ J2SE-1.5
+osgi.java.profile.name = SpringSource-AP-Java5
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/java6-server.profile b/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/java6-server.profile
new file mode 100644
index 00000000..5e41d4fe
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/java6-server.profile
@@ -0,0 +1,216 @@
+org.osgi.framework.system.packages = \
+ org.eclipse.virgo.server.serviceability.logging;version="1.0",\
+ org.eclipse.virgo.server.serviceability.output;version="1.0",\
+ org.eclipse.virgo.server.serviceability.tracing;version="1.0",\
+ javax.accessibility,\
+ javax.activation,\
+ javax.activation;version="1.1.0",\
+ javax.activity,\
+ javax.annotation,\
+ javax.annotation;version="1.0.0",\
+ javax.annotation.processing,\
+ javax.crypto,\
+ javax.crypto.interfaces,\
+ javax.crypto.spec,\
+ javax.imageio,\
+ javax.imageio.event,\
+ javax.imageio.metadata,\
+ javax.imageio.plugins.bmp,\
+ javax.imageio.plugins.jpeg,\
+ javax.imageio.spi,\
+ javax.imageio.stream,\
+ javax.jws,\
+ javax.jws;version="2.0",\
+ javax.jws.soap,\
+ javax.jws.soap;version="2.0",\
+ javax.lang.model,\
+ javax.lang.model.element,\
+ javax.lang.model.type,\
+ javax.lang.model.util,\
+ javax.management,\
+ javax.management.loading,\
+ javax.management.modelmbean,\
+ javax.management.monitor,\
+ javax.management.openmbean,\
+ javax.management.relation,\
+ javax.management.remote,\
+ javax.management.remote.rmi,\
+ javax.management.timer,\
+ javax.naming,\
+ javax.naming.directory,\
+ javax.naming.event,\
+ javax.naming.ldap,\
+ javax.naming.spi,\
+ javax.net,\
+ javax.net.ssl,\
+ javax.print,\
+ javax.print.attribute,\
+ javax.print.attribute.standard,\
+ javax.print.event,\
+ javax.rmi,\
+ javax.rmi.CORBA,\
+ javax.rmi.ssl,\
+ javax.script,\
+ javax.script;version="1.1",\
+ javax.security.auth,\
+ javax.security.auth.callback,\
+ javax.security.auth.kerberos,\
+ javax.security.auth.login,\
+ javax.security.auth.spi,\
+ javax.security.auth.x500,\
+ javax.security.cert,\
+ javax.security.sasl,\
+ javax.sound.midi,\
+ javax.sound.midi.spi,\
+ javax.sound.sampled,\
+ javax.sound.sampled.spi,\
+ javax.sql,\
+ javax.sql.rowset,\
+ javax.sql.rowset.serial,\
+ javax.sql.rowset.spi,\
+ javax.swing,\
+ javax.swing.border,\
+ javax.swing.colorchooser,\
+ javax.swing.event,\
+ javax.swing.filechooser,\
+ javax.swing.plaf,\
+ javax.swing.plaf.basic,\
+ javax.swing.plaf.metal,\
+ javax.swing.plaf.multi,\
+ javax.swing.plaf.synth,\
+ javax.swing.table,\
+ javax.swing.text,\
+ javax.swing.text.html,\
+ javax.swing.text.html.parser,\
+ javax.swing.text.rtf,\
+ javax.swing.tree,\
+ javax.swing.undo,\
+ javax.tools,\
+ javax.transaction,\
+ javax.transaction.xa,\
+ javax.xml,\
+ javax.xml;version="1.0.1",\
+ javax.xml.bind,\
+ javax.xml.bind;version="2.0",\
+ javax.xml.bind.annotation,\
+ javax.xml.bind.annotation;version="2.0",\
+ javax.xml.bind.annotation.adapters,\
+ javax.xml.bind.annotation.adapters;version="2.0",\
+ javax.xml.bind.attachment,\
+ javax.xml.bind.attachment;version="2.0",\
+ javax.xml.bind.helpers,\
+ javax.xml.bind.helpers;version="2.0",\
+ javax.xml.bind.util,\
+ javax.xml.bind.util;version="2.0",\
+ javax.xml.crypto,\
+ javax.xml.crypto;version="1.0",\
+ javax.xml.crypto.dom,\
+ javax.xml.crypto.dom;version="1.0",\
+ javax.xml.crypto.dsig,\
+ javax.xml.crypto.dsig;version="1.0",\
+ javax.xml.crypto.dsig.dom,\
+ javax.xml.crypto.dsig.dom;version="1.0",\
+ javax.xml.crypto.dsig.keyinfo,\
+ javax.xml.crypto.dsig.keyinfo;version="1.0",\
+ javax.xml.crypto.dsig.spec,\
+ javax.xml.crypto.dsig.spec;version="1.0",\
+ javax.xml.datatype,\
+ javax.xml.namespace,\
+ javax.xml.parsers,\
+ javax.xml.soap,\
+ javax.xml.soap;version="1.3.0",\
+ javax.xml.stream,\
+ javax.xml.stream;version="1.0.1",\
+ javax.xml.stream.events,\
+ javax.xml.stream.events;version="1.0.1",\
+ javax.xml.stream.util,\
+ javax.xml.stream.util;version="1.0.1",\
+ javax.xml.transform,\
+ javax.xml.transform.dom,\
+ javax.xml.transform.sax,\
+ javax.xml.transform.stax,\
+ javax.xml.transform.stream,\
+ javax.xml.validation,\
+ javax.xml.ws,\
+ javax.xml.ws;version="2.1.1",\
+ javax.xml.ws.handler,\
+ javax.xml.ws.handler;version="2.1.1",\
+ javax.xml.ws.handler.soap,\
+ javax.xml.ws.handler.soap;version="2.1.1",\
+ javax.xml.ws.http,\
+ javax.xml.ws.http;version="2.1.1",\
+ javax.xml.ws.soap,\
+ javax.xml.ws.soap;version="2.1.1",\
+ javax.xml.ws.spi,\
+ javax.xml.ws.spi;version="2.1.1",\
+ javax.xml.xpath,\
+ org.apache.commons.logging;version="1.1.1",\
+ org.apache.commons.logging.impl;version="1.1.1",\
+ org.ietf.jgss,\
+ org.omg.CORBA,\
+ org.omg.CORBA_2_3,\
+ org.omg.CORBA_2_3.portable,\
+ org.omg.CORBA.DynAnyPackage,\
+ org.omg.CORBA.ORBPackage,\
+ org.omg.CORBA.portable,\
+ org.omg.CORBA.TypeCodePackage,\
+ org.omg.CosNaming,\
+ org.omg.CosNaming.NamingContextExtPackage,\
+ org.omg.CosNaming.NamingContextPackage,\
+ org.omg.Dynamic,\
+ org.omg.DynamicAny,\
+ org.omg.DynamicAny.DynAnyFactoryPackage,\
+ org.omg.DynamicAny.DynAnyPackage,\
+ org.omg.IOP,\
+ org.omg.IOP.CodecFactoryPackage,\
+ org.omg.IOP.CodecPackage,\
+ org.omg.Messaging,\
+ org.omg.PortableInterceptor,\
+ org.omg.PortableInterceptor.ORBInitInfoPackage,\
+ org.omg.PortableServer,\
+ org.omg.PortableServer.CurrentPackage,\
+ org.omg.PortableServer.POAManagerPackage,\
+ org.omg.PortableServer.POAPackage,\
+ org.omg.PortableServer.portable,\
+ org.omg.PortableServer.ServantLocatorPackage,\
+ org.omg.SendingContext,\
+ org.omg.stub.java.rmi,\
+ org.slf4j;version="1.5.0",\
+ org.slf4j.helpers;version="1.5.0",\
+ org.slf4j.impl;version="1.5.0",\
+ org.slf4j.spi;version="1.5.0",\
+ org.w3c.dom,\
+ org.w3c.dom.bootstrap,\
+ org.w3c.dom.css,\
+ org.w3c.dom.events,\
+ org.w3c.dom.html,\
+ org.w3c.dom.ls,\
+ org.w3c.dom.ranges,\
+ org.w3c.dom.stylesheets,\
+ org.w3c.dom.traversal,\
+ org.w3c.dom.views ,\
+ org.xml.sax,\
+ org.xml.sax.ext,\
+ org.xml.sax.helpers
+org.osgi.framework.bootdelegation = \
+ com_cenqua_clover,\
+ com.cenqua.*,\
+ com.yourkit.*,\
+ org.eclipse.virgo.server.bootstrap,\
+ org.eclipse.virgo.server.bootstrap.*,\
+ org.eclipse.virgo.server.kernel.bootstrap,\
+ org.eclipse.virgo.server.osgi.*,\
+ com.sun.*,\
+ javax.xml.*,\
+ org.apache.xerces.jaxp.*,\
+ org.w3c.*,\
+ org.xml.*,\
+ sun.*
+org.osgi.framework.executionenvironment = \
+ OSGi/Minimum-1.0,\
+ OSGi/Minimum-1.1,\
+ J2SE-1.3,\
+ J2SE-1.4,\
+ J2SE-1.5,\
+ JavaSE-1.6
+osgi.java.profile.name = SpringSource-AP-Java6
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/org.eclipse.osgi-3.4.0.v20080529-1200.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/org.eclipse.osgi-3.4.0.v20080529-1200.jar
new file mode 100644
index 00000000..3d1f125b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/org.eclipse.osgi-3.4.0.v20080529-1200.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/server.profile b/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/server.profile
new file mode 100644
index 00000000..2f28c085
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/dependency-locator/lib/server.profile
@@ -0,0 +1,146 @@
+org.osgi.framework.system.packages = \
+ org.eclipse.virgo.server.serviceability.logging;version="1.0",\
+ org.eclipse.virgo.server.serviceability.output;version="1.0",\
+ org.eclipse.virgo.server.serviceability.tracing;version="1.0",\
+ javax.accessibility,\
+ javax.activity,\
+ javax.crypto,\
+ javax.crypto.interfaces,\
+ javax.crypto.spec,\
+ javax.imageio,\
+ javax.imageio.event,\
+ javax.imageio.metadata,\
+ javax.imageio.plugins.bmp,\
+ javax.imageio.plugins.jpeg,\
+ javax.imageio.spi,\
+ javax.imageio.stream,\
+ javax.management,\
+ javax.management.loading,\
+ javax.management.modelmbean,\
+ javax.management.monitor,\
+ javax.management.openmbean,\
+ javax.management.relation,\
+ javax.management.remote,\
+ javax.management.remote.rmi,\
+ javax.management.timer,\
+ javax.naming,\
+ javax.naming.directory,\
+ javax.naming.event,\
+ javax.naming.ldap,\
+ javax.naming.spi,\
+ javax.net,\
+ javax.net.ssl,\
+ javax.print,\
+ javax.print.attribute,\
+ javax.print.attribute.standard,\
+ javax.print.event,\
+ javax.rmi,\
+ javax.rmi.CORBA,\
+ javax.rmi.ssl,\
+ javax.security.auth,\
+ javax.security.auth.callback,\
+ javax.security.auth.kerberos,\
+ javax.security.auth.login,\
+ javax.security.auth.spi,\
+ javax.security.auth.x500,\
+ javax.security.cert,\
+ javax.security.sasl,\
+ javax.sound.midi,\
+ javax.sound.midi.spi,\
+ javax.sound.sampled,\
+ javax.sound.sampled.spi,\
+ javax.sql,\
+ javax.sql.rowset,\
+ javax.sql.rowset.serial,\
+ javax.sql.rowset.spi,\
+ javax.swing,\
+ javax.swing.border,\
+ javax.swing.colorchooser,\
+ javax.swing.event,\
+ javax.swing.filechooser,\
+ javax.swing.plaf,\
+ javax.swing.plaf.basic,\
+ javax.swing.plaf.metal,\
+ javax.swing.plaf.multi,\
+ javax.swing.plaf.synth,\
+ javax.swing.table,\
+ javax.swing.text,\
+ javax.swing.text.html,\
+ javax.swing.text.html.parser,\
+ javax.swing.text.rtf,\
+ javax.swing.tree,\
+ javax.swing.undo,\
+ javax.transaction,\
+ javax.transaction.xa,\
+ javax.xml,\
+ javax.xml.datatype,\
+ javax.xml.namespace,\
+ javax.xml.parsers,\
+ javax.xml.transform,\
+ javax.xml.transform.dom,\
+ javax.xml.transform.sax,\
+ javax.xml.transform.stream,\
+ javax.xml.validation,\
+ javax.xml.xpath,\
+ org.apache.commons.logging;version="1.1.1",\
+ org.apache.commons.logging.impl;version="1.1.1",\
+ org.ietf.jgss,\
+ org.omg.CORBA,\
+ org.omg.CORBA_2_3,\
+ org.omg.CORBA_2_3.portable,\
+ org.omg.CORBA.DynAnyPackage,\
+ org.omg.CORBA.ORBPackage,\
+ org.omg.CORBA.portable,\
+ org.omg.CORBA.TypeCodePackage,\
+ org.omg.CosNaming,\
+ org.omg.CosNaming.NamingContextExtPackage,\
+ org.omg.CosNaming.NamingContextPackage,\
+ org.omg.Dynamic,\
+ org.omg.DynamicAny,\
+ org.omg.DynamicAny.DynAnyFactoryPackage,\
+ org.omg.DynamicAny.DynAnyPackage,\
+ org.omg.IOP,\
+ org.omg.IOP.CodecFactoryPackage,\
+ org.omg.IOP.CodecPackage,\
+ org.omg.Messaging,\
+ org.omg.PortableInterceptor,\
+ org.omg.PortableInterceptor.ORBInitInfoPackage,\
+ org.omg.PortableServer,\
+ org.omg.PortableServer.CurrentPackage,\
+ org.omg.PortableServer.POAManagerPackage,\
+ org.omg.PortableServer.POAPackage,\
+ org.omg.PortableServer.portable,\
+ org.omg.PortableServer.ServantLocatorPackage,\
+ org.omg.SendingContext,\
+ org.omg.stub.java.rmi,\
+ org.slf4j;version="1.5.0",\
+ org.slf4j.helpers;version="1.5.0",\
+ org.slf4j.impl;version="1.5.0",\
+ org.slf4j.spi;version="1.5.0",\
+ org.w3c.dom,\
+ org.w3c.dom.bootstrap,\
+ org.w3c.dom.events,\
+ org.w3c.dom.ls,\
+ org.xml.sax,\
+ org.xml.sax.ext,\
+ org.xml.sax.helpers
+org.osgi.framework.bootdelegation = \
+ com_cenqua_clover,\
+ com.cenqua.*,\
+ com.yourkit.*,\
+ org.eclipse.virgo.server.bootstrap,\
+ org.eclipse.virgo.server.kernel.bootstrap,\
+ org.eclipse.virgo.server.osgi.*,\
+ com.sun.*,\
+ javax.xml.*,\
+ org.apache.xerces.jaxp.*,\
+ org.w3c.*,\
+ org.xml.*,\
+ sun.*
+org.osgi.framework.executionenvironment = \
+ OSGi/Minimum-1.0,\
+ OSGi/Minimum-1.1,\
+ J2SE-1.3,\
+ J2SE-1.4,\
+ J2SE-1.5
+osgi.java.profile.name = SpringSource-AP
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/fail/child/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/fail/child/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..c97a4806
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/fail/child/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: fail.child
+Bundle-Version: 1.0.0
+Export-Package: fail.child;version="1.2.3"
+Import-Package: fail.bar;version="1.2.3.";resolution:=optional
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/fail/parent/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/fail/parent/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..3c8b0e6b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/fail/parent/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: fail.parent
+Bundle-Version: 1.0.0
+Import-Package: fail.child
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/frag/child/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/frag/child/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..2795c80c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/frag/child/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: frag.child
+Bundle-Version: 1.0.0
+Fragment-Host: frag.host
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/frag/host/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/frag/host/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..47a5db64
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/frag/host/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: frag.host
+Bundle-Version: 1.0.0
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/four/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/four/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..8076c3c4
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/four/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: bundle.four
+Export-Package: bundle.four
+Import-Package: bundle.one
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/one/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/one/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..16e0d176
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/one/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: bundle.one
+Export-Package: bundle.one
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/three/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/three/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..62270044
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/three/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: bundle.three
+Export-Package: bundle.three
+Import-Package: bundle.two
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/two/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/two/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..334988a5
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/iflt/bundles/two/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: bundle.two
+Export-Package: bundle.two
+Import-Package: bundle.three
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/jars/dummy.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/jars/dummy.jar
new file mode 100644
index 00000000..7ab5fb31
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/jars/dummy.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/jars/mockbundle.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/jars/mockbundle.jar
new file mode 100644
index 00000000..d6c3b93a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/jars/mockbundle.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-domain.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-domain.jar
new file mode 100644
index 00000000..3adc23fd
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-domain.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-em.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-em.jar
new file mode 100644
index 00000000..22342b32
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-em.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-include.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-include.jar
new file mode 100644
index 00000000..06c0b6cd
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/ltw/ltw-include.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiapp-1.0.0.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiapp-1.0.0.jar
new file mode 100644
index 00000000..bb696600
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiapp-1.0.0.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiapp-2.0.0.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiapp-2.0.0.jar
new file mode 100644
index 00000000..30a81280
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiapp-2.0.0.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiservice-1.0.0.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiservice-1.0.0.jar
new file mode 100644
index 00000000..0e844c8a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiservice-1.0.0.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiservice-2.0.0.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiservice-2.0.0.jar
new file mode 100644
index 00000000..d1d6e2d7
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/platform170/simpleosgiservice-2.0.0.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd-other/other/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd-other/other/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..3169dff0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd-other/other/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: rfd.az
+Bundle-Version: 1.0
+Export-Package: rfd.az
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/a/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/a/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..deb3204b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/a/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: rfd.a
+Bundle-Version: 1.0
+Import-Package: rfd.b, rfd.az
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/app/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/app/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..13791715
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/app/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: rfd.app
+Bundle-Version: 1.0
+Export-Package: rfd.app
+Import-Package: rfd.hibernate;version="2.0",rfd.spring.orm
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/b/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/b/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..df7b55c9
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/b/META-INF/MANIFEST.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: rfd.b
+Bundle-Version: 1.0
+Import-Package: rfd.c
+Export-Package: rfd.b
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/c/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/c/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..2b732322
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/c/META-INF/MANIFEST.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: rfd.c
+Bundle-Version: 1.0
+Import-Package: rfd.d
+Export-Package: rfd.c
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/hibernate/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/hibernate/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..1ad8417f
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/hibernate/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: rfd.hibernate
+Bundle-Version: 1.0
+Export-Package: rfd.hibernate;version="1.0"
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/hibernate2/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/hibernate2/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..69f69d20
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/hibernate2/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: rfd.hibernate
+Bundle-Version: 2.0
+Export-Package: rfd.hibernate;version="2.0"
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/spring/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/spring/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..7c8dc593
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/spring/META-INF/MANIFEST.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: rfd.spring
+Bundle-Version: 1.0
+Export-Package: rfd.spring.orm;uses:=rfd.hibernate
+Import-Package: rfd.hibernate
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/web/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/web/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..26dbeeca
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/rfd/web/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: rfd.web
+Bundle-Version: 1.0
+Import-Package: rfd.app
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentOne/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentOne/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..069c59c5
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentOne/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: com.foo.fragment.one
+Bundle-Version: 1.0
+Fragment-Host: com.foo.host;bundle-version="[1.0, 2.0)"
+Export-Package: com.foo.host;version="1.5"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentTwo/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentTwo/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..657c7176
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentTwo/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: com.foo.fragment.two
+Fragment-Host: com.foo.host;bundle-version="[1.0, 2.0)"
+Export-Package: com.foo.fragment.two;version="1.0",com.foo.host.b;version="1.0"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentwithnoexports/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentwithnoexports/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..9367936f
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/fragmentwithnoexports/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: silht.bundles.fragmentwithnoexports
+Bundle-ManifestVersion: 2
+Bundle-Name: Fragment bundle with no exports
+Bundle-Version: 1.0
+Fragment-Host: silht.bundles.noexports
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/host/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/host/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..c2418555
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/host/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: com.foo.host
+Bundle-Version: 1.2
+Export-Package: com.foo.host;version="1.0",com.foo.host.a;version="1.0",com.foo.host.b;version="1.0"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/multi-version-export/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/multi-version-export/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..2b039ebb
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/multi-version-export/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: multi.version.export
+Bundle-Version: 1.0
+Export-Package: a;version=1.0,a;version=2.0,a;version=3.0
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/noexports/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/noexports/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..028ae763
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/noexports/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-SymbolicName: silht.bundles.noexports
+Bundle-ManifestVersion: 2
+Bundle-Name: Bundle with no exports
+Bundle-Version: 1.0
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/overlapper/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/overlapper/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..24701490
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/bundles/overlapper/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: overlapper
+Export-Package: javax.crypto.spec,javax.imageio,javax.imageio.event,overlapper.pkg
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/com.foo.libd b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/com.foo.libd
new file mode 100644
index 00000000..32df9f80
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/com.foo.libd
@@ -0,0 +1,3 @@
+Library-SymbolicName: com.foo
+Library-Version: 1.0
+Import-Bundle: com.foo.host, com.foo.fragment.one, com.foo.fragment.two \ No newline at end of file
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/missing.optional.bundle.libd b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/missing.optional.bundle.libd
new file mode 100644
index 00000000..b96a3fd0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/missing.optional.bundle.libd
@@ -0,0 +1,3 @@
+Library-SymbolicName: missing.optional.bundle
+Library-Version: 1.0
+Import-Bundle: no.such.bundle;resolution:=optional
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/spring.libd b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/spring.libd
new file mode 100644
index 00000000..2803caf7
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/silht/libraries/spring.libd
@@ -0,0 +1,5 @@
+Library-SymbolicName: org.springframework
+Library-Version: 2.5.1
+Import-Bundle: org.springframework.core;version="[2.5.6.SEC01,2.5.6.SEC01]",
+ org.springframework.beans;version="[2.5.6.SEC01,2.5.6.SEC01]"
+ \ No newline at end of file
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/p/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/p/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..6e96a65b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/p/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.dependent.p
+Bundle-Version: 1.0
+Import-Package: q,r;version="[1.1,1.2)",s
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/q/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/q/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..7be90f52
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/q/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.dependent.q
+Bundle-Version: 1.0
+Import-Package: r;version="[1.0, 1.1)",s
+Export-Package: q;version="1.0";uses:="r,s"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/r1/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/r1/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..ec7f492b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/r1/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.dependent.r
+Bundle-Version: 1.0
+Export-Package: r;version="1.0"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/r2/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/r2/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..c80a5c67
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/r2/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.dependent.r
+Bundle-Version: 1.1
+Export-Package: r;version="1.1"
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/s1/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/s1/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..bad89e8c
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/s1/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.dependent.s
+Bundle-Version: 1.0
+Export-Package: s;version="1.0"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/s2/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/s2/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..3a657596
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/dependent/bundles/s2/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.dependent.s
+Bundle-Version: 1.1
+Export-Package: s;version="1.1"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/p/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/p/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..6540f1d9
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/p/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.install.p
+Bundle-Version: 1.0
+Import-Package: q,r;version="[1.1,1.2]",s
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/q/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/q/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..e7d18496
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/q/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.install.q
+Bundle-Version: 1.0
+Import-Package: r;version="[1.0, 1.1]",s
+Export-Package: q;version="1.0";uses:="r,s"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/r1/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/r1/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..cd69b1f0
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/r1/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.install.r
+Bundle-Version: 1.0
+Export-Package: r;version="1.0"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/r2/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/r2/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..556fc78f
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/r2/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.install.r
+Bundle-Version: 1.1
+Export-Package: r;version="1.1"
+
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/s1/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/s1/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..bfb6f6af
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/s1/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.install.s
+Bundle-Version: 1.0
+Export-Package: s;version="1.0"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/s2/META-INF/MANIFEST.MF b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/s2/META-INF/MANIFEST.MF
new file mode 100644
index 00000000..b4b57cfb
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/install/bundles/s2/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: uat.install.s
+Bundle-Version: 1.1
+Export-Package: s;version="1.1"
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmA.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmA.jar
new file mode 100644
index 00000000..55fe9332
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmA.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmB.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmB.jar
new file mode 100644
index 00000000..0ad7b28b
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmB.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmC.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmC.jar
new file mode 100644
index 00000000..aaf6e54a
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmC.jar
Binary files differ
diff --git a/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmD.jar b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmD.jar
new file mode 100644
index 00000000..b269ce32
--- /dev/null
+++ b/org.eclipse.virgo.kernel.userregion/src/test/resources/uat/transitiveconstraint/tmD.jar
Binary files differ

Back to the top