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