/* * Copyright 2007 the original author or authors. * * 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.wamblee.system.core; import java.io.Serializable; import java.util.Arrays; import junit.framework.TestCase; import org.easymock.classextension.ConstructorArgs; import org.easymock.classextension.EasyMock; import org.easymock.classextension.IMocksControl; import org.wamblee.test.AssertionUtils; import org.wamblee.test.EasyMockMatchers; import org.wamblee.test.EventTracker; public class ContainerTest extends TestCase { private EventTracker _tracker; @Override protected void setUp() throws Exception { super.setUp(); _tracker = new EventTracker(); } private static class MyMultiple implements Serializable, Runnable { @Override public void run() { // Empty } } public void testFilterProvided() { RequiredInterface req1 = new DefaultRequiredInterface("name", Runnable.class); RequiredInterface req2 = new DefaultRequiredInterface("name", Serializable.class); ProvidedInterface prov1 = new DefaultProvidedInterface("name", Runnable.class); ProvidedInterface prov2 = new DefaultProvidedInterface("name", Serializable.class); ProvidedInterface prov3 = new DefaultProvidedInterface("name", MyMultiple.class); AssertionUtils.assertEquals(new RequiredInterface[] { req1 }, Container .filterRequiredServices(prov1, Arrays .asList(new RequiredInterface[] { req1 }))); AssertionUtils.assertEquals(new RequiredInterface[] { req1 }, Container .filterRequiredServices(prov1, Arrays .asList(new RequiredInterface[] { req1, req2 }))); AssertionUtils.assertEquals(new RequiredInterface[] { req1, req2 }, Container.filterRequiredServices(prov3, Arrays .asList(new RequiredInterface[] { req1, req2 }))); AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 }, Container.filterProvidedServices(req1, Arrays .asList(new ProvidedInterface[] { prov1 }))); AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 }, Container.filterProvidedServices(req1, Arrays .asList(new ProvidedInterface[] { prov1, prov2 }))); AssertionUtils.assertEquals(new ProvidedInterface[] { prov1, prov3 }, Container.filterProvidedServices(req1, Arrays .asList(new ProvidedInterface[] { prov1, prov3 }))); } public void testEnvironmentApplication() { Environment environment = new Environment(_tracker); Application application = new Application(_tracker); Container container = new Container("root", new Component[] { environment, application }, new ProvidedInterface[0], new RequiredInterface[0]); Scope scope = container.start(); AssertionUtils.assertEquals(new String[] { "start.environment", "start.application" }, _tracker.getEvents( Thread.currentThread()).toArray(new String[0])); assertEquals(0, scope.getProvidedInterfaces().length); assertEquals(environment.getString(), application.getString()); assertEquals(environment.getInteger(), application.getInteger()); } public void testApplicationEnvironment() { try { Component environment = new Environment(); Component application = new Application(); Container container = new Container("root", new Component[] { application, environment }, new ProvidedInterface[0], new RequiredInterface[0]); container.start(); } catch (SystemAssemblyException e) { // e.printStackTrace(); return; } fail(); } public void testComposite() { Component environment = new Environment(_tracker); Component application = new Application(_tracker); assertEquals(0, _tracker.getEventCount()); Container system = new Container("all", new Component[] { environment, application }, new ProvidedInterface[0], new RequiredInterface[0]); Scope runtime = system.start(); RequiredInterface[] required = system.getRequiredInterfaces(); assertEquals(0, required.length); ProvidedInterface[] provided = system.getProvidedInterfaces(); assertEquals(0, provided.length); AssertionUtils.assertEquals(new String[] { "start.environment", "start.application" }, _tracker.getEvents( Thread.currentThread()).toArray(new String[0])); _tracker.clear(); system.stop(runtime); AssertionUtils.assertEquals(new String[] { "stop.application", "stop.environment" }, _tracker .getEvents(Thread.currentThread()).toArray(new String[0])); } public void testCompositeWithWrongProvidedInfo() { try { Component environment = new Environment(); Component application = new Application(); Container system = new Container("all", new Component[] { environment, application }, new ProvidedInterface[] { new DefaultProvidedInterface( "float", Float.class) }, new DefaultRequiredInterface[0]); } catch (SystemAssemblyException e) { return; } fail(); } public void testCompositeRequiredInterfaceNotProvided() { try { Component environment = new Environment(); Component application = new Application(); Container system = new Container("all", new Component[] { environment, application }, new ProvidedInterface[0], new RequiredInterface[] { new DefaultRequiredInterface( "string", String.class) }); system.start(); } catch (SystemAssemblyException e) { return; } fail(); } public void testCompositeWithSuperfluousRequiredInfo() { Component environment = new Environment(); Component application = new Application(); Container system = new Container("all", new Component[] { environment, application }, new ProvidedInterface[0], new RequiredInterface[] { new DefaultRequiredInterface( "float", Float.class) }); system.getRequiredInterfaces()[0] .setProvider(new DefaultProvidedInterface("hallo", Float.class)); system.start(); RequiredInterface[] required = system.getRequiredInterfaces(); assertEquals(1, required.length); ProvidedInterface[] provided = system.getProvidedInterfaces(); assertEquals(0, provided.length); } public void testCompositeWithExternalDependencesNotProvided() { try { Component environment = new Environment(); Component application = new Application(); Container system = new Container("all", new Component[] { application }, new ProvidedInterface[0], application.getRequiredInterfaces()); system.start(); } catch (SystemAssemblyException e) { return; } fail(); } public void testCompositeWithExternalDependencesProvided() { Component environment = new Environment(); Component application = new Application(); Container system = new Container("all", new Component[] { application }, new ProvidedInterface[0], application.getRequiredInterfaces()); environment.start(new DefaultScope(new ProvidedInterface[0])); system.getRequiredInterfaces()[0].setProvider(environment .getProvidedInterfaces()[0]); system.getRequiredInterfaces()[1].setProvider(environment .getProvidedInterfaces()[1]); system.start(); RequiredInterface[] required = system.getRequiredInterfaces(); assertEquals(2, required.length); ProvidedInterface[] provided = system.getProvidedInterfaces(); assertEquals(0, provided.length); } public void testAmbiguousInterfaces() { try { Component environment1 = new Environment(); Component environment2 = new Environment(); Component application = new Application(); Container container = new Container("root", new Component[] { environment1, environment2, application }, new ProvidedInterface[0], new RequiredInterface[0]); container.start(); } catch (SystemAssemblyException e) { return; } fail(); } public void testIncompleteRequirements() { try { Component application = new Application(); Container system = new Container("all", new Component[] { application }, new ProvidedInterface[0], new RequiredInterface[0]); system.start(); } catch (SystemAssemblyException e) { return; } fail(); } public void testEnvironmentApplicationRollbackOnException() throws Exception { IMocksControl control = EasyMock.createStrictControl(); Environment environment = new Environment(_tracker); Application application = control.createMock(Application.class, new ConstructorArgs(Application.class.getConstructor()), Application.class.getDeclaredMethod("doStart", Scope.class)); application.doStart(EasyMockMatchers.anyObject(Scope.class)); EasyMock.expectLastCall().andThrow(new RuntimeException()); control.replay(); try { Container container = new Container("root", new Component[] { environment, application }, new ProvidedInterface[0], new RequiredInterface[0]); container.start(); } catch (RuntimeException e) { AssertionUtils.assertEquals(new String[] { "start.environment", "stop.environment" }, _tracker.getEvents( Thread.currentThread()).toArray(new String[0])); return; } fail(); } public void testEnvironmentApplicationRollbackOnExceptionWithExceptionOnStop() throws Exception { IMocksControl control = EasyMock.createControl(); Environment environment = new Environment(_tracker); // Application 1 will throw an exception while stopping. Application application1 = control.createMock(Application.class, new ConstructorArgs(Application.class.getConstructor()), Application.class.getDeclaredMethod("doStop", Object.class)); application1.doStop(EasyMock.anyObject()); EasyMock.expectLastCall().andThrow(new RuntimeException()); // application 2 will throw an exception while starting Application application2 = control.createMock(Application.class, new ConstructorArgs(Application.class.getConstructor()), Application.class.getDeclaredMethod("doStart", Scope.class)); application2.doStart(EasyMockMatchers.anyObject(Scope.class)); EasyMock.expectLastCall().andThrow(new RuntimeException()); control.replay(); try { Container container = new Container("root", new Component[] { environment, application1, application2 }, new ProvidedInterface[0], new RequiredInterface[0]); container.start(); } catch (RuntimeException e) { AssertionUtils.assertEquals(new String[] { "start.environment", "stop.environment" }, _tracker.getEvents( Thread.currentThread()).toArray(new String[0])); return; } fail(); } public void testOptionalRequiredInterfaceProvidedOptionalInternal() { Application application = new Application(true); Container container = new Container("top", new Component[] { application }, new ProvidedInterface[0], Application.required(true)); Environment env = new Environment(); container.getRequiredInterfaces()[0].setProvider( env.getProvidedInterfaces()[0]); container.getRequiredInterfaces()[1].setProvider( env.getProvidedInterfaces()[1]); Scope external = new DefaultScope(env.getProvidedInterfaces()); env.start(external); container.start(external); assertSame(env.getProvidedInterfaces()[0], container.getRequiredInterfaces()[0].getProvider()); assertSame(env.getProvidedInterfaces()[1], container.getRequiredInterfaces()[1].getProvider()); assertSame(env.getProvidedInterfaces()[0], application.getRequiredInterfaces()[0].getProvider()); assertSame(env.getProvidedInterfaces()[1], application.getRequiredInterfaces()[1].getProvider()); } public void testOptionalRequiredInterfaceNotProvidedOptionalInternal() { Application application = new Application(true); Container container = new Container("top", new Component[] { application }, new ProvidedInterface[0], Application.required(true)); Environment env = new Environment(); container.getRequiredInterfaces()[0].setProvider( env.getProvidedInterfaces()[0]); Scope external = new DefaultScope(new ProvidedInterface[0]); external.publishInterface(env.getProvidedInterfaces()[0], env.getString()); container.start(external); assertSame(env.getProvidedInterfaces()[0], container.getRequiredInterfaces()[0].getProvider()); assertNull(container.getRequiredInterfaces()[1].getProvider()); assertSame(env.getProvidedInterfaces()[0], application.getRequiredInterfaces()[0].getProvider()); assertNull(application.getRequiredInterfaces()[1].getProvider()); } public void testOptionalRequiredInterfaceProvidedMandatoryInternal() { Application application = new Application(); Container container = new Container("top", new Component[] { application }, new ProvidedInterface[0], Application.required(true)); Environment env = new Environment(); container.getRequiredInterfaces()[0].setProvider( env.getProvidedInterfaces()[0]); container.getRequiredInterfaces()[1].setProvider( env.getProvidedInterfaces()[1]); container.start(); assertSame(env.getProvidedInterfaces()[0], container.getRequiredInterfaces()[0].getProvider()); assertSame(env.getProvidedInterfaces()[1], container.getRequiredInterfaces()[1].getProvider()); assertSame(env.getProvidedInterfaces()[0], application.getRequiredInterfaces()[0].getProvider()); assertSame(env.getProvidedInterfaces()[1], application.getRequiredInterfaces()[1].getProvider()); } }