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