Repository: karaf Updated Branches: refs/heads/master 23023e72d -> 41fc57fdc
[KARAF-4411] FeatureResolver: spring-dm-web feature installs Spring ver 3.1.4 and 3.2.14 at the same time Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/41fc57fd Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/41fc57fd Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/41fc57fd Branch: refs/heads/master Commit: 41fc57fdcd0697d5dad3a49a56779c310b6c629b Parents: 23023e7 Author: Guillaume Nodet <[email protected]> Authored: Wed Mar 16 09:53:55 2016 +0100 Committer: Guillaume Nodet <[email protected]> Committed: Fri Apr 1 17:12:54 2016 +0200 ---------------------------------------------------------------------- .../features/internal/region/Subsystem.java | 2 +- .../region/FeaturesDependenciesTest.java | 212 +++++++++++++++++++ .../karaf/features/internal/region/data8/a1.mf | 5 + .../karaf/features/internal/region/data8/a2.mf | 4 + .../karaf/features/internal/region/data8/b1.mf | 6 + .../karaf/features/internal/region/data8/b2.mf | 6 + .../features/internal/region/data8/features.xml | 91 ++++++++ .../internal/region/data8/spring-core-3.1.4.mf | 5 + .../internal/region/data8/spring-core-3.2.14.mf | 5 + .../internal/region/data8/spring-core-4.0.7.mf | 5 + .../region/data8/spring-osgi-core-1.2.1.mf | 5 + 11 files changed, 345 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java index 09cae6b..d8863e5 100644 --- a/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java +++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java @@ -284,7 +284,7 @@ public class Subsystem extends ResourceImpl { while (!ss.isAcceptDependencies()) { ss = ss.getParent(); } - ss.requireFeature(dep.getName(), dep.getVersion(), this.mandatory && (mandatory && !dep.isDependency())); + ss.requireFeature(dep.getName(), dep.getVersion(), false); } for (Conditional cond : feature.getConditional()) { Feature fcond = cond.asFeature(); http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/test/java/org/apache/karaf/features/internal/region/FeaturesDependenciesTest.java ---------------------------------------------------------------------- diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/region/FeaturesDependenciesTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/region/FeaturesDependenciesTest.java new file mode 100644 index 0000000..db990bd --- /dev/null +++ b/features/core/src/test/java/org/apache/karaf/features/internal/region/FeaturesDependenciesTest.java @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +package org.apache.karaf.features.internal.region; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.felix.resolver.ResolverImpl; +import org.apache.karaf.features.FeaturesService; +import org.apache.karaf.features.Slf4jResolverLog; +import org.apache.karaf.features.internal.service.RepositoryImpl; +import org.apache.karaf.features.internal.support.TestDownloadManager; +import org.junit.Test; +import org.osgi.framework.namespace.IdentityNamespace; +import org.osgi.framework.wiring.BundleRevision; +import org.osgi.resource.Capability; +import org.osgi.resource.Resource; +import org.osgi.resource.Wire; +import org.osgi.service.resolver.Resolver; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static org.apache.karaf.features.internal.util.MapUtils.addToMapSet; +import static org.junit.Assert.assertEquals; + +public class FeaturesDependenciesTest { + + Logger logger = LoggerFactory.getLogger(FeaturesDependenciesTest.class);; + Resolver resolver = new ResolverImpl(new Slf4jResolverLog(logger)); + + @Test + public void testFeatureDependency1() throws Exception { + doTestFeatureDependency( + new String[] { "f1" }, + new String[] { "a1/1.0.0", "b/2.0.0" } + ); + } + + @Test + public void testFeatureDependency1b() throws Exception { + doTestFeatureDependency( + new String[] { "f1", "dep/[1.0,2.0)"}, + new String[] { "a1/1.0.0", "b/1.0.0" } + ); + } + + @Test + public void testFeatureDependency2() throws Exception { + doTestFeatureDependency( + new String[] { "f2" }, + new String[] { "a1/1.0.0", "b/2.0.0" } + ); + } + + @Test + public void testFeatureDependency2b() throws Exception { + doTestFeatureDependency( + new String[] { "f2", "dep/[1.0,2.0)"}, + new String[] { "a1/1.0.0", "b/1.0.0" } + ); + } + + @Test + public void testFeatureDependency3() throws Exception { + doTestFeatureDependency( + new String[] { "f3" }, + new String[] { "a2/1.0.0" } + ); + } + + @Test + public void testFeatureDependency3b() throws Exception { + doTestFeatureDependency( + new String[] { "f3", "dep/[1.0,2.0)"}, + new String[] { "a2/1.0.0", "b/1.0.0" } + ); + } + + @Test + public void testFeatureDependency4() throws Exception { + doTestFeatureDependency( + new String[] { "f4" }, + new String[] { "a2/1.0.0", "b/2.0.0" } + ); + } + + @Test + public void testFeatureDependency4b() throws Exception { + doTestFeatureDependency( + new String[] { "f4", "dep/[1.0,2.0)"}, + new String[] { "a2/1.0.0", "b/1.0.0" } + ); + } + + @Test + public void testSpring() throws Exception { + doTestFeatureDependency( + new String[] { "spring-dm-web"}, + new String[] { "spring-osgi-core/1.2.1", "spring-core/3.2.14" } + ); + } + + @Test + public void testFeatureDependencyLevel() throws Exception { + doTestFeatureDependency( + new String[] { "tf1" }, + new String[] { "a2/1.0.0" } + ); + } + + private void doTestFeatureDependency(String[] features, String[] bundles) throws Exception { + RepositoryImpl repo = new RepositoryImpl(getClass().getResource("data8/features.xml").toURI()); + + Map<String, Set<String>> requirements = new HashMap<String, Set<String>>(); + for (String feature : features) { + addToMapSet(requirements, "root", feature); + } + + Map<String, Set<String>> expected = new HashMap<String, Set<String>>(); + for (String bundle : bundles) { + addToMapSet(expected, "root", bundle); + } + + SubsystemResolver resolver = new SubsystemResolver(this.resolver, new TestDownloadManager(getClass(), "data8")); + resolver.prepare(Arrays.asList(repo.getFeatures()), + requirements, + Collections.<String, Set<BundleRevision>>emptyMap()); + resolver.resolve(Collections.<String>emptySet(), + FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE, + null, null, null); + + verify(resolver, expected); + } + + private void verify(SubsystemResolver resolver, Map<String, Set<String>> expected) { + Map<String, Set<String>> mapping = getBundleNamesPerRegions(resolver); + if (!expected.equals(mapping)) { + dumpBundles(resolver); + dumpWiring(resolver); + assertEquals("Resolution failed", expected, mapping); + } + } + + private void dumpBundles(SubsystemResolver resolver) { + System.out.println("Bundle mapping"); + Map<String, Set<Resource>> bundles = resolver.getBundlesPerRegions(); + for (Map.Entry<String, Set<Resource>> entry : bundles.entrySet()) { + System.out.println(" " + entry.getKey()); + for (Resource b : entry.getValue()) { + System.out.println(" " + b); + } + } + } + + private Map<String, Set<String>> getBundleNamesPerRegions(SubsystemResolver resolver) { + Map<String, Set<String>> mapping = new HashMap<String, Set<String>>(); + Map<String, Set<Resource>> bundles = resolver.getBundlesPerRegions(); + for (Map.Entry<String,Set<Resource>> entry : bundles.entrySet()) { + for (Resource r : entry.getValue()) { + addToMapSet(mapping, entry.getKey(), r.toString()); + } + } + return mapping; + } + + + private void dumpWiring(SubsystemResolver resolver) { + System.out.println("Wiring"); + Map<Resource, List<Wire>> wiring = resolver.getWiring(); + List<Resource> resources = new ArrayList<Resource>(wiring.keySet()); + Collections.sort(resources, new Comparator<Resource>() { + @Override + public int compare(Resource o1, Resource o2) { + return getName(o1).compareTo(getName(o2)); + } + }); + for (Resource resource : resources) { + System.out.println(" " + getName(resource)); + for (Wire wire : wiring.get(resource)) { + System.out.println(" " + wire); + } + } + } + + private String getName(Resource resource) { + Capability cap = resource.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE).get(0); + return cap.getAttributes().get(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE) + ": " + + cap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE) + "/" + + cap.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE); + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/a1.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/a1.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/a1.mf new file mode 100644 index 0000000..743582a --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/a1.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: a1 +Bundle-Version: 1.0.0 +Import-Package: b http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/a2.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/a2.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/a2.mf new file mode 100644 index 0000000..87199d5 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/a2.mf @@ -0,0 +1,4 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: a2 +Bundle-Version: 1.0.0 http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/b1.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/b1.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/b1.mf new file mode 100644 index 0000000..4dd6873 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/b1.mf @@ -0,0 +1,6 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: b +Bundle-Version: 1.0.0 +Export-Package: b;version=1.0 + http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/b2.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/b2.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/b2.mf new file mode 100644 index 0000000..9d78fc7 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/b2.mf @@ -0,0 +1,6 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: b +Bundle-Version: 2.0.0 +Export-Package: b;version=2.0 + http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/features.xml ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/features.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/features.xml new file mode 100644 index 0000000..5794994 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/features.xml @@ -0,0 +1,91 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. + +--> +<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0"> + + <feature name="f1"> + <feature dependency="true">dep</feature> + <bundle>a1</bundle> + </feature> + + <feature name="f2"> + <feature dependency="false">dep</feature> + <bundle>a1</bundle> + </feature> + + <feature name="f3"> + <feature dependency="true">dep</feature> + <bundle>a2</bundle> + </feature> + + <feature name="f4"> + <feature dependency="false">dep</feature> + <bundle>a2</bundle> + </feature> + + <feature name="dep" version="1.0"> + <bundle>b1</bundle> + </feature> + + <feature name="dep" version="2.0"> + <bundle>b2</bundle> + </feature> + + <feature name="spring-dm-web" version="1.2.1"> + <feature>spring-dm</feature> + <feature version="[2.5.6,4)">spring-web</feature> + </feature> + + <feature name="spring-dm" version="1.2.1"> + <feature version="[2.5.6,4)">spring</feature> + <bundle>spring-osgi-core-1.2.1</bundle> + </feature> + + <feature name="spring-web" version="3.1.4"> + <feature version="[3.1.4,3.2)">spring</feature> + </feature> + <feature name="spring" version="3.1.4"> + <bundle>spring-core-3.1.4</bundle> + </feature> + + <feature name="spring-web" version="3.2.14"> + <feature version="[3.2.14,3.3)">spring</feature> + </feature> + <feature name="spring" version="3.2.14"> + <bundle>spring-core-3.2.14</bundle> + </feature> + + <feature name="spring-web" version="4.0.7"> + <feature version="[4.0.7,4.1)">spring</feature> + </feature> + <feature name="spring" version="4.0.7"> + <bundle>spring-core-4.0.7</bundle> + </feature> + + <feature name="tf1"> + <feature>tf2</feature> + </feature> + <feature name="tf2"> + <feature>tf3</feature> + </feature> + <feature name="tf3"> + <bundle>a2</bundle> + </feature> + + +</features> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-3.1.4.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-3.1.4.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-3.1.4.mf new file mode 100644 index 0000000..e996aa6 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-3.1.4.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: spring-core +Bundle-Version: 3.1.4 +Export-Package: org.springframework.beans;version=3.1.4 http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-3.2.14.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-3.2.14.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-3.2.14.mf new file mode 100644 index 0000000..89139c6 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-3.2.14.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: spring-core +Bundle-Version: 3.2.14 +Export-Package: org.springframework.beans;version=3.2.14 http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-4.0.7.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-4.0.7.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-4.0.7.mf new file mode 100644 index 0000000..8af8738 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-core-4.0.7.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: spring-core +Bundle-Version: 4.0.7 +Export-Package: org.springframework.beans;version=4.0.7 http://git-wip-us.apache.org/repos/asf/karaf/blob/41fc57fd/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-osgi-core-1.2.1.mf ---------------------------------------------------------------------- diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-osgi-core-1.2.1.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-osgi-core-1.2.1.mf new file mode 100644 index 0000000..d3cd8b2 --- /dev/null +++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data8/spring-osgi-core-1.2.1.mf @@ -0,0 +1,5 @@ +Manifest-Version: 1 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: spring-osgi-core +Bundle-Version: 1.2.1 +Import-Package: org.springframework.beans;version="[2.5.6,4.0)"
