]> git.argeo.org Git - gpl/argeo-slc.git/blob - runtime/org.argeo.slc.unit/src/main/java/org/argeo/slc/equinox/unit/AbstractOsgiRuntimeTestCase.java
Update licence headers
[gpl/argeo-slc.git] / runtime / org.argeo.slc.unit / src / main / java / org / argeo / slc / equinox / unit / AbstractOsgiRuntimeTestCase.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
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.argeo.slc.equinox.unit;
17
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import junit.framework.TestCase;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.argeo.slc.SlcException;
28 import org.argeo.osgi.boot.OsgiBoot;
29 import org.eclipse.core.runtime.adaptor.EclipseStarter;
30 import org.osgi.framework.Bundle;
31 import org.osgi.framework.BundleContext;
32 import org.osgi.framework.InvalidSyntaxException;
33 import org.osgi.framework.ServiceReference;
34 import org.springframework.context.ApplicationContext;
35 import org.springframework.osgi.util.OsgiStringUtils;
36
37 @SuppressWarnings("restriction")
38 public abstract class AbstractOsgiRuntimeTestCase extends TestCase {
39 private final static Log log = LogFactory
40 .getLog(AbstractOsgiRuntimeTestCase.class);
41
42 protected OsgiBoot osgiBoot = null;
43
44 protected void installBundles() throws Exception {
45
46 }
47
48 public void setUp() throws Exception {
49 // To avoid xerces from the classpath being detected as the provider
50 System
51 .setProperty("javax.xml.parsers.DocumentBuilderFactory",
52 "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
53 System.setProperty("javax.xml.parsers.SAXParserFactory",
54 "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
55
56 BundleContext bundleContext = startRuntime();
57 osgiBoot = new OsgiBoot(bundleContext);
58 log.info("OSGi runtime started.");
59
60 installBundles();
61
62 List<String> bundlesToStart = getBundlesToStart();
63 osgiBoot.startBundles(bundlesToStart);
64 waitAllBundlesOk(bundlesToStart);
65 if (log.isTraceEnabled())
66 listInstalledBundles();
67 }
68
69 public void tearDown() throws Exception {
70 osgiBoot = null;
71 stopRuntime();
72 log.info("OSGi runtime stopped.");
73 }
74
75 protected BundleContext startRuntime() throws Exception {
76 String[] args = { "-console", "-clean" };
77 BundleContext bundleContext = EclipseStarter.startup(args, null);
78 return bundleContext;
79 }
80
81 protected void stopRuntime() throws Exception {
82 EclipseStarter.shutdown();
83 }
84
85 protected List<String> getBundlesToStart() {
86 return new ArrayList<String>();
87 }
88
89 protected void listInstalledBundles() {
90 BundleContext bundleContext = osgiBoot.getBundleContext();
91 Bundle[] bundles = bundleContext.getBundles();
92 for (int i = 0; i < bundles.length; i++) {
93 System.out.println(OsgiStringUtils.nullSafeSymbolicName(bundles[i])
94 + " [" + OsgiStringUtils.bundleStateAsString(bundles[i])
95 + "] " + bundles[i].getLocation());
96 }
97
98 }
99
100 protected Map<Bundle, ApplicationContext> getOsgiApplicationContexts()
101 throws Exception {
102 Map<Bundle, ApplicationContext> map = new HashMap<Bundle, ApplicationContext>();
103 BundleContext bundleContext = osgiBoot.getBundleContext();
104 ServiceReference[] srs = bundleContext.getServiceReferences(
105 ApplicationContext.class.getName(), null);
106 for (ServiceReference sr : srs) {
107 ApplicationContext context = (ApplicationContext) bundleContext
108 .getService(sr);
109 map.put(sr.getBundle(), context);
110 }
111 return map;
112 }
113
114 /** Wait for all bundles to be either RESOLVED or ACTIVE. */
115 protected void waitAllBundlesOk(List<String> bundlesToStart) {
116 BundleContext bundleContext = osgiBoot.getBundleContext();
117 long begin = System.currentTimeMillis();
118 long duration = 0;
119 boolean allBundlesOk = true;
120 StringBuffer badBundles = null;
121 while (duration < getResolvedTimeout()) {
122 badBundles = new StringBuffer();
123 for (Bundle bundle : bundleContext.getBundles()) {
124 if (bundle.getSymbolicName() != null
125 && bundle.getSymbolicName().startsWith(
126 "org.eclipse.jdt")) {
127 // don't check Eclipse SDK bundles
128 continue;
129 }
130
131 if (bundle.getState() == Bundle.INSTALLED) {
132 allBundlesOk = false;
133 badBundles
134 .append(OsgiStringUtils
135 .nullSafeSymbolicName(bundle)
136 + " ["
137 + OsgiStringUtils
138 .bundleStateAsString(bundle) + "]");
139 }
140
141 if (bundlesToStart.contains(bundle.getSymbolicName())
142 && bundle.getState() != Bundle.ACTIVE) {
143 allBundlesOk = false;
144 badBundles.append(OsgiStringUtils
145 .nullSafeSymbolicName(bundle)
146 + " ["
147 + OsgiStringUtils.bundleStateAsString(bundle)
148 + "]\n");
149 }
150 }
151
152 if (allBundlesOk)
153 break;// while
154
155 sleep(1000);
156
157 duration = System.currentTimeMillis() - begin;
158 }
159
160 if (!allBundlesOk) {
161 listInstalledBundles();
162 throw new SlcException(
163 "Some bundles are not at the proper status:\n" + badBundles);
164 }
165 }
166
167 /**
168 * Make sure that the application context of the started bundles starting
169 * with this prefix are properly initialized
170 */
171 protected void assertStartedBundlesApplicationContext(
172 String bundleSymbolicNamesPrefix) {
173 List<String> bundlesToStart = getBundlesToStart();
174 for (String bundleSName : bundlesToStart) {
175 if (bundleSName.startsWith(bundleSymbolicNamesPrefix))
176 assertBundleApplicationContext(bundleSName);
177 }
178 }
179
180 /**
181 * Make sure that the application context of this bundle is properly
182 * initialized
183 */
184 protected void assertBundleApplicationContext(String bundleSymbolicName) {
185 String filter = "(Bundle-SymbolicName=" + bundleSymbolicName + ")";
186 // Wait for application context to be ready
187 try {
188 ServiceReference[] srs = getServiceRefSynchronous(
189 ApplicationContext.class.getName(), filter);
190 if (srs == null)
191 throw new SlcException("No application context for "
192 + bundleSymbolicName);
193 } catch (InvalidSyntaxException e) {
194 throw new SlcException(
195 "Unexpected exception when looking for application context for bundle "
196 + bundleSymbolicName, e);
197 }
198 log.info("Application context of bundle " + bundleSymbolicName
199 + " is initalized.");
200 }
201
202 protected ServiceReference[] getServiceRefSynchronous(String clss,
203 String filter) throws InvalidSyntaxException {
204 // FIXME: factorize
205 if (log.isTraceEnabled())
206 log.debug("Filter: '" + filter + "'");
207 ServiceReference[] sfs = null;
208 boolean waiting = true;
209 long begin = System.currentTimeMillis();
210 do {
211 sfs = getBundleContext().getServiceReferences(clss, filter);
212
213 if (sfs != null)
214 waiting = false;
215
216 sleep(100);
217 if (System.currentTimeMillis() - begin > getDefaultTimeout())
218 throw new SlcException("Search of services " + clss
219 + " with filter " + filter + " timed out.");
220 } while (waiting);
221
222 return sfs;
223 }
224
225 protected BundleContext getBundleContext() {
226 return osgiBoot.getBundleContext();
227 }
228
229 /** Default is 30s */
230 protected long getResolvedTimeout() {
231 return 30 * 1000l;
232 }
233
234 /** Default is 10s */
235 protected long getDefaultTimeout() {
236 return 10 * 1000l;
237 }
238
239 final protected void sleep(long duration) {
240 try {
241 Thread.sleep(1000);
242 } catch (InterruptedException e) {
243 // silent
244 }
245 }
246 }