74eb43101d0fa461b30e8bd4b31dcf25fd68f479
[utils] / system / general / src / test / java / org / wamblee / system / core / 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.core;
17
18 import java.io.Serializable;
19 import java.util.Arrays;
20
21 import junit.framework.TestCase;
22
23 import org.easymock.classextension.ConstructorArgs;
24 import org.easymock.classextension.EasyMock;
25 import org.easymock.classextension.IMocksControl;
26 import org.wamblee.test.AssertionUtils;
27 import org.wamblee.test.EasyMockMatchers;
28 import org.wamblee.test.EventTracker;
29
30 public class ContainerTest extends TestCase {
31
32         private EventTracker<String> _tracker;
33
34         @Override
35         protected void setUp() throws Exception {
36                 super.setUp();
37                 _tracker = new EventTracker<String>();
38         }
39
40         private static class MyMultiple implements Serializable, Runnable {
41                 @Override
42                 public void run() {
43                         // Empty
44                 }
45         }
46
47         public void testFilterProvided() {
48                 RequiredInterface req1 = new DefaultRequiredInterface("name",
49                                 Runnable.class);
50                 RequiredInterface req2 = new DefaultRequiredInterface("name",
51                                 Serializable.class);
52                 ProvidedInterface prov1 = new DefaultProvidedInterface("name",
53                                 Runnable.class);
54                 ProvidedInterface prov2 = new DefaultProvidedInterface("name",
55                                 Serializable.class);
56                 ProvidedInterface prov3 = new DefaultProvidedInterface("name",
57                                 MyMultiple.class);
58
59                 AssertionUtils.assertEquals(new RequiredInterface[] { req1 }, Container
60                                 .filterRequiredServices(prov1, Arrays
61                                                 .asList(new RequiredInterface[] { req1 })));
62                 AssertionUtils.assertEquals(new RequiredInterface[] { req1 }, Container
63                                 .filterRequiredServices(prov1, Arrays
64                                                 .asList(new RequiredInterface[] { req1, req2 })));
65                 AssertionUtils.assertEquals(new RequiredInterface[] { req1, req2 },
66                                 Container.filterRequiredServices(prov3, Arrays
67                                                 .asList(new RequiredInterface[] { req1, req2 })));
68
69                 AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
70                                 Container.filterProvidedServices(req1, Arrays
71                                                 .asList(new ProvidedInterface[] { prov1 })));
72                 AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
73                                 Container.filterProvidedServices(req1, Arrays
74                                                 .asList(new ProvidedInterface[] { prov1, prov2 })));
75                 AssertionUtils.assertEquals(new ProvidedInterface[] { prov1, prov3 },
76                                 Container.filterProvidedServices(req1, Arrays
77                                                 .asList(new ProvidedInterface[] { prov1, prov3 })));
78         }
79
80         public void testEnvironmentApplication() {
81                 Environment environment = new Environment(_tracker);
82                 Application application = new Application(_tracker);
83                 Container container = new Container("root", new Component[] {
84                                 environment, application }, new ProvidedInterface[0],
85                                 new RequiredInterface[0]);
86
87                 Scope scope = container.start();
88                 AssertionUtils.assertEquals(new String[] { "start.environment",
89                                 "start.application" }, _tracker.getEvents(
90                                 Thread.currentThread()).toArray(new String[0]));
91                 assertEquals(0, scope.getProvidedInterfaces().length);
92                 
93                 assertEquals(environment.getString(), application.getString());
94                 assertEquals(environment.getInteger(), application.getInteger());
95
96         }
97
98         public void testApplicationEnvironment() {
99                 try {
100                         Component environment = new Environment();
101                         Component application = new Application();
102                         Container container = new Container("root", new Component[] {
103                                         application, environment }, new ProvidedInterface[0],
104                                         new RequiredInterface[0]);
105                         container.start();
106                 } catch (SystemAssemblyException e) {
107                         // e.printStackTrace();
108                         return;
109                 }
110                 fail();
111         }
112
113         public void testComposite() {
114                 Component environment = new Environment(_tracker);
115                 Component application = new Application(_tracker);
116                 assertEquals(0, _tracker.getEventCount());
117
118                 Container system = new Container("all", new Component[] { environment,
119                                 application }, new ProvidedInterface[0],
120                                 new RequiredInterface[0]);
121                 Scope runtime = system.start();
122                 RequiredInterface[] required = system.getRequiredInterfaces();
123                 assertEquals(0, required.length);
124                 ProvidedInterface[] provided = system.getProvidedInterfaces();
125                 assertEquals(0, provided.length);
126
127                 AssertionUtils.assertEquals(new String[] { "start.environment",
128                                 "start.application" }, _tracker.getEvents(
129                                 Thread.currentThread()).toArray(new String[0]));
130                 _tracker.clear();
131
132                 system.stop(runtime);
133                 AssertionUtils.assertEquals(new String[] { "stop.application",
134                                 "stop.environment" }, _tracker
135                                 .getEvents(Thread.currentThread()).toArray(new String[0]));
136
137         }
138
139         public void testCompositeWithWrongProvidedInfo() {
140                 try {
141                         Component environment = new Environment();
142                         Component application = new Application();
143                         Container system = new Container("all", new Component[] {
144                                         environment, application },
145                                         new ProvidedInterface[] { new DefaultProvidedInterface(
146                                                         "float", Float.class) },
147                                         new DefaultRequiredInterface[0]);
148                 } catch (SystemAssemblyException e) {
149                         return;
150                 }
151                 fail();
152         }
153
154         public void testCompositeRequiredInterfaceNotProvided() {
155                 try {
156                         Component environment = new Environment();
157                         Component application = new Application();
158                         Container system = new Container("all", new Component[] {
159                                         environment, application }, new ProvidedInterface[0],
160                                         new RequiredInterface[] { new DefaultRequiredInterface(
161                                                         "string", String.class) });
162                         system.start();
163                 } catch (SystemAssemblyException e) {
164                         return;
165                 }
166                 fail();
167         }
168
169         public void testCompositeWithSuperfluousRequiredInfo() {
170                 Component environment = new Environment();
171                 Component application = new Application();
172                 Container system = new Container("all", new Component[] { environment,
173                                 application }, new ProvidedInterface[0],
174                                 new RequiredInterface[] { new DefaultRequiredInterface(
175                                                 "float", Float.class) });
176                 system.getRequiredInterfaces()[0]
177                                 .setProvider(new DefaultProvidedInterface("hallo", Float.class));
178                 system.start();
179                 RequiredInterface[] required = system.getRequiredInterfaces();
180                 assertEquals(1, required.length);
181                 ProvidedInterface[] provided = system.getProvidedInterfaces();
182                 assertEquals(0, provided.length);
183         }
184
185         public void testCompositeWithExternalDependencesNotProvided() {
186                 try {
187                         Component environment = new Environment();
188                         Component application = new Application();
189                         Container system = new Container("all",
190                                         new Component[] { application }, new ProvidedInterface[0],
191                                         application.getRequiredInterfaces());
192                         system.start();
193                 } catch (SystemAssemblyException e) {
194                         return;
195                 }
196                 fail();
197
198         }
199
200         public void testCompositeWithExternalDependencesProvided() {
201
202                 Component environment = new Environment();
203                 Component application = new Application();
204                 Container system = new Container("all",
205                                 new Component[] { application }, new ProvidedInterface[0],
206                                 application.getRequiredInterfaces());
207                 environment.start(new DefaultScope(new ProvidedInterface[0]));
208                 system.getRequiredInterfaces()[0].setProvider(environment
209                                 .getProvidedInterfaces()[0]);
210                 system.getRequiredInterfaces()[1].setProvider(environment
211                                 .getProvidedInterfaces()[1]);
212
213                 system.start();
214                 RequiredInterface[] required = system.getRequiredInterfaces();
215                 assertEquals(2, required.length);
216                 ProvidedInterface[] provided = system.getProvidedInterfaces();
217                 assertEquals(0, provided.length);
218
219         }
220
221         public void testAmbiguousInterfaces() {
222                 try {
223                         Component environment1 = new Environment();
224                         Component environment2 = new Environment();
225                         Component application = new Application();
226                         Container container = new Container("root", new Component[] {
227                                         environment1, environment2, application },
228                                         new ProvidedInterface[0], new RequiredInterface[0]);
229                         container.start();
230
231                 } catch (SystemAssemblyException e) {
232                         return;
233                 }
234                 fail();
235         }
236
237         public void testIncompleteRequirements() {
238                 try {
239                         Component application = new Application();
240                         Container system = new Container("all",
241                                         new Component[] { application }, new ProvidedInterface[0],
242                                         new RequiredInterface[0]);
243                         system.start();
244                 } catch (SystemAssemblyException e) {
245                         return;
246                 }
247                 fail();
248         }
249
250         public void testEnvironmentApplicationRollbackOnException()
251                         throws Exception {
252                 IMocksControl control = EasyMock.createStrictControl();
253
254                 Environment environment = new Environment(_tracker);
255                 Application application = control.createMock(Application.class,
256                                 new ConstructorArgs(Application.class.getConstructor()),
257                                 Application.class.getDeclaredMethod("doStart", Scope.class));
258
259                 application.doStart(EasyMockMatchers.anyObject(Scope.class));
260                 EasyMock.expectLastCall().andThrow(new RuntimeException());
261                 control.replay();
262
263                 try {
264                         Container container = new Container("root", new Component[] {
265                                         environment, application }, new ProvidedInterface[0],
266                                         new RequiredInterface[0]);
267
268                         container.start();
269                 } catch (RuntimeException e) {
270                         AssertionUtils.assertEquals(new String[] { "start.environment",
271                                         "stop.environment" }, _tracker.getEvents(
272                                         Thread.currentThread()).toArray(new String[0]));
273                         return;
274                 }
275                 fail();
276         }
277
278         public void testEnvironmentApplicationRollbackOnExceptionWithExceptionOnStop()
279                         throws Exception {
280                 IMocksControl control = EasyMock.createControl();
281
282                 Environment environment = new Environment(_tracker);
283                 // Application 1 will throw an exception while stopping.
284                 Application application1 = control.createMock(Application.class,
285                                 new ConstructorArgs(Application.class.getConstructor()),
286                                 Application.class.getDeclaredMethod("doStop", Object.class));
287
288                 application1.doStop(EasyMock.anyObject());
289                 EasyMock.expectLastCall().andThrow(new RuntimeException());
290                 
291                 // application 2 will throw an exception while starting
292                 Application application2 = control.createMock(Application.class,
293                                 new ConstructorArgs(Application.class.getConstructor()),
294                                 Application.class.getDeclaredMethod("doStart", Scope.class));
295
296                 application2.doStart(EasyMockMatchers.anyObject(Scope.class));
297                 EasyMock.expectLastCall().andThrow(new RuntimeException());
298                 
299                 control.replay();
300
301                 try {
302                         Container container = new Container("root", new Component[] {
303                                         environment, application1, application2 }, new ProvidedInterface[0],
304                                         new RequiredInterface[0]);
305
306                         container.start();
307                 } catch (RuntimeException e) {
308                         AssertionUtils.assertEquals(new String[] { "start.environment", 
309                                         "stop.environment" }, _tracker.getEvents(
310                                         Thread.currentThread()).toArray(new String[0]));
311                         return;
312                 }
313                 fail();
314         }
315         
316         public void testOptionalRequiredInterfaceProvidedOptionalInternal() {
317                 Application application = new Application(true);
318                 Container container = new Container("top", new Component[] { application }, 
319                                 new ProvidedInterface[0], Application.required(true));
320                 Environment env = new Environment();
321                 container.getRequiredInterfaces()[0].setProvider(
322                                 env.getProvidedInterfaces()[0]); 
323                 container.getRequiredInterfaces()[1].setProvider(
324                                 env.getProvidedInterfaces()[1]);
325                 Scope external = new DefaultScope(env.getProvidedInterfaces());
326                 env.start(external); 
327                 
328             container.start(external);
329             assertSame(env.getProvidedInterfaces()[0], container.getRequiredInterfaces()[0].getProvider());
330             assertSame(env.getProvidedInterfaces()[1], container.getRequiredInterfaces()[1].getProvider());
331             assertSame(env.getProvidedInterfaces()[0], application.getRequiredInterfaces()[0].getProvider());
332             assertSame(env.getProvidedInterfaces()[1], application.getRequiredInterfaces()[1].getProvider());
333         }
334         
335         public void testOptionalRequiredInterfaceNotProvidedOptionalInternal() {
336                 Application application = new Application(true);
337                 Container container = new Container("top", new Component[] { application }, 
338                                 new ProvidedInterface[0], Application.required(true));
339                 Environment env = new Environment();
340                 container.getRequiredInterfaces()[0].setProvider(
341                                 env.getProvidedInterfaces()[0]);
342                 Scope external = new DefaultScope(new ProvidedInterface[0]); 
343                 external.publishInterface(env.getProvidedInterfaces()[0], env.getString());
344             container.start(external);
345             assertSame(env.getProvidedInterfaces()[0], container.getRequiredInterfaces()[0].getProvider());
346             assertNull(container.getRequiredInterfaces()[1].getProvider());
347             assertSame(env.getProvidedInterfaces()[0], application.getRequiredInterfaces()[0].getProvider());
348             assertNull(application.getRequiredInterfaces()[1].getProvider());
349         }
350         
351         public void testOptionalRequiredInterfaceProvidedMandatoryInternal() { 
352                 Application application = new Application();
353                 Container container = new Container("top", new Component[] { application }, 
354                                 new ProvidedInterface[0], Application.required(true));
355                 Environment env = new Environment();
356                 container.getRequiredInterfaces()[0].setProvider(
357                                 env.getProvidedInterfaces()[0]); 
358                 container.getRequiredInterfaces()[1].setProvider(
359                                 env.getProvidedInterfaces()[1]);
360             container.start();
361             assertSame(env.getProvidedInterfaces()[0], container.getRequiredInterfaces()[0].getProvider());
362             assertSame(env.getProvidedInterfaces()[1], container.getRequiredInterfaces()[1].getProvider());
363             assertSame(env.getProvidedInterfaces()[0], application.getRequiredInterfaces()[0].getProvider());
364             assertSame(env.getProvidedInterfaces()[1], application.getRequiredInterfaces()[1].getProvider());   
365         }
366 }