/* * 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.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Dictionary; import java.util.Hashtable; import java.util.List; import java.util.Scanner; import org.apache.aries.subsystem.ContentHandler; import org.junit.Ignore; import org.junit.Test; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceRegistration; import org.osgi.framework.namespace.IdentityNamespace; import org.osgi.resource.Capability; import org.osgi.resource.Resource; import org.osgi.service.coordinator.Coordination; import org.osgi.service.subsystem.Subsystem; public class CustomContentHandlerTest extends SubsystemTest { @Override protected void createApplications() throws Exception { createApplication("customContent", "custom1.sausages", "customContentBundleA.jar"); createApplication("customContent1", "custom2.sausages", "customContentBundleB.jar"); createApplication("customContent2", "custom3.sausages", "customContentBundleC.jar"); createApplication("customContent3", "custom4.sausages", "customContentBundleD.jar"); } @Test public void testCustomContentHandler() throws Exception { for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleA".equals(b.getSymbolicName())) { fail("Precondition"); } } SausagesContentHandler handler = new SausagesContentHandler(); Dictionary<String, Object> props = new Hashtable<String, Object>(); props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); try { assertEquals("Precondition", 0, handler.calls.size()); Subsystem subsystem = installSubsystemFromFile("customContent.esa"); try { assertEquals(Arrays.asList("install:customContent1 sausages = 1"), handler.calls); Collection<Resource> constituents = subsystem.getConstituents(); assertEquals("The custom content should not show up as a subsystem constituent", 1, constituents.size()); boolean foundBundle = false; for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleA".equals(b.getSymbolicName())) { foundBundle = true; } } assertTrue(foundBundle); boolean foundBundleInConstituents = false; for (Resource c : constituents) { for(Capability idCap : c.getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE)) { Object name = idCap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE); if ("org.apache.aries.subsystem.itests.customcontent.bundleA".equals(name)) foundBundleInConstituents = true; } } assertTrue(foundBundleInConstituents); handler.calls.clear(); assertEquals(Subsystem.State.INSTALLED, subsystem.getState()); subsystem.start(); assertEquals(Arrays.asList("start:customContent1"), handler.calls); handler.calls.clear(); assertEquals(Subsystem.State.ACTIVE, subsystem.getState()); subsystem.stop(); assertEquals(Arrays.asList("stop:customContent1"), handler.calls); assertEquals(Subsystem.State.RESOLVED, subsystem.getState()); } finally { handler.calls.clear(); subsystem.uninstall(); assertEquals(Arrays.asList("uninstall:customContent1"), handler.calls); assertEquals(Subsystem.State.UNINSTALLED, subsystem.getState()); } } finally { reg.unregister(); } } @Test public void testCustomContentInstallationException() throws Exception { for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleB".equals(b.getSymbolicName())) { fail("Precondition"); } } SausagesContentHandler handler = new SausagesContentHandler(true, "install"); Dictionary<String, Object> props = new Hashtable<String, Object>(); props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); assertEquals("Precondition", 0, handler.calls.size()); try { installSubsystemFromFile("customContent1.esa"); } catch (Exception ex) { // ignore } try { for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleB".equals(b.getSymbolicName())) { fail("Should not have installed the bundle"); } } } finally { reg.unregister(); } } @Test @Ignore("This test exposes a problem that needs to be fixed, namely that the previous test leaves stuff behind and that " + "customContent1.esa cannot be installed again. Currently ignored until someone finds the time to fix it.") public void testCustomContentInstallationSecondTime() throws Exception { for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleB".equals(b.getSymbolicName())) { fail("Precondition"); } } SausagesContentHandler handler = new SausagesContentHandler(); Dictionary<String, Object> props = new Hashtable<String, Object>(); props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); try { Subsystem subsystem = installSubsystemFromFile("customContent1.esa"); subsystem.uninstall(); } finally { reg.unregister(); } } @Test public void testCustomContentInstallationCoordinationFails() throws Exception { for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) { fail("Precondition"); } } SausagesContentHandler handler = new SausagesContentHandler(false, "install"); Dictionary<String, Object> props = new Hashtable<String, Object>(); props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); assertEquals("Precondition", 0, handler.calls.size()); try { installSubsystemFromFile("customContent2.esa"); } catch (Exception ex) { // ignore } try { for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) { fail("Should not have installed the bundle"); } } } finally { reg.unregister(); } } @Test @Ignore("This test currently doesn't pass, the bundle moves to the active state, while it shouldn't") public void testCustomContentStartException() throws Exception { for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) { fail("Precondition"); } } SausagesContentHandler handler = new SausagesContentHandler(true, "start"); Dictionary<String, Object> props = new Hashtable<String, Object>(); props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); assertEquals("Precondition", 0, handler.calls.size()); Subsystem subsystem = installSubsystemFromFile("customContent2.esa"); try { assertEquals(Arrays.asList("install:customContent3 sausages = 3"), handler.calls); try { Bundle theBundle = null; for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleC".equals(b.getSymbolicName())) { assertEquals(Bundle.INSTALLED, b.getState()); theBundle = b; } } assertNotNull(theBundle); try { subsystem.start(); } catch (Exception ex) { // good } assertEquals("There was an exception during start, so the bundle should not be started", Bundle.INSTALLED, theBundle.getState()); } finally { subsystem.uninstall(); } } finally { reg.unregister(); } } @Test @Ignore("This test currently doesn't pass, the bundle moves to the active state, while it shouldn't") public void testCustomContentStartFailCoordination() throws Exception { for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleD".equals(b.getSymbolicName())) { fail("Precondition"); } } SausagesContentHandler handler = new SausagesContentHandler(false, "start"); Dictionary<String, Object> props = new Hashtable<String, Object>(); props.put(ContentHandler.CONTENT_TYPE_PROPERTY, "foo.sausages"); ServiceRegistration<ContentHandler> reg = bundleContext.registerService(ContentHandler.class, handler, props); assertEquals("Precondition", 0, handler.calls.size()); Subsystem subsystem = installSubsystemFromFile("customContent3.esa"); try { assertEquals(Arrays.asList("install:customContent4 sausages = 4"), handler.calls); try { Bundle theBundle = null; for (Bundle b : bundleContext.getBundles()) { if ("org.apache.aries.subsystem.itests.customcontent.bundleD".equals(b.getSymbolicName())) { assertEquals(Bundle.INSTALLED, b.getState()); theBundle = b; } } assertNotNull(theBundle); try { subsystem.start(); } catch (Exception ex) { // good } assertEquals("The coordination failued during start, so the bundle should not be started", Bundle.INSTALLED, theBundle.getState()); } finally { subsystem.uninstall(); } } finally { reg.unregister(); } } private static String convertStreamToString(InputStream is) { Scanner s = new Scanner(is).useDelimiter("\\A"); return s.hasNext() ? s.next() : ""; } static class SausagesContentHandler implements ContentHandler { List<String> calls = new ArrayList<String>(); private final boolean exception; private final String state; public SausagesContentHandler() { this(false, null); } public SausagesContentHandler(boolean exception, String state) { this.exception = exception; this.state = state; } @Override public void install(InputStream is, String symbolicName, String type, Subsystem subsystem, Coordination coordination) { if ("install".equals(state)) { if (exception) { throw new RuntimeException(state); } else { coordination.fail(new RuntimeException(state)); } } String content = convertStreamToString(is); calls.add(("install:" + symbolicName + " " + content).trim()); } @Override public void start(String symbolicName, String type, Subsystem subsystem, Coordination coordination) { if ("start".equals(state)) { if (exception) { throw new RuntimeException(state); } else { coordination.fail(new RuntimeException(state)); } } calls.add("start:" + symbolicName); } @Override public void stop(String symbolicName, String type, Subsystem subsystem) { calls.add("stop:" + symbolicName); } @Override public void uninstall(String symbolicName, String type, Subsystem subsystem) { calls.add("uninstall:" + symbolicName); } } }