2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.slc
.equinox
.unit
;
18 import java
.util
.ArrayList
;
19 import java
.util
.HashMap
;
20 import java
.util
.List
;
23 import junit
.framework
.TestCase
;
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
;
37 @SuppressWarnings("restriction")
38 public abstract class AbstractOsgiRuntimeTestCase
extends TestCase
{
39 private final static Log log
= LogFactory
40 .getLog(AbstractOsgiRuntimeTestCase
.class);
42 protected OsgiBoot osgiBoot
= null;
44 protected void installBundles() throws Exception
{
48 public void setUp() throws Exception
{
49 // To avoid xerces from the classpath being detected as the provider
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");
56 BundleContext bundleContext
= startRuntime();
57 osgiBoot
= new OsgiBoot(bundleContext
);
58 log
.info("OSGi runtime started.");
62 List
<String
> bundlesToStart
= getBundlesToStart();
63 osgiBoot
.startBundles(bundlesToStart
);
64 waitAllBundlesOk(bundlesToStart
);
65 if (log
.isTraceEnabled())
66 listInstalledBundles();
69 public void tearDown() throws Exception
{
72 log
.info("OSGi runtime stopped.");
75 protected BundleContext
startRuntime() throws Exception
{
76 String
[] args
= { "-console", "-clean" };
77 BundleContext bundleContext
= EclipseStarter
.startup(args
, null);
81 protected void stopRuntime() throws Exception
{
82 EclipseStarter
.shutdown();
85 protected List
<String
> getBundlesToStart() {
86 return new ArrayList
<String
>();
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());
100 protected Map
<Bundle
, ApplicationContext
> getOsgiApplicationContexts()
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
109 map
.put(sr
.getBundle(), context
);
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();
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
131 if (bundle
.getState() == Bundle
.INSTALLED
) {
132 allBundlesOk
= false;
134 .append(OsgiStringUtils
135 .nullSafeSymbolicName(bundle
)
138 .bundleStateAsString(bundle
) + "]");
141 if (bundlesToStart
.contains(bundle
.getSymbolicName())
142 && bundle
.getState() != Bundle
.ACTIVE
) {
143 allBundlesOk
= false;
144 badBundles
.append(OsgiStringUtils
145 .nullSafeSymbolicName(bundle
)
147 + OsgiStringUtils
.bundleStateAsString(bundle
)
157 duration
= System
.currentTimeMillis() - begin
;
161 listInstalledBundles();
162 throw new SlcException(
163 "Some bundles are not at the proper status:\n" + badBundles
);
168 * Make sure that the application context of the started bundles starting
169 * with this prefix are properly initialized
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
);
181 * Make sure that the application context of this bundle is properly
184 protected void assertBundleApplicationContext(String bundleSymbolicName
) {
185 String filter
= "(Bundle-SymbolicName=" + bundleSymbolicName
+ ")";
186 // Wait for application context to be ready
188 ServiceReference
[] srs
= getServiceRefSynchronous(
189 ApplicationContext
.class.getName(), filter
);
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
);
198 log
.info("Application context of bundle " + bundleSymbolicName
199 + " is initalized.");
202 protected ServiceReference
[] getServiceRefSynchronous(String clss
,
203 String filter
) throws InvalidSyntaxException
{
205 if (log
.isTraceEnabled())
206 log
.debug("Filter: '" + filter
+ "'");
207 ServiceReference
[] sfs
= null;
208 boolean waiting
= true;
209 long begin
= System
.currentTimeMillis();
211 sfs
= getBundleContext().getServiceReferences(clss
, filter
);
217 if (System
.currentTimeMillis() - begin
> getDefaultTimeout())
218 throw new SlcException("Search of services " + clss
219 + " with filter " + filter
+ " timed out.");
225 protected BundleContext
getBundleContext() {
226 return osgiBoot
.getBundleContext();
229 /** Default is 30s */
230 protected long getResolvedTimeout() {
234 /** Default is 10s */
235 protected long getDefaultTimeout() {
239 final protected void sleep(long duration
) {
242 } catch (InterruptedException e
) {