blob: 480df3c6165f850519b33d017335c019f70f02ec [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.osgi.tests.services.resolver;
import java.util.*;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.*;
public class XFriendsInternalResolverTest extends AbstractStateTest {
public static Test suite() {
return new TestSuite(XFriendsInternalResolverTest.class);
}
public XFriendsInternalResolverTest(String name) {
super(name);
}
/**
* Tests the x-friends directive. A bundle should not be allowed to import a package which
* declares an x-friends directive and the importer is not a friend. When a bundle requires
* anther bundle which exports packages which declare an x-friends directive it should not
* have access to the packages unless the requiring bundle is a friend.
* @throws BundleException
*/
public void testXFriends() throws BundleException {
State state = buildEmptyState();
int bundleID = 0;
// test the selection algorithm of the resolver to pick the bundles which
// resolve the largest set of bundles; with fragments using Import-Package
Hashtable manifest = new Hashtable();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.exporter");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.EXPORT_PACKAGE,
"test.exporter.foo1; x-friends:=\"test.importer1, test.requirer1\"," +
"test.exporter.foo2; x-friends:=\"test.importer2, test.requirer2\"," +
"test.exporter.bar1; x-friends:=\"test.importer1, test.requirer1\"," +
"test.exporter.bar2; x-friends:=\"test.importer2, test.requirer2\"");
BundleDescription testExporter = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.importer1");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.IMPORT_PACKAGE,
"test.exporter.foo1," +
"test.exporter.bar1," +
"test.exporter.foo2; resolution:=optional," +
"test.exporter.bar2; resolution:=optional");
BundleDescription testImporter1 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.importer2");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.IMPORT_PACKAGE,
"test.exporter.foo1; resolution:=optional," +
"test.exporter.bar1; resolution:=optional," +
"test.exporter.foo2," +
"test.exporter.bar2");
BundleDescription testImporter2 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.importer3");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.IMPORT_PACKAGE,
"test.exporter.foo1," +
"test.exporter.bar1," +
"test.exporter.foo2; resolution:=optional," +
"test.exporter.bar2; resolution:=optional");
BundleDescription testImporter3 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.requirer1");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE, "test.exporter");
BundleDescription testRequirer1 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.requirer2");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE, "test.exporter");
BundleDescription testRequirer2 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
Dictionary[] props = new Dictionary[] {new Hashtable()};
props[0].put("osgi.resolverMode", "strict");
state.setPlatformProperties(props);
state.addBundle(testExporter);
state.addBundle(testImporter1);
state.addBundle(testImporter2);
state.addBundle(testImporter3);
state.addBundle(testRequirer1);
state.addBundle(testRequirer2);
state.resolve();
// make sure all bundles are resolved that should be
assertTrue("1.0", testExporter.isResolved());
assertTrue("1.1", testImporter1.isResolved());
assertTrue("1.2", testImporter2.isResolved());
assertFalse("1.3", testImporter3.isResolved()); // should not be resolved
assertTrue("1.4", testRequirer1.isResolved());
assertTrue("1.5", testRequirer2.isResolved());
String[] validPackages1 = {"test.exporter.foo1", "test.exporter.bar1"};
String[] validPackages2 = {"test.exporter.foo2", "test.exporter.bar2"};
// make sure the importers only got the packages they are really friends to
ExportPackageDescription[] imported1 = testImporter1.getResolvedImports();
assertTrue("2.0", imported1 != null && imported1.length == 2); // should only have 2 resolved imports
assertTrue("2.1", contains(validPackages1, imported1[0].getName()));
assertTrue("2.2", contains(validPackages1, imported1[1].getName()));
ExportPackageDescription[] imported2 = testImporter2.getResolvedImports();
assertTrue("3.0", imported2 != null && imported2.length == 2); // should only have 2 resolved imports
assertTrue("3.1", contains(validPackages2, imported2[0].getName()));
assertTrue("3.2", contains(validPackages2, imported2[1].getName()));
StateHelper helper = state.getStateHelper();
ExportPackageDescription[] required1 = helper.getVisiblePackages(testRequirer1);
assertTrue("4.0", required1 != null && required1.length == 2); // should only have 2 visible imports
assertTrue("4.1", contains(validPackages1, required1[0].getName()));
assertTrue("4.2", contains(validPackages1, required1[1].getName()));
ExportPackageDescription[] required2 = helper.getVisiblePackages(testRequirer2);
assertTrue("5.0", required2 != null && required2.length == 2); // should only have 2 visible imports
assertTrue("5.1", contains(validPackages2, required2[0].getName()));
assertTrue("5.2", contains(validPackages2, required2[1].getName()));
}
public void testVisiblePackages001() throws BundleException {
State state = buildEmptyState();
int bundleID = 0;
Hashtable manifest = new Hashtable();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "a.base");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.EXPORT_PACKAGE, "a.split.pkg; a.base=split; mandatory:=a.base");
BundleDescription aBase = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "a.extra");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE, "a.base");
manifest.put(Constants.EXPORT_PACKAGE, "a.split.pkg");
BundleDescription aExtra = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "b");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE, "a.extra");
manifest.put(Constants.EXPORT_PACKAGE, "test.base.exporter.require");
BundleDescription b= state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
state.addBundle(aBase);
state.addBundle(aExtra);
state.addBundle(b);
state.resolve();
// make sure all bundles are resolved that should be
assertTrue("1.0", aBase.isResolved());
assertTrue("1.1", aExtra.isResolved());
assertTrue("1.2", b.isResolved());
StateHelper helper = state.getStateHelper();
ExportPackageDescription[] visImporter = helper.getVisiblePackages(b);
assertTrue("2.0", visImporter != null && visImporter.length == 2);
assertEquals("2.1", visImporter[0].getName(), "a.split.pkg");
assertEquals("2.2", visImporter[1].getName(), "a.split.pkg");
BundleDescription exporter1 = visImporter[0].getExporter();
BundleDescription exporter2 = visImporter[1].getExporter();
assertTrue("2.3", exporter1 != exporter2);
assertTrue("2.4", exporter1 == aBase || exporter1 == aExtra);
assertTrue("2.4", exporter2 == aBase || exporter2 == aExtra);
}
public void testVisiblePackages002() throws BundleException {
State state = buildEmptyState();
int bundleID = 0;
Hashtable manifest = new Hashtable();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.base.exporter");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.EXPORT_PACKAGE,
"test.base; base.exporter=split; mandatory:=base.exporter");
BundleDescription baseExporter = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.base.exporter.require");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE, "test.base.exporter");
manifest.put(Constants.EXPORT_PACKAGE,
"test.base; base.exporter.require=split; mandatory:=base.exporter.require");
BundleDescription baseExporterRequire = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.base.exporter.require2");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE,
"test.base.exporter.require");
manifest.put(Constants.EXPORT_PACKAGE, "test.base.exporter.require");
BundleDescription baseExporterRequire2 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.base.importer");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE,
"test.base.exporter.require");
BundleDescription baseImporter = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.base.importer2");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE, "test.base.exporter.require2");
manifest.put(Constants.EXPORT_PACKAGE, "test.base");
BundleDescription baseImporter2 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "test.base.importer3");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.IMPORT_PACKAGE, "test.base; bundle-symbolic-name=test.base.importer2");
BundleDescription baseImporter3 = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
Dictionary[] props = new Dictionary[] {new Hashtable()};
props[0].put("osgi.resolverMode", "strict");
state.setPlatformProperties(props);
state.addBundle(baseExporter);
state.addBundle(baseExporterRequire);
state.addBundle(baseExporterRequire2);
state.addBundle(baseImporter);
state.addBundle(baseImporter2);
state.addBundle(baseImporter3);
state.resolve();
// make sure all bundles are resolved that should be
assertTrue("1.0", baseExporter.isResolved());
assertTrue("1.1", baseExporterRequire.isResolved());
assertTrue("1.2", baseExporterRequire2.isResolved());
assertTrue("1.3", baseImporter.isResolved());
assertTrue("1.4", baseImporter2.isResolved());
assertTrue("1.5", baseImporter3.isResolved());
StateHelper helper = state.getStateHelper();
ExportPackageDescription[] visImporter = helper.getVisiblePackages(baseImporter);
assertTrue("2.0", visImporter != null && visImporter.length == 2);
assertEquals("2.1", visImporter[0].getName(), "test.base");
assertEquals("2.2", visImporter[1].getName(), "test.base");
BundleDescription exporter1 = visImporter[0].getExporter();
BundleDescription exporter2 = visImporter[1].getExporter();
assertTrue("2.3", exporter1 != exporter2);
assertTrue("2.4", exporter1 == baseExporter || exporter1 == baseExporterRequire);
assertTrue("2.5", exporter2 == baseExporter || exporter2 == baseExporterRequire);
ExportPackageDescription[] visImporter2 = helper.getVisiblePackages(baseImporter2);
assertTrue("3.0", visImporter2 != null && visImporter2.length == 1);
assertEquals("3.1", visImporter2[0].getName(), "test.base.exporter.require");
assertTrue("3.2", visImporter2[0].getExporter() == baseExporterRequire2);
ExportPackageDescription[] visImporter3 = helper.getVisiblePackages(baseImporter3);
assertTrue("4.0", visImporter3 != null && visImporter3.length == 1);
assertEquals("4.1", visImporter3[0].getName(), "test.base");
assertTrue("4.2", visImporter3[0].getExporter() == baseImporter2);
}
public void testVisiblePackages003() throws BundleException {
State state = buildEmptyState();
int bundleID = 0;
Hashtable manifest = new Hashtable();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "E");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.EXPORT_PACKAGE, "test.base; E=split; mandatory:=E");
BundleDescription e = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "D");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE, "E");
BundleDescription d = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "C");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE, "D");
manifest.put(Constants.EXPORT_PACKAGE, "test.base; D=split; mandatory:=D");
BundleDescription c = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "B");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE, "F; " + Constants.VISIBILITY_DIRECTIVE + ":=" + Constants.VISIBILITY_REEXPORT );
BundleDescription b = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "F");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.EXPORT_PACKAGE, "test.base; F=split; mandatory:=F");
BundleDescription f = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
manifest.clear();
manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
manifest.put(Constants.BUNDLE_SYMBOLICNAME, "A");
manifest.put(Constants.BUNDLE_VERSION, "1.0");
manifest.put(Constants.REQUIRE_BUNDLE, "B; " + Constants.VISIBILITY_DIRECTIVE + ":=" + Constants.VISIBILITY_REEXPORT +
",C");
BundleDescription a = state.getFactory().createBundleDescription(state, manifest, (String) manifest.get(Constants.BUNDLE_SYMBOLICNAME), bundleID++);
Dictionary[] props = new Dictionary[] {new Hashtable()};
props[0].put("osgi.resolverMode", "strict");
state.setPlatformProperties(props);
state.addBundle(f);
state.addBundle(e);
state.addBundle(d);
state.addBundle(c);
state.addBundle(b);
state.addBundle(a);
state.resolve();
// make sure all bundles are resolved that should be
assertTrue("1.0", a.isResolved());
assertTrue("1.1", b.isResolved());
assertTrue("1.2", c.isResolved());
assertTrue("1.3", d.isResolved());
assertTrue("1.4", e.isResolved());
assertTrue("1.5", f.isResolved());
StateHelper helper = state.getStateHelper();
ExportPackageDescription[] visImporter = helper.getVisiblePackages(a);
assertTrue("2.0", visImporter != null && visImporter.length == 2);
assertEquals("2.1", visImporter[0].getName(), "test.base");
assertEquals("2.2", visImporter[1].getName(), "test.base");
BundleDescription exporter1 = visImporter[0].getExporter();
BundleDescription exporter2 = visImporter[1].getExporter();
assertTrue("2.3", exporter1 != exporter2);
assertTrue("2.4", exporter1 == c || exporter1 == f);
assertTrue("2.5", exporter2 == c || exporter2 == f);
}
private boolean contains(Object[] array, Object element) {
for (int i = 0; i < array.length; i++)
if (array[i].equals(element))
return true;
return false;
}
}