/* * #%L * Wisdom-Framework * %% * Copyright (C) 2013 - 2015 Wisdom Framework * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ package org.wisdom.bnd.plugins; import aQute.bnd.header.Attrs; import aQute.bnd.osgi.Analyzer; import aQute.bnd.osgi.Descriptors; import aQute.bnd.osgi.Jar; import aQute.bnd.osgi.Packages; import aQute.service.reporter.Reporter; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import org.junit.Test; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** * Check the {@link ImportedPackageRangeFixer}. */ public class ImportedPackageRangeFixerTest { private static final String GUAVA_VERSION = "14.0.0"; @Test public void testEmpty() throws Exception { ImportedPackageRangeFixer fixer = new ImportedPackageRangeFixer(); Reporter reporter = mock(Reporter.class); fixer.setReporter(reporter); fixer.setProperties(Collections.<String, String>emptyMap()); Analyzer analyzer = new Analyzer(); fixer.analyzeJar(analyzer); } @Test public void testWithoutReferred() throws Exception { ImportedPackageRangeFixer fixer = new ImportedPackageRangeFixer(); Reporter reporter = mock(Reporter.class); fixer.setReporter(reporter); fixer.setProperties(Collections.<String, String>emptyMap()); Analyzer analyzer = new Analyzer(); analyzer.setClasspath(new Jar[] { new Jar("foo") }); fixer.analyzeJar(analyzer); } @Test public void testWithReferredWithoutClasspath() throws Exception { ImportedPackageRangeFixer fixer = new ImportedPackageRangeFixer(); Reporter reporter = mock(Reporter.class); fixer.setReporter(reporter); fixer.setProperties(Collections.<String, String>emptyMap()); Analyzer analyzer = mock(Analyzer.class); final Packages packages = new Packages(); Descriptors descriptors = new Descriptors(); packages.put(descriptors.getPackageRef("com.acme")); when(analyzer.getReferred()).thenReturn(packages); fixer.analyzeJar(analyzer); final Map.Entry<Descriptors.PackageRef, Attrs> actual = foundByPackageName(analyzer, "com.acme"); assertThat(actual).isNotNull(); assertThat(actual.getValue()).isEmpty(); } @Test public void testWithReferredMatchingButNotInClasspath() throws Exception { ImportedPackageRangeFixer fixer = new ImportedPackageRangeFixer(); Reporter reporter = mock(Reporter.class); fixer.setReporter(reporter); fixer.setProperties(Collections.<String, String>emptyMap()); Analyzer analyzer = mock(Analyzer.class); final Packages packages = new Packages(); Descriptors descriptors = new Descriptors(); packages.put(descriptors.getPackageRef("com.acme")); packages.put(descriptors.getPackageRef("com.google.common.collections")); when(analyzer.getReferred()).thenReturn(packages); fixer.analyzeJar(analyzer); Map.Entry<Descriptors.PackageRef, Attrs> actual = foundByPackageName(analyzer, "com.acme"); assertThat(actual).isNotNull(); assertThat(actual.getValue()).isEmpty(); actual = foundByPackageName(analyzer, "com.google.common.collections"); assertThat(actual).isNotNull(); assertThat(actual.getValue()).isEmpty(); } @Test public void testWithReferredMatchingAndInClasspath() throws Exception { ImportedPackageRangeFixer fixer = new ImportedPackageRangeFixer(); Reporter reporter = mock(Reporter.class); fixer.setReporter(reporter); fixer.setProperties(Collections.<String, String>emptyMap()); Analyzer analyzer = mock(Analyzer.class); final Packages packages = new Packages(); Descriptors descriptors = new Descriptors(); packages.put(descriptors.getPackageRef("com.acme")); packages.put(descriptors.getPackageRef("com.google.common.collections")); packages.put(descriptors.getPackageRef("org.joda.time")); when(analyzer.getReferred()).thenReturn(packages); when(analyzer.getClasspath()).thenReturn(ImmutableList.of(createJarFromClasspath("guava"), createJarFromClasspath("joda-time"))); fixer.analyzeJar(analyzer); // First package, not in classpath Map.Entry<Descriptors.PackageRef, Attrs> actual = foundByPackageName(analyzer, "com.acme"); assertThat(actual).isNotNull(); assertThat(actual.getValue()).isEmpty(); // Second package in classpath and range fixed by internal file actual = foundByPackageName(analyzer, "com.google.common.collections"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isNotNull().contains(GUAVA_VERSION).doesNotContain(")"); // Third package in classpath, range not fixed actual = foundByPackageName(analyzer, "org.joda.time"); assertThat(actual).isNotNull(); assertThat(actual.getValue()).isEmpty(); } @Test public void testWithExternalFile() throws Exception { ImportedPackageRangeFixer fixer = new ImportedPackageRangeFixer(); Reporter reporter = mock(Reporter.class); fixer.setReporter(reporter); fixer.setProperties(ImmutableMap.of("file", new File("src/test/resources/versions.properties").getAbsolutePath())); Analyzer analyzer = mock(Analyzer.class); final Packages packages = new Packages(); Descriptors descriptors = new Descriptors(); packages.put(descriptors.getPackageRef("com.acme")); packages.put(descriptors.getPackageRef("com.google.common.collections")); packages.put(descriptors.getPackageRef("org.joda.time")); packages.put(descriptors.getPackageRef("org.apache.felix.ipojo.manipulator")); packages.put(descriptors.getPackageRef("org.mockito")); when(analyzer.getReferred()).thenReturn(packages); when(analyzer.getClasspath()).thenReturn(ImmutableList.of( createJarFromClasspath("guava"), createJarFromClasspath("joda-time"), createJarFromClasspath("org.apache.felix.ipojo.manipulator"), createJarFromClasspath("mockito"))); fixer.analyzeJar(analyzer); // First package, not in classpath Map.Entry<Descriptors.PackageRef, Attrs> actual = foundByPackageName(analyzer, "com.acme"); assertThat(actual).isNotNull(); assertThat(actual.getValue()).isEmpty(); // Second package in classpath and range fixed by internal file actual = foundByPackageName(analyzer, "com.google.common.collections"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isNotNull().contains(GUAVA_VERSION).doesNotContain(")"); // Third package in classpath, set explicitly by external file (no upper bound) actual = foundByPackageName(analyzer, "org.joda.time"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).doesNotContain("[").doesNotContain(")"); // Fourth package in classpath, range set explicitly by external file actual = foundByPackageName(analyzer, "org.apache.felix.ipojo.manipulator"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isEqualToIgnoringCase("[1.12, 3)"); // Fifth package in classpath, customize from external file, no upper bound. actual = foundByPackageName(analyzer, "org.mockito"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).doesNotContain("[").doesNotContain(")"); } @Test public void testWithMissingExternalFile() throws Exception { ImportedPackageRangeFixer fixer = new ImportedPackageRangeFixer(); Reporter reporter = mock(Reporter.class); fixer.setReporter(reporter); fixer.setProperties(ImmutableMap.of("file", new File("src/test/resources/missing.properties") .getAbsolutePath())); Analyzer analyzer = mock(Analyzer.class); final Packages packages = new Packages(); Descriptors descriptors = new Descriptors(); packages.put(descriptors.getPackageRef("com.acme")); packages.put(descriptors.getPackageRef("com.google.common.collections")); packages.put(descriptors.getPackageRef("org.joda.time")); packages.put(descriptors.getPackageRef("org.apache.felix.ipojo.manipulator")); packages.put(descriptors.getPackageRef("org.mockito")); when(analyzer.getReferred()).thenReturn(packages); when(analyzer.getClasspath()).thenReturn(ImmutableList.of( createJarFromClasspath("guava"), createJarFromClasspath("joda-time"), createJarFromClasspath("org.apache.felix.ipojo.manipulator"), createJarFromClasspath("mockito"))); fixer.analyzeJar(analyzer); // First package, not in classpath Map.Entry<Descriptors.PackageRef, Attrs> actual = foundByPackageName(analyzer, "com.acme"); assertThat(actual).isNotNull(); assertThat(actual.getValue()).isEmpty(); // Second package in classpath and range fixed by internal file actual = foundByPackageName(analyzer, "com.google.common.collections"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isNotNull().contains(GUAVA_VERSION).doesNotContain(")"); // Third package in classpath, but no external file actual = foundByPackageName(analyzer, "org.joda.time"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isNull(); // Fourth package in classpath, but no external file actual = foundByPackageName(analyzer, "org.apache.felix.ipojo.manipulator"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isNull(); // Fifth package in classpath, but no external file actual = foundByPackageName(analyzer, "org.mockito"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isNull(); } @Test public void testWhenPrefixSortingIsRequired() throws Exception { ImportedPackageRangeFixer fixer = new ImportedPackageRangeFixer(); Reporter reporter = mock(Reporter.class); fixer.setReporter(reporter); fixer.setProperties(ImmutableMap.of("file", new File("src/test/resources/sorting.properties").getAbsolutePath ())); Analyzer analyzer = mock(Analyzer.class); final Packages packages = new Packages(); Descriptors descriptors = new Descriptors(); packages.put(descriptors.getPackageRef("com.acme")); packages.put(descriptors.getPackageRef("com.google.common.collections")); packages.put(descriptors.getPackageRef("com.google.common.reflect")); packages.put(descriptors.getPackageRef("org.apache.felix.ipojo.manipulator")); packages.put(descriptors.getPackageRef("org.apache.felix.ipojo.metadata")); packages.put(descriptors.getPackageRef("org.apache.felix.ipojo.handlers")); when(analyzer.getReferred()).thenReturn(packages); when(analyzer.getClasspath()).thenReturn(ImmutableList.of( createJarFromClasspath("guava"), createJarFromClasspath("org.apache.felix.ipojo.manipulator"), createJarFromClasspath("org.apache.felix.ipojo.metadata"))); fixer.analyzeJar(analyzer); // First package, not in classpath Map.Entry<Descriptors.PackageRef, Attrs> actual = foundByPackageName(analyzer, "com.acme"); assertThat(actual).isNotNull(); assertThat(actual.getValue()).isEmpty(); // Second package in classpath and range fixed by internal file but overridden by external file actual = foundByPackageName(analyzer, "com.google.common.collections"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isEqualToIgnoringCase("14.0.0"); // Third package in classpath and range fixed by internal file actual = foundByPackageName(analyzer, "com.google.common.reflect"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).doesNotContain("[").doesNotContain(")").contains(GUAVA_VERSION); // Fourth package in classpath, range set explicitly by external file actual = foundByPackageName(analyzer, "org.apache.felix.ipojo.manipulator"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isEqualToIgnoringCase("[1.12, 2)"); // Fifth package in classpath, range set explicitly by external file actual = foundByPackageName(analyzer, "org.apache.felix.ipojo.metadata"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isEqualToIgnoringCase("1.0.0"); actual = foundByPackageName(analyzer, "org.apache.felix.ipojo.handlers"); assertThat(actual).isNotNull(); assertThat(actual.getValue().get("version")).isEqualToIgnoringCase("1.12.1"); } private Jar createJarFromClasspath(String name) throws IOException { List<URL> list = new ArrayList<>(); if (this.getClass().getClassLoader() instanceof URLClassLoader) { URL[] urls = ((URLClassLoader) this.getClass().getClassLoader()).getURLs(); for (URL url : urls) { list.add(url); if (url.toExternalForm().contains(name)) { return new Jar(url.getFile(), url.getPath()); } } } throw new IllegalArgumentException("Cannot find " + name + " in classpath - " + list); } private Map.Entry<Descriptors.PackageRef, Attrs> foundByPackageName(Analyzer analyzer, String name) { for (Map.Entry<Descriptors.PackageRef, Attrs> entry : analyzer.getReferred().entrySet()) { if (name.equals(entry.getKey().getFQN())) { return entry; } } throw new IllegalArgumentException("Cannot find " + name + " in referred packages"); } }