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