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