blob: 838e12bc4d03f71426031b45524d3acf42b3e0a4 [file] [log] [blame]
/*
* 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.
*/
package org.apache.aries.subsystem.itests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.equinox.region.Region;
import org.eclipse.equinox.region.RegionDigraph;
import org.eclipse.equinox.region.RegionFilter;
import org.junit.Test;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.Version;
import org.osgi.service.subsystem.Subsystem;
import org.osgi.service.subsystem.SubsystemConstants;
public class RootSubsystemTest extends SubsystemTest {
/*
* Subsystem-SymbolicName: application.a.esa
* Subsystem-Content: bundle.a.jar
*/
private static final String APPLICATION_A = "application.a.esa";
/*
* Bundle-SymbolicName: bundle.a.jar
* Import-Package: org.osgi.framework
*/
private static final String BUNDLE_A = "bundle.a.jar";
@Override
public void createApplications() throws Exception {
createBundleA();
createApplicationA();
}
private static void createApplicationA() throws IOException {
createApplicationAManifest();
createSubsystem(APPLICATION_A, BUNDLE_A);
}
private static void createApplicationAManifest() throws IOException {
Map<String, String> attributes = new HashMap<String, String>();
attributes.put(SubsystemConstants.SUBSYSTEM_SYMBOLICNAME, APPLICATION_A);
createManifest(APPLICATION_A + ".mf", attributes);
}
private void createBundleA() throws IOException {
createBundle(name(BUNDLE_A), importPackage("org.osgi.framework"));
}
// TODO Test root subsystem headers.
@Test
public void testDoNotStartExtraneousRootRegionBundles() throws Exception {
bundleContext.installBundle(new File(BUNDLE_A).toURI().toURL().toString());
getSubsystemCoreBundle().stop();
getSubsystemCoreBundle().start();
Bundle bundleA = context().getBundleByName(BUNDLE_A);
assertEquals("Extraneous root region bundle should not be started", Bundle.INSTALLED, bundleA.getState());
}
@Test
public void testId() {
assertEquals("Wrong root ID", getRootSubsystem().getSubsystemId(), 0);
}
@Test
public void testLocation() {
assertEquals("Wrong root location", getRootSubsystem().getLocation(), "subsystem://?Subsystem-SymbolicName=org.osgi.service.subsystem.root&Subsystem-Version=1.0.0");
}
@Test
public void testRegionContextBundle() throws BundleException {
assertRegionContextBundle(getRootSubsystem());
getSubsystemCoreBundle().stop();
getSubsystemCoreBundle().start();
assertRegionContextBundle(getRootSubsystem());
}
@Test
public void testServiceEvents() throws Exception {
Subsystem root = getRootSubsystem();
Bundle core = getSubsystemCoreBundle();
// TODO Temporary(?) workaround to allow time for any tardy service
// events to arrive so they can be cleared. So far, this sleep has only
// been necessary on the IBM 6.0 64-bit JDK.
Thread.sleep(1000);
subsystemEvents.clear();
core.stop();
assertServiceEventsStop(root);
core.uninstall();
core = bundleContext.installBundle(normalizeBundleLocation(core));
core.start();
// There should be install events since the persisted root subsystem was
// deleted when the subsystems implementation bundle was uninstalled.
assertServiceEventsInstall(root);
assertServiceEventsResolve(root);
assertServiceEventsStart(root);
core.stop();
assertServiceEventsStop(root);
core.start();
// There should be no install events or RESOLVING event since there
// should be a persisted root subsystem already in the RESOLVED state.
assertServiceEventResolved(root, ServiceEvent.REGISTERED);
assertServiceEventsStart(root);
}
@Test
public void testSymbolicName() {
assertEquals("Wrong root symbolic name", getRootSubsystem().getSymbolicName(), "org.osgi.service.subsystem.root");
}
@Test
public void testUninstallRootRegionBundleWithNoBundleEventHook() throws Exception {
// Install an extraneous bundle into the root region. The bundle will
// be recorded in the root subsystem's persistent memory.
Bundle bundleA = bundleContext.installBundle(new File(BUNDLE_A).toURI().toURL().toString());
try {
Bundle core = getSubsystemCoreBundle();
// Stop the subsystems bundle in order to unregister the bundle
// event hook.
core.stop();
// Uninstall the bundle so it won't be there on restart.
bundleA.uninstall();
try {
// Start the subsystems bundle and ensure the root subsystem
// recovers from the uninstalled bundle being in persistent
// memory.
core.start();
}
catch (BundleException e) {
fail("Could not start subsystems bundle after uninstalling a root region bundle with no bundle event hook registered");
}
}
finally {
if (Bundle.UNINSTALLED != bundleA.getState())
bundleA.uninstall();
}
}
@Test
public void testVersion() {
assertEquals("Wrong root version", getRootSubsystem().getVersion(), Version.parseVersion("1.0.0"));
}
/*
* The root subsystem should be associated with the region in which the
* subsystems implementation bundle is installed.
*/
@Test
public void testRegion() throws Exception {
RegionDigraph digraph = context().getService(RegionDigraph.class);
Bundle core = getSubsystemCoreBundle();
Region kernel = digraph.getRegion(core);
Subsystem root = getRootSubsystem();
Bundle rootRegionContext = root.getBundleContext().getBundle();
// Get the region containing the subsystem's region context bundle,
// which is the same thing as getting the region with which the
// subsystem is associated.
Region region = digraph.getRegion(root.getBundleContext().getBundle());
assertEquals("Wrong region", kernel, region);
// Uninstall the core bundle to remove the persisted root subsystem.
core.uninstall();
// Clean up the lingering region context bundle.
rootRegionContext.uninstall();
// Create a new region and install the core bundle into it.
Region user = digraph.createRegion("user");
// Allow everything from the kernel region into the user region so the
// core bundle will resolve.
user.connectRegion(
kernel,
digraph.createRegionFilterBuilder().allowAll(RegionFilter.VISIBLE_ALL_NAMESPACE).build());
// Allow everything from the user region into the kernel region so the
// root subsystem service can be found.
kernel.connectRegion(
user,
digraph.createRegionFilterBuilder().allowAll(RegionFilter.VISIBLE_ALL_NAMESPACE).build());
core = user.installBundle(normalizeBundleLocation(core.getLocation()));
user = digraph.getRegion(core);
core.start();
root = getRootSubsystem();
region = digraph.getRegion(root.getBundleContext().getBundle());
// The root subsystem should now be in the new region.
assertEquals("Wrong region", user, region);
// Extra test. Install application A into the root region (user) and
// make sure it resolves. Although the system bundle is in the kernel
// region and not a constituent of the root subsystem, the capability
// should still be found and used.
try {
Subsystem applicationA = installSubsystemFromFile(root, APPLICATION_A);
uninstallSubsystemSilently(applicationA);
}
catch (Exception e) {
e.printStackTrace();
fail("Subsystem should have installed");
}
}
}