/*******************************************************************************
* Copyright (c) 2014 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
* and Eclipse Distribution License v1.0 which accompany this distribution.
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Jochen Hiller
*******************************************************************************/
package org.eclipse.concierge;
import java.util.Arrays;
import java.util.Collection;
import org.eclipse.concierge.test.util.AbstractConciergeTestCase;
import org.eclipse.concierge.test.util.SyntheticBundleBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.osgi.framework.Bundle;
/**
* These tests will check whether fragment bundles will be resolved when using
* import package statements. These import package statements can match the host
* one's or will have a conflict with host based on version or other directives.
*
* The test is setup using 3 types of bundles:
*
* <pre>
* Bundle "Provider": Export-Package = p1;version="1.2.3"
* Bundle "Host": Import-Package = p1
* Bundle "Fragment": Import-Package = p1
* </pre>
*
* The Import-Package statements will be specified with different versions, to
* check whether this resolvement from Fragment to Host to Provider bundle is
* possible or not.
*
* See OSGi Spec R5, chapter 3.14
*
* <pre>
* When attaching a fragment bundle to a host bundle the Framework must perform the following
* ...
* 1. Append the import definitions for the Fragment bundle that do not conflict with an import
* definition of the host to the import definitions of the host bundle. A Fragment can provide an
* import statement for a private package of the host. The private package in the host is
* hidden in that case.
* ...
* </pre>
*
* TODO This tests does fail due to temporary change in
* BundleImpl.checkConflicts, Line 2348. TODO add more tests for directives
*
* @author Jochen Hiller - Initial Contribution
*/
@RunWith(Parameterized.class)
@Ignore("TODO Does not work due to temporary change in BundleImpl.Revision.checkConflicts")
public class FragmentBundleWithImportsTest extends AbstractConciergeTestCase {
// Parameterized tests:
// {0} description of test
// {1} import package statement of host
// {2} import package statement of fragment
// {3} expected result: "has to be resolved": true/false
@Parameters(name = "{index}: {0} for host={1} and fragment={2} resolved to: {3}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {
// note: provided version is package;version="1.2.3"
{ "Import packages are equals", "p1", "p1", true },
{ "Import of fragment is newer than host",
"p1;version=\"1.0.0\"", "p1;version=\"2.0.0\"", false },
{ "Import of fragment is older than host, and host is less than provider",
"p1;version=\"1.0.0\"", "p1;version=\"0.0.1\"", false },
{ "Import of fragment is exact the host",
"p1;version=\"1.2.3\"", "p1;version=\"1.2.3\"", true },
// TODO is this correct?
{ "Import of host is exact the provider, fragment is less than",
"p1;version=\"1.2.3\"", "p1;version=\"1.0.0\"",
true }, });
}
private String hostImportPackage;
private String fragmentImportPackage;
private boolean fragmentShouldBeResolved;
public FragmentBundleWithImportsTest(String name, String host,
String fragment, boolean shouldBeResolved) {
this.hostImportPackage = host;
this.fragmentImportPackage = fragment;
this.fragmentShouldBeResolved = shouldBeResolved;
}
@Before
public void setUp() throws Exception {
startFramework();
// provider bundle for hosting a package
SyntheticBundleBuilder builder = SyntheticBundleBuilder.newBuilder();
builder.bundleSymbolicName("Provider")
.addManifestHeader("Export-Package", "p1;version=\"1.2.3\"");
Bundle providerBundle = installBundle(builder);
providerBundle.start();
assertBundleActive(providerBundle);
}
@After
public void tearDown() throws Exception {
stopFramework();
}
@Test
public void test() throws Exception {
Bundle hostBundle = installHostBundle(this.hostImportPackage);
Bundle fragmentBundle = installFragmentBundle(
this.fragmentImportPackage);
// now start host bundle. Check for fragment state based on expected
// result
hostBundle.start();
assertBundleActive(hostBundle);
if (this.fragmentShouldBeResolved) {
assertBundleResolved(fragmentBundle);
} else {
assertBundleInstalled(fragmentBundle);
}
}
/**
* Installs the host bundle with given import package statement.
*/
private Bundle installHostBundle(String importPackageHeader)
throws Exception {
SyntheticBundleBuilder builder = SyntheticBundleBuilder.newBuilder();
builder.bundleSymbolicName("Host").addManifestHeader("Import-Package",
importPackageHeader);
Bundle hostBundle = installBundle(builder);
return hostBundle;
}
/**
* Installs the fragment bundle with given import package statement.
*/
private Bundle installFragmentBundle(String importPackageHeader)
throws Exception {
SyntheticBundleBuilder builder = SyntheticBundleBuilder.newBuilder();
builder.bundleSymbolicName("Fragment")
.addManifestHeader("Fragment-Host", "Host")
.addManifestHeader("Import-Package", importPackageHeader);
Bundle fragmentBundle = installBundle(builder);
return fragmentBundle;
}
}