/* * 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 WARRANTIESOR 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.aries.application.resolver.obr.impl; import static junit.framework.Assert.assertEquals; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.aries.application.resolver.obr.OBRAriesResolver; import org.apache.aries.unittest.mocks.Skeleton; import org.apache.felix.bundlerepository.Capability; import org.apache.felix.bundlerepository.Reason; import org.apache.felix.bundlerepository.RepositoryAdmin; import org.apache.felix.bundlerepository.Requirement; import org.apache.felix.bundlerepository.Resolver; import org.apache.felix.bundlerepository.Resource; import org.junit.Before; import org.junit.Test; import org.osgi.framework.Version; public class AriesResolverTest extends OBRAriesResolver { Resolver resolver; ResolverMock resolverMock; public AriesResolverTest() { super(Skeleton.newMock(RepositoryAdmin.class)); } static class ResolverMock { private final List<Resource> resources = new ArrayList<Resource>(); private final Map<String, List<Requirement>> requirements = new HashMap<String, List<Requirement>>(); private String curRes; private ResourceMock curResMock; private RequirementMock curReqMock; public Reason[] getReason(Resource r) { Requirement[] reqs = requirements.get(r.getSymbolicName() + "_" + r.getVersion()).toArray(new Requirement[0]); Reason[] reasons = new Reason[reqs.length]; int i=0; for (Requirement req : reqs) { reasons[i++] = new ReasonMock(r, req); } return reasons; } public Resource[] getRequiredResources() { return resources.toArray(new Resource[0]); } public ResolverMock res(String name, String version) { curRes = name + "_" + version; curResMock = new ResourceMock(name,version); resources.add(Skeleton.newMock(curResMock, Resource.class)); requirements.put(curRes, new ArrayList<Requirement>()); return this; } public ResolverMock optional() { curReqMock.optional = true; return this; } public ResolverMock req(String name) { // requirements are based on String, so that we have valid equals and hashCode implementations curReqMock = new RequirementMock(name); requirements.get(curRes).add(Skeleton.newMock(curReqMock, Requirement.class)); curResMock.addCapability(name); return this; } } static class CapabilityMock { private final String cap; CapabilityMock(String cap) { this.cap = cap; } @Override public String toString() { return cap; } } static class RequirementMock { private final String req; public boolean optional = false; RequirementMock(String req) { this.req = req; } public boolean isSatisfied(Capability c) { return c.toString().equals(req); } public boolean isOptional() { return optional; } } static class ReasonMock implements Reason{ private final Resource res; private final Requirement req; ReasonMock (Resource res, Requirement req) { this.res = res; this.req = req; } public Resource getResource() { return this.res; } public Requirement getRequirement() { return this.req; } } static class ResourceMock { private final String name; private final Version version; private final List<Capability> capabilities; ResourceMock(String name, String version) { this.name = name; this.version = new Version(version); capabilities = new ArrayList<Capability>(); } public void addCapability(String cap) { capabilities.add(Skeleton.newMock(new CapabilityMock(cap), Capability.class)); } public Capability[] getCapabilities() { return capabilities.toArray(new Capability[0]); } public Version getVersion() { return version; } public String getSymbolicName() { return name; } } @Before public void before() { resolverMock = new ResolverMock(); resolver = Skeleton.newMock(resolverMock, Resolver.class); } @Test public void testIncompatible() { resolverMock .res("com.ibm.test", "0.0.0") .req("a") .req("b") .res("com.ibm.test", "1.0.0") .req("a") .req("c"); List<Resource> res = retrieveRequiredResources(resolver); assertEquals(2, res.size()); assertResource(res.get(0), "com.ibm.test", "0.0.0"); assertResource(res.get(1), "com.ibm.test", "1.0.0"); } @Test public void testLeftRedundant() { resolverMock .res("com.ibm.test", "0.0.0") .req("a") .req("b") .res("com.ibm.test", "1.0.0") .req("a") .req("b") .req("c"); List<Resource> res = retrieveRequiredResources(resolver); assertEquals(1, res.size()); assertResource(res.get(0), "com.ibm.test", "1.0.0"); } @Test public void testRightRedundant() { resolverMock .res("com.ibm.test", "0.0.0") .req("a") .req("b") .req("c") .res("com.ibm.test", "1.0.0") .req("a") .req("c"); List<Resource> res = retrieveRequiredResources(resolver); assertEquals(1, res.size()); assertResource(res.get(0), "com.ibm.test", "0.0.0"); } @Test public void testEquivalent() { resolverMock .res("com.ibm.test", "0.0.0") .req("a") .req("b") .res("com.ibm.test", "2.0.0") .req("a") .req("b") .res("com.ibm.test", "1.0.0") .req("a") .req("b"); List<Resource> res = retrieveRequiredResources(resolver); assertEquals(1, res.size()); assertResource(res.get(0), "com.ibm.test", "2.0.0"); } @Test public void testEquivalentWithOptionals() { // 1.1.0 and 1.0.0 are incompatible if we leave aside that "c" is optional. // "bundle" is the downgrade dependency on 1.0.0, "c" is the optional service requirement for the CommentService resolverMock .res("com.ibm.test", "1.0.0") .req("a") .req("b") .req("bundle") .res("com.ibm.test", "1.1.0") .req("a") .req("b") .req("c").optional(); List<Resource> res = retrieveRequiredResources(resolver); assertEquals(1, res.size()); assertResource(res.get(0), "com.ibm.test", "1.0.0"); } private void assertResource(Resource r, String name, String version) { assertEquals(name, r.getSymbolicName()); assertEquals(version, r.getVersion().toString()); } }