e61c023ca0e35ae66908b04259a0d99bee520a28
[utils] / system / general / src / test / java / org / wamblee / system / container / ContainerTest.java
1 /*
2  * Copyright 2007 the original author or authors.
3  * 
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
7  * 
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  * 
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.
15  */
16 package org.wamblee.system.container;
17
18 import java.io.Serializable;
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import junit.framework.TestCase;
23
24 import org.easymock.classextension.ConstructorArgs;
25 import org.easymock.classextension.EasyMock;
26 import org.easymock.classextension.IMocksControl;
27 import org.wamblee.general.Pair;
28 import org.wamblee.system.core.Component;
29 import org.wamblee.system.core.DefaultProvidedInterface;
30 import org.wamblee.system.core.DefaultRequiredInterface;
31 import org.wamblee.system.core.DefaultScope;
32 import org.wamblee.system.core.Environment;
33 import org.wamblee.system.core.ProvidedInterface;
34 import org.wamblee.system.core.RequiredInterface;
35 import org.wamblee.system.core.Scope;
36 import org.wamblee.system.core.StringComponent;
37 import org.wamblee.system.core.SystemAssemblyException;
38 import org.wamblee.test.AssertionUtils;
39 import org.wamblee.test.EasyMockMatchers;
40 import org.wamblee.test.EventTracker;
41
42 public class ContainerTest extends TestCase {
43
44         private EventTracker<String> _tracker;
45
46         @Override
47         protected void setUp() throws Exception {
48                 super.setUp();
49                 _tracker = new EventTracker<String>();
50         }
51
52         private static class MyMultiple implements Serializable, Runnable {
53                 @Override
54                 public void run() {
55                         // Empty
56                 }
57         }
58
59         private List<Pair<ProvidedInterface, Component>> createProvidedInput(
60                         ProvidedInterface[] aProvided, Component aProvider) {
61                 List<Pair<ProvidedInterface, Component>> result = new ArrayList<Pair<ProvidedInterface, Component>>();
62                 for (ProvidedInterface provided : aProvided) {
63                         result.add(new Pair<ProvidedInterface, Component>(provided,
64                                         aProvider));
65                 }
66                 return result;
67         }
68
69         public void testEnvironmentApplication() {
70                 Environment environment = new Environment(_tracker);
71                 Application application = new Application(_tracker);
72                 Container container = new Container("root", new Component[] {
73                                 environment, application }, new ProvidedInterface[0],
74                                 new RequiredInterface[0]);
75                 Scope scope = container.start();
76                 assertTrue(container.isSealed());
77                 AssertionUtils.assertEquals(new String[] { "start.environment",
78                                 "start.application" }, _tracker.getEvents(
79                                 Thread.currentThread()).toArray(new String[0]));
80                 assertEquals(0, scope.getProvidedInterfaces().size());
81
82                 assertEquals(environment.getString(), application.getString());
83                 assertEquals(environment.getInteger(), application.getInteger());
84
85         }
86
87         public void testEnvironmentApplicationSimpleConstructor() {
88                 Environment environment = new Environment(_tracker);
89                 Application application = new Application(_tracker);
90                 Container container = new Container("root").addComponent(environment)
91                                 .addComponent(application);
92
93                 Scope scope = container.start();
94                 AssertionUtils.assertEquals(new String[] { "start.environment",
95                                 "start.application" }, _tracker.getEvents(
96                                 Thread.currentThread()).toArray(new String[0]));
97                 assertEquals(0, scope.getProvidedInterfaces().size());
98
99                 assertEquals(environment.getString(), application.getString());
100                 assertEquals(environment.getInteger(), application.getInteger());
101
102         }
103
104         public void testApplicationEnvironment() {
105                 try {
106                         Component<?> environment = new Environment();
107                         Component<?> application = new Application();
108                         Container container = new Container("root", new Component[] {
109                                         application, environment }, new ProvidedInterface[0],
110                                         new RequiredInterface[0]);
111                         container.start();
112                 } catch (SystemAssemblyException e) {
113                         // e.printStackTrace();
114                         return;
115                 }
116                 fail();
117         }
118
119         public void testComposite() {
120                 Component<?> environment = new Environment(_tracker);
121                 Component<?> application = new Application(_tracker);
122                 assertEquals(0, _tracker.getEventCount());
123
124                 Container system = new Container("all", new Component[] { environment,
125                                 application }, new ProvidedInterface[0],
126                                 new RequiredInterface[0]);
127                 Scope runtime = system.start();
128                 List<RequiredInterface> required = system.getRequiredInterfaces();
129                 assertEquals(0, required.size());
130                 List<ProvidedInterface> provided = system.getProvidedInterfaces();
131                 assertEquals(0, provided.size());
132
133                 AssertionUtils.assertEquals(new String[] { "start.environment",
134                                 "start.application" }, _tracker.getEvents(
135                                 Thread.currentThread()).toArray(new String[0]));
136                 _tracker.clear();
137
138                 system.stop(runtime);
139                 AssertionUtils.assertEquals(new String[] { "stop.application",
140                                 "stop.environment" }, _tracker
141                                 .getEvents(Thread.currentThread()).toArray(new String[0]));
142
143         }
144
145         public void testCompositeWithWrongProvidedInfo() {
146                 try {
147                         Component<?> environment = new Environment();
148                         Component<?> application = new Application();
149                         Container system = new Container("all", new Component[] {
150                                         environment, application },
151                                         new ProvidedInterface[] { new DefaultProvidedInterface(
152                                                         "float", Float.class) },
153                                         new DefaultRequiredInterface[0]);
154                         system.validate();
155                 } catch (SystemAssemblyException e) {
156                         return;
157                 }
158                 fail();
159         }
160
161         public void testCompositeRequiredInterfaceNotProvided() {
162                 try {
163                         Component<?> environment = new Environment();
164                         Component<?> application = new Application();
165                         Container system = new Container("all", new Component[] {
166                                         environment, application }, new ProvidedInterface[0],
167                                         new RequiredInterface[] { new DefaultRequiredInterface(
168                                                         "string", String.class) });
169                         system.start();
170                 } catch (SystemAssemblyException e) {
171                         return;
172                 }
173                 fail();
174         }
175
176         public void testCompositeWithSuperfluousRequiredInfo() {
177                 Component<?> environment = new Environment();
178                 Component<?> application = new Application();
179                 Container system = new Container("all", new Component[] { environment,
180                                 application }, new ProvidedInterface[0],
181                                 new RequiredInterface[] { new DefaultRequiredInterface("float",
182                                                 Float.class) });
183                 system.getRequiredInterfaces().get(0).setProvider(
184                                 new DefaultProvidedInterface("hallo", Float.class));
185                 system.start();
186                 List<RequiredInterface> required = system.getRequiredInterfaces();
187                 assertEquals(1, required.size());
188                 List<ProvidedInterface> provided = system.getProvidedInterfaces();
189                 assertEquals(0, provided.size());
190         }
191
192         public void testCompositeWithExternalDependencesNotProvided() {
193                 try {
194                         Component<?> application = new Application();
195
196                         Container system = new Container("all",
197                                         new Component[] { application }, new ProvidedInterface[0],
198                                         application.getRequiredInterfaces().toArray(
199                                                         new RequiredInterface[0]));
200                         system.start();
201                 } catch (SystemAssemblyException e) {
202                         return;
203                 }
204                 fail();
205         }
206
207         public void testDuplicateComponent() {
208                 try {
209                         Component<?> comp1 = new Application();
210                         Component<?> comp2 = new Application();
211                         Container system = new Container("top");
212                         system.addComponent(comp1).addComponent(comp2);
213                 } catch (SystemAssemblyException e) {
214                         return;
215                 }
216                 fail();
217         }
218
219         public void testInconsistentHierarchy() {
220                 try {
221                         Component<?> comp = new Application();
222                         Container system = new Container("top").addComponent(comp);
223                         Container system2 = new Container("top2").addComponent(comp);
224                 } catch (SystemAssemblyException e) {
225                         return;
226                 }
227                 fail();
228         }
229
230         public void testCompositeWithExternalDependencesProvided() {
231
232                 Component<?> environment = new Environment();
233                 Component<?> application = new Application();
234                 Container system = new Container("all",
235                                 new Component[] { application }, new ProvidedInterface[0],
236                                 application.getRequiredInterfaces().toArray(
237                                                 new RequiredInterface[0]));
238                 environment.start(new DefaultScope(new ProvidedInterface[0]));
239                 system.getRequiredInterfaces().get(0).setProvider(
240                                 environment.getProvidedInterfaces().get(0));
241                 system.getRequiredInterfaces().get(1).setProvider(
242                                 environment.getProvidedInterfaces().get(1));
243
244                 system.start();
245                 List<RequiredInterface> required = system.getRequiredInterfaces();
246                 assertEquals(2, required.size());
247                 List<ProvidedInterface> provided = system.getProvidedInterfaces();
248                 assertEquals(0, provided.size());
249
250         }
251
252         public void testAmbiguousInterfaces() {
253                 try {
254                         Component<?> environment1 = new Environment();
255                         Component<?> environment2 = new Environment();
256                         Component<?> application = new Application();
257                         Container container = new Container("root", new Component[] {
258                                         environment1, environment2, application },
259                                         new ProvidedInterface[0], new RequiredInterface[0]);
260                         container.start();
261
262                 } catch (SystemAssemblyException e) {
263                         return;
264                 }
265                 fail();
266         }
267
268         public void testIncompleteRequirements() {
269                 try {
270                         Component<?> application = new Application();
271                         Container system = new Container("all",
272                                         new Component[] { application }, new ProvidedInterface[0],
273                                         new RequiredInterface[0]);
274                         system.start();
275                 } catch (SystemAssemblyException e) {
276                         return;
277                 }
278                 fail();
279         }
280
281         public void testEnvironmentApplicationRollbackOnException()
282                         throws Exception {
283                 IMocksControl control = EasyMock.createStrictControl();
284
285                 Environment environment = new Environment(_tracker);
286                 Application application = control.createMock(Application.class,
287                                 new ConstructorArgs(Application.class.getConstructor()),
288                                 Application.class.getDeclaredMethod("doStart", Scope.class));
289
290                 application.doStart(EasyMockMatchers.anyObject(Scope.class));
291                 EasyMock.expectLastCall().andThrow(new RuntimeException());
292                 control.replay();
293
294                 try {
295                         Container container = new Container("root", new Component[] {
296                                         environment, application }, new ProvidedInterface[0],
297                                         new RequiredInterface[0]);
298
299                         container.start();
300                 } catch (RuntimeException e) {
301                         AssertionUtils.assertEquals(new String[] { "start.environment",
302                                         "stop.environment" }, _tracker.getEvents(
303                                         Thread.currentThread()).toArray(new String[0]));
304                         return;
305                 }
306                 fail();
307         }
308
309         public void testEnvironmentApplicationRollbackOnExceptionWithExceptionOnStop()
310                         throws Exception {
311                 IMocksControl control = EasyMock.createControl();
312
313                 Environment environment = new Environment(_tracker);
314                 // Application 1 will throw an exception while stopping.
315                 Application application1 = control.createMock(Application.class,
316                                 new ConstructorArgs(Application.class.getConstructor()),
317                                 Application.class.getDeclaredMethod("doStop", Object.class));
318
319                 application1.doStop(EasyMock.anyObject());
320                 EasyMock.expectLastCall().andThrow(new RuntimeException());
321
322                 // application 2 will throw an exception while starting
323                 Application application2 = control.createMock(Application.class,
324                                 new ConstructorArgs(Application.class
325                                                 .getConstructor(String.class), "application2"),
326                                 Application.class.getDeclaredMethod("doStart", Scope.class));
327
328                 application2.doStart(EasyMockMatchers.anyObject(Scope.class));
329                 EasyMock.expectLastCall().andThrow(new RuntimeException());
330
331                 control.replay();
332
333                 try {
334                         Container container = new Container("root", new Component[] {
335                                         environment, application1, application2 },
336                                         new ProvidedInterface[0], new RequiredInterface[0]);
337
338                         container.start();
339                 } catch (RuntimeException e) {
340                         AssertionUtils.assertEquals(new String[] { "start.environment",
341                                         "stop.environment" }, _tracker.getEvents(
342                                         Thread.currentThread()).toArray(new String[0]));
343                         return;
344                 }
345                 fail();
346         }
347
348         public void testOptionalRequiredInterfaceProvidedOptionalInternal() {
349                 Application application = new Application(true);
350                 Container container = new Container("top",
351                                 new Component[] { application }, new ProvidedInterface[0],
352                                 Application.required(true));
353                 Environment env = new Environment();
354                 container.getRequiredInterfaces().get(0).setProvider(
355                                 env.getProvidedInterfaces().get(0));
356                 container.getRequiredInterfaces().get(1).setProvider(
357                                 env.getProvidedInterfaces().get(1));
358                 Scope external = new DefaultScope(env.getProvidedInterfaces());
359                 env.start(external);
360
361                 container.start(external);
362                 assertSame(env.getProvidedInterfaces().get(0), container
363                                 .getRequiredInterfaces().get(0).getProvider());
364                 assertSame(env.getProvidedInterfaces().get(1), container
365                                 .getRequiredInterfaces().get(1).getProvider());
366                 assertSame(env.getProvidedInterfaces().get(0), application
367                                 .getRequiredInterfaces().get(0).getProvider());
368                 assertSame(env.getProvidedInterfaces().get(1), application
369                                 .getRequiredInterfaces().get(1).getProvider());
370         }
371
372         public void testOptionalRequiredInterfaceNotProvidedOptionalInternal() {
373                 Application application = new Application(true);
374                 Container container = new Container("top",
375                                 new Component[] { application }, new ProvidedInterface[0],
376                                 Application.required(true));
377                 Environment env = new Environment();
378                 container.getRequiredInterfaces().get(0).setProvider(
379                                 env.getProvidedInterfaces().get(0));
380                 Scope external = new DefaultScope(new ProvidedInterface[0]);
381                 external.publishInterface(env.getProvidedInterfaces().get(0), env
382                                 .getString());
383                 container.start(external);
384                 assertSame(env.getProvidedInterfaces().get(0), container
385                                 .getRequiredInterfaces().get(0).getProvider());
386                 assertNull(container.getRequiredInterfaces().get(1).getProvider());
387                 assertSame(env.getProvidedInterfaces().get(0), application
388                                 .getRequiredInterfaces().get(0).getProvider());
389                 assertNull(application.getRequiredInterfaces().get(1).getProvider());
390         }
391
392         public void testOptionalRequiredInterfaceProvidedMandatoryInternal() {
393                 Application application = new Application();
394                 Container container = new Container("top",
395                                 new Component[] { application }, new ProvidedInterface[0],
396                                 Application.required(true));
397                 Environment env = new Environment();
398                 container.getRequiredInterfaces().get(0).setProvider(
399                                 env.getProvidedInterfaces().get(0));
400                 container.getRequiredInterfaces().get(1).setProvider(
401                                 env.getProvidedInterfaces().get(1));
402                 try {
403                         container.start();
404                 } catch (SystemAssemblyException e) {
405                         return;
406                 }
407                 fail();
408         }
409
410         public void testSealed() {
411                 final Container container = new Container("xx");
412                 assertFalse(container.isSealed());
413                 container.start();
414                 assertTrue(container.isSealed());
415
416                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
417                         @Override
418                         public void run() throws Exception {
419                                 container.addComponent(new Application());
420                         }
421                 }, SystemAssemblyException.class);
422
423                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
424                         @Override
425                         public void run() throws Exception {
426                                 container.connectRequiredProvided("x", "y", "a", "b");
427                         }
428                 }, SystemAssemblyException.class);
429                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
430                         @Override
431                         public void run() throws Exception {
432                                 container.connectExternalRequired("x", "y", "a");
433                         }
434                 }, SystemAssemblyException.class);
435                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
436                         @Override
437                         public void run() throws Exception {
438                                 container.connectExternalProvided("x", "y", "z");
439                         }
440                 }, SystemAssemblyException.class);
441                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
442                         @Override
443                         public void run() throws Exception {
444                                 container.addProvidedInterface(new DefaultProvidedInterface(
445                                                 "xx", String.class));
446                         }
447                 }, SystemAssemblyException.class);
448
449                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
450                         @Override
451                         public void run() throws Exception {
452                                 container.addRequiredInterface(new DefaultRequiredInterface(
453                                                 "xx", String.class));
454                         }
455                 }, SystemAssemblyException.class);
456         }
457
458         public void testRestriction() {
459                 Environment env1 = new Environment("env1");
460                 Environment env2 = new Environment("env2");
461                 Application app = new Application("app");
462                 Container container = new Container("top").addComponent(env1)
463                                 .addComponent(env2).addComponent(app);
464                 container.connectRequiredProvided("app", null, "env1", null);
465                 container.start();
466                 assertEquals(env1.getString(), app.getString());
467                 assertEquals(env1.getInteger(), app.getInteger());
468                 assertFalse(env2.getString().equals(app.getString()));
469                 assertFalse(env2.getInteger().equals(app.getInteger()));
470         }
471
472         public void testRestrictionWithFromAndToInterfaceName() {
473                 Environment env1 = new Environment("env1");
474                 Environment env2 = new Environment("env2");
475                 Application app = new Application("app");
476                 Container container = new Container("top").addComponent(env1)
477                                 .addComponent(env2).addComponent(app);
478                 container.connectRequiredProvided("app", app.getRequiredInterfaces()
479                                 .get(0).getName(), "env1", env1.getProvidedInterfaces().get(0)
480                                 .getName());
481                 container.connectRequiredProvided("app", app.getRequiredInterfaces()
482                                 .get(1).getName(), "env2", env2.getProvidedInterfaces().get(1)
483                                 .getName());
484                 container.start();
485                 assertEquals(env1.getString(), app.getString());
486                 assertEquals(env2.getInteger(), app.getInteger());
487                 assertFalse(env2.getString().equals(app.getString()));
488                 assertFalse(env1.getInteger().equals(app.getInteger()));
489         }
490
491         public void testRestrictionWrongComponentNames() {
492                 Environment env1 = new Environment("env1");
493                 Environment env2 = new Environment("env2");
494                 Application app = new Application("app");
495                 final Container container = new Container("top").addComponent(env1)
496                                 .addComponent(env2).addComponent(app);
497                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
498                         @Override
499                         public void run() throws Exception {
500                                 container.connectRequiredProvided("app2", null, "env1", null);
501                         }
502                 }, SystemAssemblyException.class);
503                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
504                         @Override
505                         public void run() throws Exception {
506                                 container.connectRequiredProvided("app", null, "env3", null);
507                         }
508                 }, SystemAssemblyException.class);
509         }
510
511         public void testRestrictionWrongInterfaceNames() {
512                 final Environment env1 = new Environment("env1");
513                 Environment env2 = new Environment("env2");
514                 final Application app = new Application("app");
515                 final Container container = new Container("top").addComponent(env1)
516                                 .addComponent(env2).addComponent(app);
517                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
518                         @Override
519                         public void run() throws Exception {
520                                 container.connectRequiredProvided("app", app
521                                                 .getRequiredInterfaces().get(0).getName()
522                                                 + "xxx", "env1", null);
523                         }
524                 }, SystemAssemblyException.class);
525                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
526                         @Override
527                         public void run() throws Exception {
528                                 container.connectRequiredProvided("app", null, "env1", env1
529                                                 .getProvidedInterfaces().get(0).getName()
530                                                 + "yyy");
531                         }
532                 }, SystemAssemblyException.class);
533         }
534
535         public void testProvidedInDifferentScopes() {
536                 // Scoping problem occurred. Externally and internally provided
537                 // components clashed
538                 // because unique id generation in the scope was wrong.
539
540                 StringComponent str = new StringComponent("string");
541                 Application app = new Application("app");
542                 Container container = new Container("top").addComponent(str)
543                                 .addComponent(app);
544                 container.addRequiredInterface(new DefaultRequiredInterface("integer",
545                                 Integer.class));
546
547                 ProvidedInterface provided = new DefaultProvidedInterface("hallo",
548                                 Integer.class);
549                 container.getRequiredInterfaces().get(0).setProvider(provided);
550
551                 Scope external = new DefaultScope(new ProvidedInterface[0]);
552                 external.publishInterface(provided, 100);
553                 Scope scope = container.start(external);
554         }
555
556         public void testProvidedInterfaces() {
557                 Environment env = new Environment(_tracker);
558                 Container envcontainer = new Container("0").addComponent(env)
559                                 .addProvidedInterface(
560                                                 new DefaultProvidedInterface("string", String.class))
561                                 .addProvidedInterface(
562                                                 new DefaultProvidedInterface("integer", Integer.class));
563                 Scope scope = envcontainer.start();
564
565                 AssertionUtils.assertEquals(new String[] { "start.environment" },
566                                 _tracker.getEvents(Thread.currentThread()).toArray(
567                                                 new String[0]));
568
569                 envcontainer.stop(scope);
570         }
571
572         public void testCoupleTwoContainers() {
573                 Environment env = new Environment(_tracker);
574                 Container envcontainer = new Container("0").addComponent(env)
575                                 .addProvidedInterface(
576                                                 new DefaultProvidedInterface("string", String.class))
577                                 .addProvidedInterface(
578                                                 new DefaultProvidedInterface("integer", Integer.class));
579
580                 Application app = new Application(_tracker);
581                 Container appcontainer = new Container("1").addComponent(app)
582                                 .addRequiredInterface(
583                                                 new DefaultRequiredInterface("string", String.class))
584                                 .addRequiredInterface(
585                                                 new DefaultRequiredInterface("integer", Integer.class));
586
587                 Container top = new Container("top");
588                 top.addComponent(envcontainer).addComponent(appcontainer);
589
590                 top.start();
591                 AssertionUtils.assertEquals(new String[] { "start.environment",
592                                 "start.application" }, _tracker.getEvents(
593                                 Thread.currentThread()).toArray(new String[0]));
594
595         }
596
597         public void testNonUniqueRequiredInterface() {
598                 final Container container = new Container("top");
599                 container.addRequiredInterface(new DefaultRequiredInterface("i",
600                                 Integer.class));
601                 container.addRequiredInterface(new DefaultRequiredInterface("x",
602                                 String.class));
603                 container.addRequiredInterface(new DefaultRequiredInterface("y",
604                                 String.class));
605
606                 Application app = new Application("1");
607                 container.addComponent(app);
608
609                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
610                         @Override
611                         public void run() throws Exception {
612                                 container.start();
613                         }
614                 }, SystemAssemblyException.class);
615
616                 container.connectExternalRequired("1", app.getRequiredInterfaces().get(
617                                 0).getName(), "y");
618
619                 ProvidedInterface i = new DefaultProvidedInterface("i", Integer.class);
620                 ProvidedInterface x = new DefaultProvidedInterface("x", String.class);
621                 ProvidedInterface y = new DefaultProvidedInterface("y", String.class);
622
623                 Scope externalScope = new DefaultScope(new ProvidedInterface[0]);
624
625                 externalScope.publishInterface(i, 100);
626                 externalScope.publishInterface(x, "x-value");
627                 externalScope.publishInterface(y, "y-value");
628
629                 container.getRequiredInterfaces().get(0).setProvider(i);
630                 container.getRequiredInterfaces().get(1).setProvider(x);
631                 container.getRequiredInterfaces().get(2).setProvider(y);
632
633                 Scope runtime = container.start(externalScope);
634
635                 assertEquals("y-value", app.getString());
636
637         }
638
639         public void testNonUniqueRequiredInterfaceWrongNames() {
640                 final Container container = new Container("top");
641                 container.addRequiredInterface(new DefaultRequiredInterface("i",
642                                 Integer.class));
643                 container.addRequiredInterface(new DefaultRequiredInterface("x",
644                                 String.class));
645                 container.addRequiredInterface(new DefaultRequiredInterface("y",
646                                 String.class));
647
648                 final Application app = new Application("1");
649                 container.addComponent(app);
650
651                 // wrong component name.
652                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
653                         @Override
654                         public void run() throws Exception {
655                                 container.connectExternalRequired("2", "x", "y");
656                         }
657                 }, SystemAssemblyException.class);
658
659                 // Wrong interface name of component.
660                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
661                         @Override
662                         public void run() throws Exception {
663                                 container.connectExternalRequired("1", app
664                                                 .getRequiredInterfaces().get(0).getName()
665                                                 + "xxx", "y");
666                         }
667                 }, SystemAssemblyException.class);
668
669                 // Wrong external interface name of container
670                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
671                         @Override
672                         public void run() throws Exception {
673                                 container.connectExternalRequired("1", app
674                                                 .getRequiredInterfaces().get(0).getName(), "z");
675                         }
676                 }, SystemAssemblyException.class);
677         }
678
679         public void testNonUniqueProvidedInterface() {
680
681                 final Container container = new Container("top")
682                                 .addProvidedInterface(new DefaultProvidedInterface("external",
683                                                 String.class));
684                 Environment env1 = new Environment("env1");
685                 Environment env2 = new Environment("env2");
686
687                 container.addComponent(env1);
688                 container.addComponent(env2);
689
690                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
691                         @Override
692                         public void run() throws Exception {
693                                 container.start();
694                         }
695                 }, SystemAssemblyException.class);
696
697                 // now choose env2
698
699                 container.connectExternalProvided(container.getProvidedInterfaces()
700                                 .get(0).getName(), env2.getName(), env2.getProvidedInterfaces()
701                                 .get(0).getName());
702
703                 Scope scope = container.start();
704
705                 // check the value of the provided interface of the container
706
707                 String value = scope.getInterfaceImplementation(container
708                                 .getProvidedInterfaces().get(0), String.class);
709                 assertNotNull(value);
710                 assertEquals(value, env2.getString());
711                 assertFalse(value.equals(env1.getString()));
712         }
713
714         public void testNonUniqueProvidedInterfaceWrongNames() {
715
716                 final Container container = new Container("top")
717                                 .addProvidedInterface(new DefaultProvidedInterface("external",
718                                                 String.class));
719                 final Environment env1 = new Environment("env1");
720                 final Environment env2 = new Environment("env2");
721
722                 container.addComponent(env1);
723                 container.addComponent(env2);
724
725                 // Wrong external provided interface name
726                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
727                         @Override
728                         public void run() throws Exception {
729                                 container.connectExternalProvided(container
730                                                 .getProvidedInterfaces().get(0).getName()
731                                                 + "xx", "env1", env1.getProvidedInterfaces().get(0)
732                                                 .getName());
733                         }
734                 }, SystemAssemblyException.class);
735
736                 // Wrong provided interface name.
737                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
738                         @Override
739                         public void run() throws Exception {
740                                 container.connectExternalProvided(container
741                                                 .getProvidedInterfaces().get(0).getName(), "env1", env1
742                                                 .getProvidedInterfaces().get(0).getName()
743                                                 + "xx");
744                         }
745                 }, SystemAssemblyException.class);
746
747                 // Wrong provided component
748                 AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
749                         @Override
750                         public void run() throws Exception {
751                                 container.connectExternalProvided(container
752                                                 .getProvidedInterfaces().get(0).getName(), "env3", env1
753                                                 .getProvidedInterfaces().get(0).getName());
754                         }
755                 }, SystemAssemblyException.class);
756         }
757 }