2 * Copyright 2007 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.wamblee.system.core;
18 import java.io.IOException;
19 import java.io.Serializable;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.List;
24 import junit.framework.TestCase;
26 import org.easymock.classextension.ConstructorArgs;
27 import org.easymock.classextension.EasyMock;
28 import org.easymock.classextension.IMocksControl;
29 import org.wamblee.general.Pair;
30 import org.wamblee.test.AssertionUtils;
31 import org.wamblee.test.EasyMockMatchers;
32 import org.wamblee.test.EventTracker;
34 public class ContainerTest extends TestCase {
36 private EventTracker<String> _tracker;
39 protected void setUp() throws Exception {
41 _tracker = new EventTracker<String>();
44 private static class MyMultiple implements Serializable, Runnable {
51 private List<Pair<ProvidedInterface, Component>> createProvidedInput(
52 ProvidedInterface[] aProvided, Component aProvider) {
53 List<Pair<ProvidedInterface, Component>> result = new ArrayList<Pair<ProvidedInterface, Component>>();
54 for (ProvidedInterface provided : aProvided) {
55 result.add(new Pair<ProvidedInterface, Component>(provided,
61 public void testFilterProvided() {
62 RequiredInterface req1 = new DefaultRequiredInterface("name",
64 RequiredInterface req2 = new DefaultRequiredInterface("name",
66 ProvidedInterface prov1 = new DefaultProvidedInterface("name",
68 ProvidedInterface prov2 = new DefaultProvidedInterface("name",
70 ProvidedInterface prov3 = new DefaultProvidedInterface("name",
73 Component client = new Application("client");
74 Component dummy = new Application("dummy");
76 InterfaceRestriction noRestriction = new InterfaceRestriction() {
78 public boolean isViolated(Component aClient,
79 RequiredInterface aRequired, Component aServer,
80 ProvidedInterface aProvided) {
85 AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
86 Container.filterProvidedServices(client, req1,
87 createProvidedInput(new ProvidedInterface[] { prov1 }, dummy), noRestriction));
88 AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
89 Container.filterProvidedServices(client, req1,
90 createProvidedInput(new ProvidedInterface[] { prov1, prov2 }, dummy), noRestriction));
91 AssertionUtils.assertEquals(new ProvidedInterface[] { prov1, prov3 },
92 Container.filterProvidedServices(client, req1,
93 createProvidedInput(new ProvidedInterface[] { prov1, prov3 }, dummy), noRestriction));
95 InterfaceRestriction everything = new InterfaceRestriction() {
97 public boolean isViolated(Component aClient,
98 RequiredInterface aRequired, Component aServer,
99 ProvidedInterface aProvided) {
103 AssertionUtils.assertEquals(new ProvidedInterface[0],
104 Container.filterProvidedServices(client, req1,
105 createProvidedInput(new ProvidedInterface[] { prov1, prov3 }, dummy), everything));
109 public void testEnvironmentApplication() {
110 Environment environment = new Environment(_tracker);
111 Application application = new Application(_tracker);
112 Container container = new Container("root", new Component[] {
113 environment, application }, new ProvidedInterface[0],
114 new RequiredInterface[0]);
115 Scope scope = container.start();
116 assertTrue(container.isSealed());
117 AssertionUtils.assertEquals(new String[] { "start.environment",
118 "start.application" }, _tracker.getEvents(
119 Thread.currentThread()).toArray(new String[0]));
120 assertEquals(0, scope.getProvidedInterfaces().length);
122 assertEquals(environment.getString(), application.getString());
123 assertEquals(environment.getInteger(), application.getInteger());
127 public void testEnvironmentApplicationSimpleConstructor() {
128 Environment environment = new Environment(_tracker);
129 Application application = new Application(_tracker);
130 Container container = new Container("root").addComponent(environment)
131 .addComponent(application);
133 Scope scope = container.start();
134 AssertionUtils.assertEquals(new String[] { "start.environment",
135 "start.application" }, _tracker.getEvents(
136 Thread.currentThread()).toArray(new String[0]));
137 assertEquals(0, scope.getProvidedInterfaces().length);
139 assertEquals(environment.getString(), application.getString());
140 assertEquals(environment.getInteger(), application.getInteger());
144 public void testApplicationEnvironment() {
146 Component environment = new Environment();
147 Component application = new Application();
148 Container container = new Container("root", new Component[] {
149 application, environment }, new ProvidedInterface[0],
150 new RequiredInterface[0]);
152 } catch (SystemAssemblyException e) {
153 // e.printStackTrace();
159 public void testComposite() {
160 Component environment = new Environment(_tracker);
161 Component application = new Application(_tracker);
162 assertEquals(0, _tracker.getEventCount());
164 Container system = new Container("all", new Component[] { environment,
165 application }, new ProvidedInterface[0],
166 new RequiredInterface[0]);
167 Scope runtime = system.start();
168 RequiredInterface[] required = system.getRequiredInterfaces();
169 assertEquals(0, required.length);
170 ProvidedInterface[] provided = system.getProvidedInterfaces();
171 assertEquals(0, provided.length);
173 AssertionUtils.assertEquals(new String[] { "start.environment",
174 "start.application" }, _tracker.getEvents(
175 Thread.currentThread()).toArray(new String[0]));
178 system.stop(runtime);
179 AssertionUtils.assertEquals(new String[] { "stop.application",
180 "stop.environment" }, _tracker
181 .getEvents(Thread.currentThread()).toArray(new String[0]));
185 public void testCompositeWithWrongProvidedInfo() {
187 Component environment = new Environment();
188 Component application = new Application();
189 Container system = new Container("all", new Component[] {
190 environment, application },
191 new ProvidedInterface[] { new DefaultProvidedInterface(
192 "float", Float.class) },
193 new DefaultRequiredInterface[0]);
195 } catch (SystemAssemblyException e) {
201 public void testCompositeRequiredInterfaceNotProvided() {
203 Component environment = new Environment();
204 Component application = new Application();
205 Container system = new Container("all", new Component[] {
206 environment, application }, new ProvidedInterface[0],
207 new RequiredInterface[] { new DefaultRequiredInterface(
208 "string", String.class) });
210 } catch (SystemAssemblyException e) {
216 public void testCompositeWithSuperfluousRequiredInfo() {
217 Component environment = new Environment();
218 Component application = new Application();
219 Container system = new Container("all", new Component[] { environment,
220 application }, new ProvidedInterface[0],
221 new RequiredInterface[] { new DefaultRequiredInterface("float",
223 system.getRequiredInterfaces()[0]
224 .setProvider(new DefaultProvidedInterface("hallo", Float.class));
226 RequiredInterface[] required = system.getRequiredInterfaces();
227 assertEquals(1, required.length);
228 ProvidedInterface[] provided = system.getProvidedInterfaces();
229 assertEquals(0, provided.length);
232 public void testCompositeWithExternalDependencesNotProvided() {
234 Component environment = new Environment();
235 Component application = new Application();
236 Container system = new Container("all",
237 new Component[] { application }, new ProvidedInterface[0],
238 application.getRequiredInterfaces());
240 } catch (SystemAssemblyException e) {
247 public void testDuplicateComponent() {
249 Component comp1 = new Application();
250 Component comp2 = new Application();
251 Container system = new Container("top");
252 system.addComponent(comp1).addComponent(comp2);
253 } catch (SystemAssemblyException e) {
259 public void testInconsistentHierarchy() {
261 Component comp = new Application();
262 Container system = new Container("top").addComponent(comp);
263 Container system2 = new Container("top2").addComponent(comp);
264 } catch (SystemAssemblyException e) {
270 public void testCompositeWithExternalDependencesProvided() {
272 Component environment = new Environment();
273 Component application = new Application();
274 Container system = new Container("all",
275 new Component[] { application }, new ProvidedInterface[0],
276 application.getRequiredInterfaces());
277 environment.start(new DefaultScope(new ProvidedInterface[0]));
278 system.getRequiredInterfaces()[0].setProvider(environment
279 .getProvidedInterfaces()[0]);
280 system.getRequiredInterfaces()[1].setProvider(environment
281 .getProvidedInterfaces()[1]);
284 RequiredInterface[] required = system.getRequiredInterfaces();
285 assertEquals(2, required.length);
286 ProvidedInterface[] provided = system.getProvidedInterfaces();
287 assertEquals(0, provided.length);
291 public void testAmbiguousInterfaces() {
293 Component environment1 = new Environment();
294 Component environment2 = new Environment();
295 Component application = new Application();
296 Container container = new Container("root", new Component[] {
297 environment1, environment2, application },
298 new ProvidedInterface[0], new RequiredInterface[0]);
301 } catch (SystemAssemblyException e) {
307 public void testIncompleteRequirements() {
309 Component application = new Application();
310 Container system = new Container("all",
311 new Component[] { application }, new ProvidedInterface[0],
312 new RequiredInterface[0]);
314 } catch (SystemAssemblyException e) {
320 public void testEnvironmentApplicationRollbackOnException()
322 IMocksControl control = EasyMock.createStrictControl();
324 Environment environment = new Environment(_tracker);
325 Application application = control.createMock(Application.class,
326 new ConstructorArgs(Application.class.getConstructor()),
327 Application.class.getDeclaredMethod("doStart", Scope.class));
329 application.doStart(EasyMockMatchers.anyObject(Scope.class));
330 EasyMock.expectLastCall().andThrow(new RuntimeException());
334 Container container = new Container("root", new Component[] {
335 environment, application }, new ProvidedInterface[0],
336 new RequiredInterface[0]);
339 } catch (RuntimeException e) {
340 AssertionUtils.assertEquals(new String[] { "start.environment",
341 "stop.environment" }, _tracker.getEvents(
342 Thread.currentThread()).toArray(new String[0]));
348 public void testEnvironmentApplicationRollbackOnExceptionWithExceptionOnStop()
350 IMocksControl control = EasyMock.createControl();
352 Environment environment = new Environment(_tracker);
353 // Application 1 will throw an exception while stopping.
354 Application application1 = control.createMock(Application.class,
355 new ConstructorArgs(Application.class.getConstructor()),
356 Application.class.getDeclaredMethod("doStop", Object.class));
358 application1.doStop(EasyMock.anyObject());
359 EasyMock.expectLastCall().andThrow(new RuntimeException());
361 // application 2 will throw an exception while starting
362 Application application2 = control.createMock(Application.class,
363 new ConstructorArgs(Application.class
364 .getConstructor(String.class), "application2"),
365 Application.class.getDeclaredMethod("doStart", Scope.class));
367 application2.doStart(EasyMockMatchers.anyObject(Scope.class));
368 EasyMock.expectLastCall().andThrow(new RuntimeException());
373 Container container = new Container("root", new Component[] {
374 environment, application1, application2 },
375 new ProvidedInterface[0], new RequiredInterface[0]);
378 } catch (RuntimeException e) {
379 AssertionUtils.assertEquals(new String[] { "start.environment",
380 "stop.environment" }, _tracker.getEvents(
381 Thread.currentThread()).toArray(new String[0]));
387 public void testOptionalRequiredInterfaceProvidedOptionalInternal() {
388 Application application = new Application(true);
389 Container container = new Container("top",
390 new Component[] { application }, new ProvidedInterface[0],
391 Application.required(true));
392 Environment env = new Environment();
393 container.getRequiredInterfaces()[0].setProvider(env
394 .getProvidedInterfaces()[0]);
395 container.getRequiredInterfaces()[1].setProvider(env
396 .getProvidedInterfaces()[1]);
397 Scope external = new DefaultScope(env.getProvidedInterfaces());
400 container.start(external);
401 assertSame(env.getProvidedInterfaces()[0], container
402 .getRequiredInterfaces()[0].getProvider());
403 assertSame(env.getProvidedInterfaces()[1], container
404 .getRequiredInterfaces()[1].getProvider());
405 assertSame(env.getProvidedInterfaces()[0], application
406 .getRequiredInterfaces()[0].getProvider());
407 assertSame(env.getProvidedInterfaces()[1], application
408 .getRequiredInterfaces()[1].getProvider());
411 public void testOptionalRequiredInterfaceNotProvidedOptionalInternal() {
412 Application application = new Application(true);
413 Container container = new Container("top",
414 new Component[] { application }, new ProvidedInterface[0],
415 Application.required(true));
416 Environment env = new Environment();
417 container.getRequiredInterfaces()[0].setProvider(env
418 .getProvidedInterfaces()[0]);
419 Scope external = new DefaultScope(new ProvidedInterface[0]);
420 external.publishInterface(env.getProvidedInterfaces()[0], env
422 container.start(external);
423 assertSame(env.getProvidedInterfaces()[0], container
424 .getRequiredInterfaces()[0].getProvider());
425 assertNull(container.getRequiredInterfaces()[1].getProvider());
426 assertSame(env.getProvidedInterfaces()[0], application
427 .getRequiredInterfaces()[0].getProvider());
428 assertNull(application.getRequiredInterfaces()[1].getProvider());
431 public void testOptionalRequiredInterfaceProvidedMandatoryInternal() {
432 Application application = new Application();
433 Container container = new Container("top",
434 new Component[] { application }, new ProvidedInterface[0],
435 Application.required(true));
436 Environment env = new Environment();
437 container.getRequiredInterfaces()[0].setProvider(env
438 .getProvidedInterfaces()[0]);
439 container.getRequiredInterfaces()[1].setProvider(env
440 .getProvidedInterfaces()[1]);
442 assertSame(env.getProvidedInterfaces()[0], container
443 .getRequiredInterfaces()[0].getProvider());
444 assertSame(env.getProvidedInterfaces()[1], container
445 .getRequiredInterfaces()[1].getProvider());
446 assertSame(env.getProvidedInterfaces()[0], application
447 .getRequiredInterfaces()[0].getProvider());
448 assertSame(env.getProvidedInterfaces()[1], application
449 .getRequiredInterfaces()[1].getProvider());
452 public void testSealed() {
453 final Container container = new Container("xx");
454 assertFalse(container.isSealed());
456 assertTrue(container.isSealed());
458 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
460 public void run() throws Exception {
461 container.addComponent(new Application());
463 }, SystemAssemblyException.class);
465 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
467 public void run() throws Exception {
468 container.addRestriction(new InterfaceRestriction() {
470 public boolean isViolated(Component aClient,
471 RequiredInterface aRequired, Component aServer,
472 ProvidedInterface aProvided) {
477 }, SystemAssemblyException.class);
478 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
480 public void run() throws Exception {
481 container.addProvidedInterface(new DefaultProvidedInterface(
482 "xx", String.class));
484 }, SystemAssemblyException.class);
486 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
488 public void run() throws Exception {
489 container.addRequiredInterface(new DefaultRequiredInterface(
490 "xx", String.class));
492 }, SystemAssemblyException.class);
495 public void testRestriction() {
496 Environment env1 = new Environment("env1");
497 Environment env2 = new Environment("env2");
498 Application app = new Application("app");
499 Container container = new Container("top").addComponent(env1)
500 .addComponent(env2).addComponent(app);
501 container.addRestriction(new DefaultInterfaceRestriction("app", null,
504 assertEquals(env1.getString(), app.getString());
505 assertFalse(env2.getString().equals(app.getString()));