(no commit message)
[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                 Component environment = new Environment(_tracker);
90                 Component 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         }
105
106         public void testApplicationEnvironment() {
107                 try {
108                         Component environment = new Environment();
109                         Component application = new Application();
110                         Container container = new Container("root", new Component[] {
111                                         application, environment }, new ProvidedInterface[0],
112                                         new RequiredInterface[0]);
113                         container.start();
114                 } catch (SystemAssemblyException e) {
115                         // e.printStackTrace();
116                         return;
117                 }
118                 fail();
119         }
120
121         public void testComposite() {
122                 Component environment = new Environment(_tracker);
123                 Component application = new Application(_tracker);
124                 assertEquals(0, _tracker.getEventCount());
125                 assertEquals(Status.NOT_STARTED, environment.getStatus());
126                 assertEquals(Status.NOT_STARTED, application.getStatus());
127
128                 Container system = new Container("all", new Component[] { environment,
129                                 application }, new ProvidedInterface[0],
130                                 new RequiredInterface[0]);
131                 assertEquals(Status.NOT_STARTED, system.getStatus());
132                 system.start();
133                 RequiredInterface[] required = system.getRequiredInterfaces();
134                 assertEquals(0, required.length);
135                 ProvidedInterface[] provided = system.getProvidedInterfaces();
136                 assertEquals(0, provided.length);
137                 assertEquals(Status.RUNNING, environment.getStatus());
138                 assertEquals(Status.RUNNING, application.getStatus());
139                 assertEquals(Status.RUNNING, system.getStatus());
140
141                 AssertionUtils.assertEquals(new String[] { "start.environment",
142                                 "start.application" }, _tracker.getEvents(
143                                 Thread.currentThread()).toArray(new String[0]));
144                 _tracker.clear();
145
146                 system.stop();
147                 assertEquals(Status.STOPPED, environment.getStatus());
148                 assertEquals(Status.STOPPED, application.getStatus());
149                 assertEquals(Status.STOPPED, system.getStatus());
150
151                 AssertionUtils.assertEquals(new String[] { "stop.application",
152                                 "stop.environment" }, _tracker
153                                 .getEvents(Thread.currentThread()).toArray(new String[0]));
154
155         }
156
157         public void testCompositeWithWrongProvidedInfo() {
158                 try {
159                         Component environment = new Environment();
160                         Component application = new Application();
161                         Container system = new Container("all", new Component[] {
162                                         environment, application },
163                                         new ProvidedInterface[] { new DefaultProvidedInterface(
164                                                         "string", String.class) },
165                                         new DefaultRequiredInterface[0]);
166                 } catch (SystemAssemblyException e) {
167                         return;
168                 }
169                 fail();
170         }
171
172         public void testCompositeRequiredInterfaceNotProvided() {
173                 try {
174                         Component environment = new Environment();
175                         Component application = new Application();
176                         Container system = new Container("all", new Component[] {
177                                         environment, application }, new ProvidedInterface[0],
178                                         new RequiredInterface[] { new DefaultRequiredInterface(
179                                                         "string", String.class) });
180                         system.start();
181                 } catch (SystemAssemblyException e) {
182                         return;
183                 }
184                 fail();
185         }
186
187         public void testCompositeWithSuperfluousRequiredInfo() {
188                 Component environment = new Environment();
189                 Component application = new Application();
190                 Container system = new Container("all", new Component[] { environment,
191                                 application }, new ProvidedInterface[0],
192                                 new RequiredInterface[] { new DefaultRequiredInterface(
193                                                 "string", String.class) });
194                 system.getRequiredInterfaces()[0]
195                                 .setProvider(new DefaultProvidedInterface("hallo", String.class));
196                 system.start();
197                 RequiredInterface[] required = system.getRequiredInterfaces();
198                 assertEquals(1, required.length);
199                 ProvidedInterface[] provided = system.getProvidedInterfaces();
200                 assertEquals(0, provided.length);
201         }
202
203         public void testCompositeWithExternalDependencesNotProvided() {
204                 try {
205                         Component environment = new Environment();
206                         Component application = new Application();
207                         Container system = new Container("all",
208                                         new Component[] { application }, new ProvidedInterface[0],
209                                         application.getRequiredInterfaces());
210                         system.start();
211                 } catch (SystemAssemblyException e) {
212                         return;
213                 }
214                 fail();
215
216         }
217
218         public void testCompositeWithExternalDependencesProvided() {
219
220                 Component environment = new Environment();
221                 Component application = new Application();
222                 Container system = new Container("all",
223                                 new Component[] { application }, new ProvidedInterface[0],
224                                 application.getRequiredInterfaces());
225                 environment.start();
226                 system.getRequiredInterfaces()[0].setProvider(environment
227                                 .getProvidedInterfaces()[0]);
228                 system.getRequiredInterfaces()[1].setProvider(environment
229                                 .getProvidedInterfaces()[1]);
230
231                 system.start();
232                 RequiredInterface[] required = system.getRequiredInterfaces();
233                 assertEquals(2, required.length);
234                 ProvidedInterface[] provided = system.getProvidedInterfaces();
235                 assertEquals(0, provided.length);
236
237         }
238
239         public void testAmbiguousInterfaces() {
240                 try {
241                         Component environment1 = new Environment();
242                         Component environment2 = new Environment();
243                         Component application = new Application();
244                         Container container = new Container("root", new Component[] {
245                                         environment1, environment2, application },
246                                         new ProvidedInterface[0], new RequiredInterface[0]);
247                         container.start();
248
249                 } catch (SystemAssemblyException e) {
250                         return;
251                 }
252                 fail();
253         }
254
255         public void testIncompleteRequirements() {
256                 try {
257                         Component application = new Application();
258                         Container system = new Container("all",
259                                         new Component[] { application }, new ProvidedInterface[0],
260                                         new RequiredInterface[0]);
261                         system.start();
262                 } catch (SystemAssemblyException e) {
263                         return;
264                 }
265                 fail();
266         }
267
268         public void testEnvironmentApplicationRollbackOnException()
269                         throws Exception {
270                 IMocksControl control = EasyMock.createStrictControl();
271
272                 Environment environment = new Environment(_tracker);
273                 Application application = control.createMock(Application.class,
274                                 new ConstructorArgs(Application.class.getConstructor()),
275                                 Application.class.getDeclaredMethod("doStart"));
276
277                 application.doStart();
278                 EasyMock.expectLastCall().andThrow(new RuntimeException());
279                 control.replay();
280
281                 try {
282                         Container container = new Container("root", new Component[] {
283                                         environment, application }, new ProvidedInterface[0],
284                                         new RequiredInterface[0]);
285
286                         container.start();
287                 } catch (RuntimeException e) {
288                         AssertionUtils.assertEquals(new String[] { "start.environment",
289                                         "stop.environment" }, _tracker.getEvents(
290                                         Thread.currentThread()).toArray(new String[0]));
291                         ProvidedInterface[] envServices = environment.getRunningInterfaces();
292                         assertEquals(0, envServices.length);
293                         assertNull(environment.getProvidedInterfaces()[0].getImplementation());
294                         assertNull(environment.getProvidedInterfaces()[0].getImplementation());
295                         return;
296                 }
297                 fail();
298         }
299
300         public void testEnvironmentApplicationRollbackOnExceptionWithExceptionOnStop()
301                         throws Exception {
302                 IMocksControl control = EasyMock.createControl();
303
304                 Environment environment = new Environment(_tracker);
305                 // Application 1 will throw an exception while stopping.
306                 Application application1 = control.createMock(Application.class,
307                                 new ConstructorArgs(Application.class.getConstructor()),
308                                 Application.class.getDeclaredMethod("doStop"));
309
310                 application1.doStop();
311                 EasyMock.expectLastCall().andThrow(new RuntimeException());
312                 
313                 // application 2 will throw an exception while starting
314                 Application application2 = control.createMock(Application.class,
315                                 new ConstructorArgs(Application.class.getConstructor()),
316                                 Application.class.getDeclaredMethod("doStart"));
317
318                 application2.doStart();
319                 EasyMock.expectLastCall().andThrow(new RuntimeException());
320                 
321                 control.replay();
322
323                 try {
324                         Container container = new Container("root", new Component[] {
325                                         environment, application1, application2 }, new ProvidedInterface[0],
326                                         new RequiredInterface[0]);
327
328                         container.start();
329                 } catch (RuntimeException e) {
330                         AssertionUtils.assertEquals(new String[] { "start.environment", 
331                                         "stop.environment" }, _tracker.getEvents(
332                                         Thread.currentThread()).toArray(new String[0]));
333                         ProvidedInterface[] envServices = environment.getRunningInterfaces();
334                         assertEquals(0, envServices.length);
335                         assertNull(environment.getProvidedInterfaces()[0].getImplementation());
336                         assertNull(environment.getProvidedInterfaces()[0].getImplementation());
337                         return;
338                 }
339                 fail();
340         }
341 }