| /******************************************************************************* |
| * 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 org.eclipse.virgo.kernel.artifact.bundle.BundleBridge; |
| import org.eclipse.virgo.kernel.artifact.library.LibraryBridge; |
| 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.medic.test.eventlog.LoggedEvent; |
| import org.eclipse.virgo.medic.test.eventlog.MockEventLogger; |
| import org.eclipse.virgo.repository.*; |
| import org.eclipse.virgo.util.osgi.manifest.*; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.osgi.framework.Version; |
| import org.springframework.core.io.FileSystemResource; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.StringReader; |
| import java.util.*; |
| |
| import static java.util.Arrays.asList; |
| import static java.util.Collections.emptyList; |
| import static java.util.Collections.singletonList; |
| import static org.easymock.EasyMock.*; |
| import static org.eclipse.virgo.kernel.userregion.internal.TestUtils.fromBndPlatform; |
| import static org.junit.Assert.*; |
| import static org.springframework.core.io.support.PropertiesLoaderUtils.loadProperties; |
| |
| public class ImportExpansionHandlerTests { |
| |
| private StubRepository repository = new StubRepository(); |
| |
| private static Set<String> packagesExportedBySystemBundle = new HashSet<>(); |
| |
| static { |
| packagesExportedBySystemBundle.add("javax.crypto.spec"); |
| packagesExportedBySystemBundle.add("javax.imageio"); |
| packagesExportedBySystemBundle.add("javax.imageio.event"); |
| } |
| |
| @Before |
| public void populateRepository() throws ArtifactGenerationException, IOException { |
| BundleBridge bundleBridge = new BundleBridge(new StubHashGenerator()); |
| LibraryBridge libraryBridge = new LibraryBridge(new StubHashGenerator()); |
| |
| Properties gradleProperties = loadProperties(new FileSystemResource("../../gradle.properties")); |
| |
| this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(fromBndPlatform("oevm.org.springframework.core_" + |
| gradleProperties.getProperty("springframeworkVersion") + ".jar"))); |
| this.repository.addArtifactDescriptor(bundleBridge.generateArtifactDescriptor(fromBndPlatform("oevm.org.springframework.beans_" + |
| gradleProperties.getProperty("springframeworkVersion") + ".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/fragmentThree"))); |
| 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<>(); |
| |
| ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks); |
| expect(bundleImport.getBundleSymbolicName()).andReturn("oevm.org.springframework.core").atLeastOnce(); |
| expect(bundleImport.getVersion()).andReturn(new VersionRange("[5,6)")).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<>(), singletonList(bundleImport), bundleManifest); |
| |
| verifyMocks(mocks); |
| |
| assertTrue(bundleManifest.getImportPackage().getImportedPackages().size() > 19); |
| |
| List<ImportedPackage> packageImports = bundleManifest.getImportPackage().getImportedPackages(); |
| for (ImportedPackage packageImport : packageImports) { |
| Map<String, String> attributes = packageImport.getAttributes(); |
| assertEquals("oevm.org.springframework.core", attributes.get("bundle-symbolic-name")); |
| assertEquals(new VersionRange("[5.1.11.RELEASE,5.1.11.RELEASE]"), new VersionRange(attributes.get("bundle-version"))); |
| } |
| } |
| |
| @Test |
| public void basicImportLibrary() throws UnableToSatisfyDependenciesException { |
| |
| List<Object> mocks = new ArrayList<>(); |
| |
| ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks); |
| |
| expect(libraryImport.getLibrarySymbolicName()).andReturn("org.springframework").atLeastOnce(); |
| expect(libraryImport.getVersion()).andReturn(new VersionRange("[5,6)")).atLeastOnce(); |
| expect(libraryImport.getResolution()).andReturn(Resolution.MANDATORY).anyTimes(); |
| |
| ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger()); |
| |
| replayMocks(mocks); |
| |
| BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest(); |
| |
| handler.expandImports(singletonList(libraryImport), emptyList(), bundleManifest); |
| |
| verifyMocks(mocks); |
| |
| assertTrue(bundleManifest.getImportPackage().getImportedPackages().size() > 33); |
| |
| List<ImportedPackage> packageImports = bundleManifest.getImportPackage().getImportedPackages(); |
| for (ImportedPackage packageImport : packageImports) { |
| Map<String, String> attributes = packageImport.getAttributes(); |
| if (packageImport.getPackageName().startsWith("org.springframework.beans")) { |
| assertEquals("oevm.org.springframework.beans", attributes.get("bundle-symbolic-name")); |
| } else { |
| assertEquals("oevm.org.springframework.core", attributes.get("bundle-symbolic-name")); |
| } |
| assertEquals(new VersionRange("[5.1.11.RELEASE,5.1.11.RELEASE]"), new VersionRange(attributes.get("bundle-version"))); |
| } |
| } |
| |
| @Test |
| public void basicImportFragmentBundle() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(emptyList(), singletonList(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 |
| public void basicImportFragmentBundleSpecifyingExactBundleVersionRange() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks); |
| expect(bundleImport.getBundleSymbolicName()).andReturn("com.foo.fragment.two").atLeastOnce(); |
| expect(bundleImport.getVersion()).andReturn(new VersionRange("[3,3]")).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(emptyList(), singletonList(bundleImport), bundleManifest); |
| |
| verifyMocks(mocks); |
| } |
| |
| @Test |
| public void basicImportFragmentBundleWithNoFragmentHostBundleVersion() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks); |
| expect(bundleImport.getBundleSymbolicName()).andReturn("com.foo.fragment.three").atLeastOnce(); |
| expect(bundleImport.getVersion()).andReturn(new VersionRange("[0,3]")).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(emptyList(), singletonList(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("0"), new VersionRange(attributes.get("bundle-version"))); |
| assertEquals("com.foo.fragment.three", packageImport.getPackageName()); |
| assertEquals(VersionRange.createExactRange(new Version("1")), packageImport.getVersion()); |
| } |
| |
| @Test(expected = UnableToSatisfyBundleDependenciesException.class) |
| public void importLibraryReferringToNonExistentBundle() throws UnableToSatisfyDependenciesException, IOException { |
| |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(singletonList(libraryImport), emptyList(), bundleManifest); |
| } |
| |
| @Test |
| public void optionalImportBundle() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(emptyList(), singletonList(bundleImport), bundleManifest); |
| |
| verifyMocks(mocks); |
| |
| assertEquals("" + bundleManifest.getImportPackage().getImportedPackages().size(), 0, |
| bundleManifest.getImportPackage().getImportedPackages().size()); |
| } |
| |
| @Test |
| public void optionalImportLibrary() throws UnableToSatisfyDependenciesException { |
| |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(singletonList(libraryImport), emptyList(), bundleManifest); |
| |
| verifyMocks(mocks); |
| |
| assertEquals(0, bundleManifest.getImportPackage().getImportedPackages().size()); |
| } |
| |
| @Test(expected = UnableToSatisfyDependenciesException.class) |
| public void optionalImportLibraryException() throws UnableToSatisfyDependenciesException { |
| |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(singletonList(libraryImport), emptyList(), bundleManifest); |
| } |
| |
| /** |
| * Test the expansion of the following import: |
| * |
| * Import-Library: com.foo;bundle-version="[1.0,2.0)" |
| */ |
| @Test |
| public void importLibraryWithFragment() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(singletonList(libraryImport), emptyList(), bundleManifest); |
| |
| verifyMocks(mocks); |
| |
| assertImported(bundleManifest, asList("com.foo.host", "com.foo.host.a", "com.foo.host.b", "com.foo.fragment.two"), |
| asList("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<>(); |
| |
| 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(); |
| handler.expandImports(asList(libraryImport1, libraryImport2), emptyList(), |
| bundleManifest); |
| } |
| |
| @Test(expected = UnableToSatisfyDependenciesException.class) |
| public void incompatibleIntersection() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(); |
| handler.expandImports(asList(libraryImport1, libraryImport2), emptyList(), |
| bundleManifest); |
| } |
| |
| @Test(expected = UnableToSatisfyBundleDependenciesException.class) |
| public void disjointImportedPackageAndImportedLibraryVersionRanges() throws UnableToSatisfyDependenciesException, IOException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(singletonList(libraryImport), emptyList(), bundleManifest); |
| } |
| |
| @Test(expected = UnableToSatisfyDependenciesException.class) |
| // TODO review - this test had a missing @Test annotation |
| public void disjointImportedPackageAndImportedBundleVersionRanges() throws UnableToSatisfyDependenciesException, IOException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(emptyList(), singletonList(bundleImport), bundleManifest); |
| } |
| |
| @Test |
| public void packageImportAndImportedBundleVersionRangeIntersection() throws UnableToSatisfyDependenciesException, IOException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks); |
| expect(bundleImport.getBundleSymbolicName()).andReturn("oevm.org.springframework.core").atLeastOnce(); |
| expect(bundleImport.getVersion()).andReturn(new VersionRange("[5,6)")).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=\"[4.5,4.6)\"")); |
| handler.expandImports(emptyList(), singletonList(bundleImport), bundleManifest); |
| |
| verifyMocks(mocks); |
| |
| assertTrue(bundleManifest.getImportPackage().getImportedPackages().size() > 19); |
| } |
| |
| @Test |
| public void packageImportAndImportedLibraryVersionRangeIntersection() throws UnableToSatisfyDependenciesException, IOException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| ImportedLibrary libraryImport = createAndStoreMock(ImportedLibrary.class, mocks); |
| expect(libraryImport.getLibrarySymbolicName()).andReturn("org.springframework").atLeastOnce(); |
| expect(libraryImport.getVersion()).andReturn(new VersionRange("[5,6)")).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=\"[4.5,4.6)\"")); |
| handler.expandImports(singletonList(libraryImport), emptyList(), bundleManifest); |
| |
| verifyMocks(mocks); |
| |
| assertTrue(bundleManifest.getImportPackage().getImportedPackages().size() > 33); |
| } |
| |
| @Test(expected = UnableToSatisfyDependenciesException.class) |
| public void disjointImportedBundleVersionRangeIntersection() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(); |
| |
| handler.expandImports(emptyList(), asList(bundleImport1, bundleImport2), |
| bundleManifest); |
| } |
| |
| @Test |
| public void overlappingBundleAndImportedLibrarys() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| ImportedBundle bundleImport = createAndStoreMock(ImportedBundle.class, mocks); |
| expect(bundleImport.getBundleSymbolicName()).andReturn("oevm.org.springframework.core").atLeastOnce(); |
| expect(bundleImport.getVersion()).andReturn(new VersionRange("[5.1.11,6)")).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("[5.1.11,6)")).atLeastOnce(); |
| expect(libraryImport.getResolution()).andReturn(Resolution.MANDATORY).atLeastOnce(); |
| |
| ImportExpansionHandler handler = new ImportExpansionHandler(repository, packagesExportedBySystemBundle, new MockEventLogger()); |
| |
| replayMocks(mocks); |
| |
| BundleManifest bundleManifest = BundleManifestFactory.createBundleManifest(); |
| |
| handler.expandImports(singletonList(libraryImport), singletonList(bundleImport), |
| bundleManifest); |
| } |
| |
| @Test |
| public void importBundleWithNoExports() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(emptyList(), singletonList(bundleImport), bundleManifest); |
| } |
| |
| @Test |
| public void importBundleWithFragmentWithNoExports() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(emptyList(), |
| asList(hostImportedBundle, fragmentImportedBundle), bundleManifest); |
| assertEquals(0, bundleManifest.getImportPackage().getImportedPackages().size()); |
| } |
| |
| @Test |
| public void importBundleBetweenManifests() throws Exception { |
| List<BundleManifest> manifests = new ArrayList<>(); |
| |
| 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, singletonList("com.foo"), singletonList("1.0.0")); |
| } |
| |
| @Test |
| public void importBundleExportingPackagesExportedBySystemBundle() throws Exception { |
| List<BundleManifest> manifests = new ArrayList<>(); |
| 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, asList("javax.crypto.spec", "javax.imageio", "javax.imageio.event", "overlapper.pkg"), |
| asList("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")); |
| List<LoggedEvent> ur3Events = eventLogger.getEventsWithCodes("UR0003W"); |
| Assert.assertEquals(1, ur3Events.size()); |
| LoggedEvent ur3Event = ur3Events.get(0); |
| Object[] inserts = ur3Event.getInserts(); |
| Assert.assertTrue("Wrong number of inserts.", inserts.length >= 3); |
| Object overlap = inserts[2]; |
| Assert.assertTrue("Insert at index 2 is not a String", overlap instanceof String); |
| String overlapString = (String)overlap; |
| String[] splitOverlap = overlapString.substring(1, overlapString.length()-1).split(", "); |
| Set<String> overlapSet = new HashSet<>(); |
| Collections.addAll(overlapSet, splitOverlap); |
| Assert.assertEquals("Unexpected overlap with system bundle exports", packagesExportedBySystemBundle, overlapSet); |
| } |
| |
| @Test |
| public void importLibraryThatImportsMissingOptionalBundle() throws Exception { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(singletonList(libraryImport), emptyList(), bundleManifest); |
| |
| verifyMocks(mocks); |
| |
| assertEquals(0, bundleManifest.getImportPackage().getImportedPackages().size()); |
| } |
| |
| @Test |
| public void importBundleThatExportsPackageAtMultipleVersions() throws UnableToSatisfyDependenciesException { |
| List<Object> mocks = new ArrayList<>(); |
| |
| 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(emptyList(), singletonList(bundleImport), bundleManifest); |
| |
| verifyMocks(mocks); |
| |
| assertImported(bundleManifest, singletonList("a"), singletonList("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[0]); |
| replay(mocksArray); |
| } |
| |
| private static void verifyMocks(List<Object> mocks) { |
| Object[] mocksArray = mocks.toArray(new Object[0]); |
| 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<>(packages); |
| List<String> expectedVersions = new ArrayList<>(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<>(); |
| |
| @Override |
| public Query createQuery(String key, String value) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public Query createQuery(String key, String value, Map<String, Set<String>> properties) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| 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; |
| } |
| |
| @Override |
| public String getName() { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| 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; |
| |
| 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"; |
| } |
| } |
| } |
| } |