1 package com.atlassian.plugin.osgi.container.felix;
2
3 import com.atlassian.plugin.event.impl.DefaultPluginEventManager;
4 import com.atlassian.plugin.osgi.container.impl.DefaultPackageScannerConfiguration;
5 import com.atlassian.plugin.osgi.container.impl.DefaultOsgiPersistentCache;
6 import com.atlassian.plugin.osgi.container.OsgiContainerException;
7 import com.atlassian.plugin.test.PluginJarBuilder;
8 import com.atlassian.plugin.test.PluginTestUtils;
9 import junit.framework.TestCase;
10 import org.apache.commons.io.FileUtils;
11 import org.osgi.framework.Bundle;
12 import org.osgi.framework.BundleException;
13 import org.osgi.framework.Constants;
14
15 import java.io.File;
16 import java.io.IOException;
17 import java.io.FilenameFilter;
18 import java.net.URISyntaxException;
19 import java.net.URL;
20
21 public class TestFelixOsgiContainerManager extends TestCase
22 {
23 private File tmpdir;
24 private FelixOsgiContainerManager felix;
25 private URL frameworkBundlesUrl = getClass().getResource("/nothing.zip");
26
27 @Override
28 public void setUp() throws Exception
29 {
30 super.setUp();
31 tmpdir = PluginTestUtils.createTempDirectory(TestFelixOsgiContainerManager.class);
32 felix = new FelixOsgiContainerManager(frameworkBundlesUrl, new DefaultOsgiPersistentCache(tmpdir), new DefaultPackageScannerConfiguration(),
33 null, new DefaultPluginEventManager());
34 }
35
36 @Override
37 public void tearDown() throws Exception
38 {
39 if (felix != null && felix.isRunning())
40 {
41 for (Bundle bundle : felix.getBundles())
42 {
43 try
44 {
45 bundle.uninstall();
46 }
47 catch (BundleException ignored) {}
48 }
49 }
50 if (felix != null)
51 felix.stop();
52 felix = null;
53 tmpdir = null;
54 super.tearDown();
55 }
56
57 public void testDetectXercesOverride()
58 {
59 felix.detectXercesOverride("foo.bar,baz.jim");
60 felix.detectXercesOverride("foo.bar,org.apache.xerces.util;version=\"1.0\",baz.jim");
61 felix.detectXercesOverride("foo.bar,org.apache.xerces.util;version=\"1.0\"");
62
63 try
64 {
65 felix.detectXercesOverride("foo.bar,org.apache.xerces.util");
66 fail("Should fail validation");
67 }
68 catch (OsgiContainerException ex)
69 {
70
71 }
72
73 try
74 {
75 felix.detectXercesOverride("org.apache.xerces.util");
76 fail("Should fail validation");
77 }
78 catch (OsgiContainerException ex)
79 {
80
81 }
82
83 try
84 {
85 felix.detectXercesOverride("org.apache.xerces.util,bar.baz");
86 fail("Should fail validation");
87 }
88 catch (OsgiContainerException ex)
89 {
90
91 }
92
93 }
94
95 public void testDeleteDirectory() throws IOException
96 {
97 File dir = new File(tmpdir, "base");
98 dir.mkdir();
99 File subdir = new File(dir, "subdir");
100 subdir.mkdir();
101 File kid = File.createTempFile("foo", "bar", subdir);
102
103 FileUtils.deleteDirectory(dir);
104 assertTrue(!kid.exists());
105 assertTrue(!subdir.exists());
106 assertTrue(!dir.exists());
107 }
108
109 public void testStartStop()
110 {
111 FilenameFilter filter = new FilenameFilter()
112 {
113 public boolean accept(File file, String s)
114 {
115 return s.startsWith("felix");
116 }
117 };
118 int filesNamedFelix = tmpdir.listFiles(filter).length;
119 felix.start();
120 assertTrue(felix.isRunning());
121 assertEquals(1, felix.getBundles().length);
122 felix.stop();
123 assertEquals(filesNamedFelix, tmpdir.listFiles(filter).length);
124 }
125
126 public void testInstallBundle() throws URISyntaxException
127 {
128 felix.start();
129 assertEquals(1, felix.getBundles().length);
130 File jar = new File(getClass().getResource("/myapp-1.0.jar").toURI());
131 felix.installBundle(jar);
132 assertEquals(2, felix.getBundles().length);
133 }
134
135 public void testBootDelegation() throws Exception
136 {
137
138 File pluginServer = new PluginJarBuilder("plugin")
139 .addResource("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n" +
140 "Bundle-Version: 1.0\n" +
141 "Bundle-SymbolicName: my.server\n" +
142 "Bundle-ManifestVersion: 2\n" +
143 "Export-Package: my.server\n")
144 .addJava("my.server.ServerClass", "package my.server; public class ServerClass extends junit.framework.TestCase {}")
145 .build();
146
147
148
149
150 File pluginClient = new PluginJarBuilder("plugin")
151 .addResource("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n" +
152 "Bundle-Version: 1.0\n" +
153 "Bundle-SymbolicName: my.client\n" +
154 "Bundle-ManifestVersion: 2\n" +
155 "Import-Package: my.server\n")
156 .addJava("my.client.ClientClass", "package my.client; public class ClientClass {" +
157 "public ClientClass() throws ClassNotFoundException {" +
158 "getClass().getClassLoader().loadClass(\"my.server.ServerClass\");" +
159 "}}")
160 .build();
161
162 felix.start();
163 Bundle serverBundle = felix.installBundle(pluginServer);
164 serverBundle.start();
165 Bundle clientBundle = felix.installBundle(pluginClient);
166 clientBundle.start();
167 try
168 {
169 clientBundle.loadClass("my.client.ClientClass").newInstance();
170 fail("Expected exception: NoClassDefFoundError for junit.framework.TestCase");
171 }
172 catch (NoClassDefFoundError expected)
173 {
174 }
175 felix.stop();
176
177
178 System.setProperty("atlassian.org.osgi.framework.bootdelegation", "junit.framework.*");
179 try
180 {
181 felix.start();
182 serverBundle = felix.installBundle(pluginServer);
183 serverBundle.start();
184 clientBundle = felix.installBundle(pluginClient);
185 clientBundle.start();
186 clientBundle.loadClass("my.client.ClientClass").newInstance();
187 felix.stop();
188 }
189 finally
190 {
191 System.clearProperty("atlassian.org.osgi.framework.bootdelegation");
192 }
193 }
194
195 public void testInstallBundleTwice() throws URISyntaxException, IOException, BundleException
196 {
197 File plugin = new PluginJarBuilder("plugin")
198 .addResource("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n" +
199 "Import-Package: javax.swing\n" +
200 "Bundle-Version: 1.0\n" +
201 "Bundle-SymbolicName: my.foo.symbolicName\n" +
202 "Bundle-ManifestVersion: 2\n")
203 .addResource("foo.txt", "foo")
204 .build();
205
206 File pluginUpdate = new PluginJarBuilder("plugin")
207 .addResource("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n" +
208 "Import-Package: javax.swing\n" +
209 "Bundle-Version: 1.0\n" +
210 "Bundle-SymbolicName: my.foo.symbolicName\n" +
211 "Bundle-ManifestVersion: 2\n")
212 .addResource("bar.txt", "bar")
213 .build();
214
215 felix.start();
216 assertEquals(1, felix.getBundles().length);
217 Bundle bundle = felix.installBundle(plugin);
218 assertEquals(2, felix.getBundles().length);
219 assertEquals("my.foo.symbolicName", bundle.getSymbolicName());
220 assertEquals("1.0", bundle.getHeaders().get(Constants.BUNDLE_VERSION));
221 assertEquals(Bundle.INSTALLED, bundle.getState());
222 assertNotNull(bundle.getResource("foo.txt"));
223 assertNull(bundle.getResource("bar.txt"));
224 bundle.start();
225 assertEquals(Bundle.ACTIVE, bundle.getState());
226 Bundle bundleUpdate = felix.installBundle(pluginUpdate);
227 assertEquals(2, felix.getBundles().length);
228 assertEquals(Bundle.INSTALLED, bundleUpdate.getState());
229 bundleUpdate.start();
230 assertEquals(Bundle.ACTIVE, bundleUpdate.getState());
231 assertNull(bundleUpdate.getResource("foo.txt"));
232 assertNotNull(bundleUpdate.getResource("bar.txt"));
233 }
234
235 public void testInstallBundleTwiceDifferentSymbolicNames() throws URISyntaxException, IOException, BundleException
236 {
237 File plugin = new PluginJarBuilder("plugin")
238 .addResource("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n" +
239 "Import-Package: javax.swing\n" +
240 "Bundle-Version: 1.0\n" +
241 "Bundle-SymbolicName: my.foo\n" +
242 "Atlassian-Plugin-Key: my.foo.symbolicName\n" +
243 "Bundle-ManifestVersion: 2\n")
244 .addResource("foo.txt", "foo")
245 .build();
246
247 File pluginUpdate = new PluginJarBuilder("plugin")
248 .addResource("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n" +
249 "Import-Package: javax.swing\n" +
250 "Bundle-Version: 1.0\n" +
251 "Atlassian-Plugin-Key: my.foo.symbolicName\n" +
252 "Bundle-SymbolicName: my.bar\n" +
253 "Bundle-ManifestVersion: 2\n")
254 .addResource("bar.txt", "bar")
255 .build();
256
257 felix.start();
258 assertEquals(1, felix.getBundles().length);
259 Bundle bundle = felix.installBundle(plugin);
260 assertEquals(2, felix.getBundles().length);
261 assertEquals("1.0", bundle.getHeaders().get(Constants.BUNDLE_VERSION));
262 assertEquals(Bundle.INSTALLED, bundle.getState());
263 assertNotNull(bundle.getResource("foo.txt"));
264 assertNull(bundle.getResource("bar.txt"));
265 bundle.start();
266 assertEquals(Bundle.ACTIVE, bundle.getState());
267 Bundle bundleUpdate = felix.installBundle(pluginUpdate);
268 assertEquals(2, felix.getBundles().length);
269 assertEquals(Bundle.INSTALLED, bundleUpdate.getState());
270 bundleUpdate.start();
271 assertEquals(Bundle.ACTIVE, bundleUpdate.getState());
272 assertNull(bundleUpdate.getResource("foo.txt"));
273 assertNotNull(bundleUpdate.getResource("bar.txt"));
274 }
275
276 public void testInstallFailure() throws Exception
277 {
278 File plugin = new PluginJarBuilder("plugin")
279 .addResource("META-INF/MANIFEST.MF", "Manifest-Version: 1.0\n" +
280 "Bundle-Version: 1.0\n" +
281 "Import-Package: foo.missing.package\n" +
282 "Bundle-SymbolicName: my.foo.symbolicName\n" +
283 "Bundle-ManifestVersion: 2\n" )
284 .build();
285 felix.start();
286
287 Bundle bundle = felix.installBundle(plugin);
288 try {
289 bundle.loadClass("foo.bar");
290 fail("Should have thrown exception");
291 } catch (ClassNotFoundException ex) {
292
293 }
294 }
295 }