offline building of site deploy to improve performance.
[utils] / system / spring / src / test / java / org / wamblee / system / spring / SpringComponentTest.java
1 /*
2  * Copyright 2005-2010 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.spring;
17
18 import junit.framework.TestCase;
19
20 import org.wamblee.io.ClassPathResource;
21
22 import org.wamblee.system.core.DefaultProvidedInterface;
23 import org.wamblee.system.core.DefaultRequiredInterface;
24 import org.wamblee.system.core.DefaultScope;
25 import org.wamblee.system.core.ProvidedInterface;
26 import org.wamblee.system.core.RequiredInterface;
27 import org.wamblee.system.core.Scope;
28 import org.wamblee.system.core.SystemAssemblyException;
29
30 import org.wamblee.test.EventTracker;
31
32 import java.io.IOException;
33
34 import java.util.HashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Properties;
38
39 /**
40  * 
41  * @author $author$
42  * @version $Revision$
43  */
44 public class SpringComponentTest extends TestCase {
45     private static final String HELLO_SERVICE_SPRING_XML = "test.org.wamblee.system.spring.xml";
46
47     private static final String HELLO_SERVICE_SPRING_WITH_REQS_XML = "test.org.wamblee.system.springWithRequirements.xml";
48
49     private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML = "test.org.wamblee.system.springWithProperties.xml";
50
51     private static final String HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML2 = "test.org.wamblee.system.springWithProperties2.xml";
52
53     private static final String PROPERTY_FILE = "test.org.wamblee.system.spring.properties";
54
55     private static EventTracker<String> EVENT_TRACKER;
56
57     private Scope externalScope;
58
59     public static EventTracker<String> getEventTracker() { 
60         return EVENT_TRACKER;
61     }
62     
63     @Override
64     protected void setUp() throws Exception {
65         super.setUp();
66         EVENT_TRACKER = new EventTracker<String>();
67         externalScope = new DefaultScope(new ProvidedInterface[0]);
68     }
69
70     public void testBlackboxSystem() {
71         SpringComponent system = new SpringComponent("system",
72             new String[] { HELLO_SERVICE_SPRING_XML },
73             new HashMap<String, ProvidedInterface>(),
74             new HashMap<RequiredInterface, String>());
75
76         Scope runtime = system.start(externalScope);
77         assertEquals(0, externalScope.getProvidedInterfaces().size());
78
79         system.stop(runtime);
80     }
81
82     public void testOneProvidedService() {
83         Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
84         provided.put("helloService", new DefaultProvidedInterface("hello",
85             HelloService.class));
86
87         SpringComponent system = new SpringComponent("system",
88             new String[] { HELLO_SERVICE_SPRING_XML }, provided,
89             new HashMap<RequiredInterface, String>());
90         Scope runtime = system.start(externalScope);
91         List<ProvidedInterface> services = runtime.getProvidedInterfaces();
92
93         assertEquals(1, services.size());
94
95         Object service = runtime.getInterfaceImplementation(services.get(0),
96             Object.class);
97         assertTrue(service instanceof HelloService);
98
99         // BUG; Provided services should be made available in the external
100         // scope.
101         Object service2 = externalScope.getInterfaceImplementation(provided
102             .get("helloService"), Object.class);
103         assertSame(service, service2);
104
105         assertEquals("Hello world!", ((HelloService) service).say());
106         system.stop(runtime);
107     }
108
109     public void testWithProperties() throws IOException {
110         Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
111         provided.put("helloService", new DefaultProvidedInterface("hello",
112             HelloService.class));
113
114         SpringComponent system = new SpringComponent("system",
115             new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML },
116             provided, new HashMap<RequiredInterface, String>());
117         Properties props = new Properties();
118         props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
119         system.addProperties(props);
120
121         Scope scope = system.start(externalScope);
122         // BUG: Hello service was constructed multiple times. Once with the
123         // unprocessed property
124         // and another time with the processed property.
125         assertEquals(1, EVENT_TRACKER.getEventCount());
126
127         List<ProvidedInterface> services = scope.getProvidedInterfaces();
128         assertEquals("Property Value", scope.getInterfaceImplementation(
129             services.get(0), HelloService.class).say());
130     }
131
132     public void testWithPropertiesAsBean() throws IOException {
133         Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
134         provided.put("helloService", new DefaultProvidedInterface("hello",
135             HelloService2.class));
136
137         SpringComponent system = new SpringComponent("system",
138             new String[] { HELLO_SERVICE_SPRING_WITH_PROPERTIES_XML2 },
139             provided, new HashMap<RequiredInterface, String>());
140         Properties props = new Properties();
141         props.load(new ClassPathResource(PROPERTY_FILE).getInputStream());
142         system.addProperties("properties", props);
143
144         Scope scope = system.start(externalScope);
145
146         List<ProvidedInterface> services = scope.getProvidedInterfaces();
147
148         Properties props2 = scope.getInterfaceImplementation(services.get(0),
149             HelloService2.class).getProperties();
150         assertEquals(props, props2);
151     }
152
153     public void testWithMissingRequirement() {
154         try {
155             SpringComponent system = new SpringComponent("system",
156                 new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
157                 new HashMap<String, ProvidedInterface>(),
158                 new HashMap<RequiredInterface, String>());
159             system.start(externalScope);
160         } catch (SystemAssemblyException e) {
161             // e.printStackTrace();
162             return;
163         }
164
165         fail();
166     }
167
168     public void testWithRequirement() {
169         Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
170         required.put(new DefaultRequiredInterface("hello", HelloService.class),
171             "helloService");
172
173         SpringComponent system = new SpringComponent("system",
174             new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
175             new HashMap<String, ProvidedInterface>(), required);
176
177         HelloService helloObject = new HelloService("ladida");
178         ProvidedInterface helloService = new DefaultProvidedInterface("hello",
179             HelloService.class);
180         Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
181         scope.publishInterface(helloService, helloObject);
182         system.getRequiredInterfaces().get(0).setProvider(helloService);
183
184         Scope runtime = system.start(scope);
185         system.stop(runtime);
186     }
187
188     public void testWithRequirementAndProvidedService() {
189         Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
190         required.put(new DefaultRequiredInterface("hello", HelloService.class),
191             "helloService");
192
193         Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
194         provided.put("blaService", new DefaultProvidedInterface("bla",
195             BlaService.class));
196
197         SpringComponent system = new SpringComponent("system",
198             new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML }, provided,
199             required);
200
201         HelloService helloObject = new HelloService("ladida");
202         ProvidedInterface helloService = new DefaultProvidedInterface("hello",
203             HelloService.class);
204         Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
205         scope.publishInterface(helloService, helloObject);
206         system.getRequiredInterfaces().get(0).setProvider(helloService);
207
208         Scope runtime = system.start(scope);
209         ProvidedInterface started = runtime.getProvidedInterfaces().get(0);
210
211         Object impl = runtime.getInterfaceImplementation(started,
212             BlaService.class);
213         assertNotNull(impl);
214         assertTrue(impl instanceof BlaService);
215         assertEquals("ladida", ((BlaService) impl).execute());
216         system.stop(runtime);
217     }
218
219     /**
220      * Tests a scenario where a subclass of SpringComponent adds a new provided
221      * interface where the interface is provided by the subclass itself and not
222      * by the spring configs inside.
223      */
224     public void testWithProvidedFromSubClassNotFromConfig() {
225         Map<String, ProvidedInterface> provided = new HashMap<String, ProvidedInterface>();
226         provided.put("helloService", new DefaultProvidedInterface("hello",
227             HelloService.class));
228
229         SubSpringComponent system = new SubSpringComponent("system",
230             new String[] { HELLO_SERVICE_SPRING_XML }, provided,
231             new HashMap<RequiredInterface, String>());
232
233         Scope runtime = system.start(externalScope);
234         List<ProvidedInterface> services = runtime.getProvidedInterfaces();
235
236         assertEquals(2, services.size());
237
238         Object service = runtime.getInterfaceImplementation(services.get(0),
239             Object.class);
240         assertTrue(service instanceof HelloService);
241
242         // BUG; Provided services should be made available in the external
243         // scope.
244         Object service2 = externalScope.getInterfaceImplementation(provided
245             .get("helloService"), Object.class);
246         assertSame(service, service2);
247
248         Object floatsvc = externalScope.getInterfaceImplementation(system
249             .getProvidedInterfaces().get(1), Object.class);
250         assertTrue(floatsvc instanceof Float);
251         assertTrue((((Float) floatsvc).floatValue() - 100.345f) < 0.00001);
252
253         assertEquals("Hello world!", ((HelloService) service).say());
254         system.stop(runtime);
255     }
256
257     /**
258      * Tests the spring component with an additional requirement from the
259      * subclass which is not required by the spring config files inside.
260      */
261     public void testWithRequirementFromSubClass() {
262         Map<RequiredInterface, String> required = new HashMap<RequiredInterface, String>();
263         required.put(new DefaultRequiredInterface("hello", HelloService.class),
264             "helloService");
265
266         SpringComponent system = new SubSpringComponent2("system",
267             new String[] { HELLO_SERVICE_SPRING_WITH_REQS_XML },
268             new HashMap<String, ProvidedInterface>(), required);
269
270         HelloService helloObject = new HelloService("ladida");
271         ProvidedInterface helloService = new DefaultProvidedInterface("hello",
272             HelloService.class);
273
274         ProvidedInterface floatService = new DefaultProvidedInterface("float",
275             Float.class);
276
277         Scope scope = new DefaultScope(new ProvidedInterface[] { helloService });
278         scope.publishInterface(helloService, helloObject);
279         scope.publishInterface(floatService, 100.234f);
280         system.getRequiredInterfaces().get(0).setProvider(helloService);
281         system.getRequiredInterfaces().get(1).setProvider(floatService);
282
283         Scope runtime = system.start(scope);
284         system.stop(runtime);
285
286         assertEquals(100.234f,
287             ((Float) runtime.get("floatValue")).floatValue(), 0.0001f);
288     }
289 }