diff options
author | John Ross | 2013-08-09 14:29:15 +0000 |
---|---|---|
committer | John Ross | 2013-08-12 20:21:34 +0000 |
commit | 07670433d11dd8ebcca2377523e4e9d176ccdb5a (patch) | |
tree | b6a0ffa444b629a8893bd27e1a35520088057e19 /bundles/org.eclipse.equinox.ds.tests | |
parent | 55f96a565cf574519f8f98173516a351cc24ac19 (diff) | |
download | rt.equinox.bundles-07670433d11dd8ebcca2377523e4e9d176ccdb5a.tar.gz rt.equinox.bundles-07670433d11dd8ebcca2377523e4e9d176ccdb5a.tar.xz rt.equinox.bundles-07670433d11dd8ebcca2377523e4e9d176ccdb5a.zip |
[Bug 413053] Test component descriptors are reloaded on bundle update when using wildcards in Service-Component.
Diffstat (limited to 'bundles/org.eclipse.equinox.ds.tests')
10 files changed, 300 insertions, 2 deletions
diff --git a/bundles/org.eclipse.equinox.ds.tests/.classpath b/bundles/org.eclipse.equinox.ds.tests/.classpath index 932ccfeb7..d81e9c02f 100644 --- a/bundles/org.eclipse.equinox.ds.tests/.classpath +++ b/bundles/org.eclipse.equinox.ds.tests/.classpath @@ -30,5 +30,6 @@ <classpathentry kind="src" output="scr_test/tb22" path="bundles_src/tb22"/> <classpathentry kind="src" output="scr_test/tb23" path="bundles_src/tb23"/> <classpathentry kind="src" output="scr_test/tb25" path="bundles_src/tb25"/> + <classpathentry kind="src" output="scr_test/tb26" path="bundles_src/tb26"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/bundles/org.eclipse.equinox.ds.tests/build.properties b/bundles/org.eclipse.equinox.ds.tests/build.properties index 8b6a057b3..55429d97a 100644 --- a/bundles/org.eclipse.equinox.ds.tests/build.properties +++ b/bundles/org.eclipse.equinox.ds.tests/build.properties @@ -39,6 +39,7 @@ bin.includes = META-INF/,\ scr_test/tb23.jar,\ scr_test/tb24.jar,\ scr_test/tb25.jar,\ + scr_test/tb26.jar,\ test.xml jars.compile.order = .,\ scr_test/tb1.jar,\ @@ -67,7 +68,8 @@ jars.compile.order = .,\ scr_test/tb22.jar,\ scr_test/tb23.jar,\ scr_test/tb24.jar,\ - scr_test/tb25.jar + scr_test/tb25.jar,\ + scr_test/tb26.jar source.scr_test/tb1.jar = bundles_src/tb1/ manifest.scr_test/tb1.jar = META-INF/MANIFEST.MF source.scr_test/tb1a.jar = bundles_src/tb1a/ @@ -122,3 +124,5 @@ source.scr_test/tb24.jar = bundles_src/tb24/ manifest.scr_test/tb24.jar = META-INF/MANIFEST.MF source.scr_test/tb25.jar = bundles_src/tb25/ manifest.scr_test/tb25.jar = META-INF/MANIFEST.MF +source.scr_test/tb26.jar = bundles_src/tb26/ +manifest.scr_test/tb26.jar = META-INF/MANIFEST.MF diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/META-INF/MANIFEST.MF new file mode 100755 index 000000000..7c62d09c0 --- /dev/null +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/META-INF/MANIFEST.MF @@ -0,0 +1,8 @@ +Manifest-Version: 1.0 +Bundle-SymbolicName: org.eclipse.equinox.ds.tests.tb26 +Service-Component: OSGI-INF/*.xml +Export-Package: org.eclipse.equinox.ds.tests.tb26 +Import-Package: org.osgi.service.component, + org.osgi.framework, + org.eclipse.osgi.service.urlconversion, + org.osgi.util.tracker
\ No newline at end of file diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/OSGI-INF/component.xml b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/OSGI-INF/component.xml new file mode 100755 index 000000000..fc8ec082e --- /dev/null +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/OSGI-INF/component.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<root> + <scr:component + name="org.eclipse.equinox.ds.tests.tb26.Component1" + enabled="true" + immediate="true" + xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0"> + <implementation class="org.eclipse.equinox.ds.tests.tb26.impl.Component1"/> + <service> + <provide interface="org.eclipse.equinox.ds.tests.tb26.Component"/> + </service> + </scr:component> +</root> diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/Component.java b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/Component.java new file mode 100755 index 000000000..3a33eaa15 --- /dev/null +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/Component.java @@ -0,0 +1,107 @@ +package org.eclipse.equinox.ds.tests.tb26; + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URL; + +import org.eclipse.osgi.service.urlconversion.URLConverter; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Filter; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.service.component.ComponentContext; +import org.osgi.util.tracker.ServiceTracker; + +public abstract class Component { + protected ComponentContext context; + protected ServiceTracker<URLConverter, URLConverter> tracker; + + public abstract String getName(); + + public abstract void update() throws Exception; + + protected void activate(ComponentContext context) throws InvalidSyntaxException { + this.context = context; + BundleContext bc = context.getBundleContext(); + Filter f = bc.createFilter("(&(objectClass=" + URLConverter.class.getName() + ")(protocol=bundleentry))"); + tracker = new ServiceTracker<URLConverter, URLConverter>(bc, f, null); + tracker.open(); + } + + protected void deactivate(ComponentContext context) { + tracker.close(); + } + + protected void replaceCurrentComponentXmlWith(String componentXmlFileName) throws Exception { + writeResource("component.xml", readResource(componentXmlFileName)); + } + + private void closeSilently(Closeable closeable) { + try { + closeable.close(); + } + catch (IOException e) {} + } + + private URL getResource(String name) { + Bundle b = context.getBundleContext().getBundle(); + URL result = b.getResource(name); + if (result == null) + result = b.findEntries("/", name, true).nextElement(); + return result; + } + + private File getResourceAsFile(String name) throws Exception { + return new File(getResourceAsUri(name)); + } + + private FileInputStream getResourceAsFileInputStream(String name) throws Exception { + return new FileInputStream(getResourceAsFile(name)); + } + + private FileOutputStream getResourceAsFileOutputStream(String name) throws Exception { + return new FileOutputStream(getResourceAsFile(name)); + } + + private URI getResourceAsUri(String name) throws Exception { + URL url = getResource(name); + URLConverter converter = tracker.getService(); + url = converter.toFileURL(url); + return url.toURI(); + } + + private byte[] readResource(String name) throws Exception { + FileInputStream fis = getResourceAsFileInputStream(name); + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + byte[] bytes = new byte[1024]; + int read; + while((read = fis.read(bytes)) != -1) + baos.write(bytes, 0, read); + return baos.toByteArray(); + } + finally { + closeSilently(baos); + } + } + finally { + closeSilently(fis); + } + } + + private void writeResource(String name, byte[] content) throws Exception { + FileOutputStream fos = getResourceAsFileOutputStream(name); + try { + fos.write(content); + } + finally { + closeSilently(fos); + } + } +} diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component1.java b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component1.java new file mode 100755 index 000000000..80984e347 --- /dev/null +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component1.java @@ -0,0 +1,13 @@ +package org.eclipse.equinox.ds.tests.tb26.impl; + +import org.eclipse.equinox.ds.tests.tb26.Component; + +public class Component1 extends Component { + public String getName() { + return getClass().getName(); + } + + public void update() throws Exception { + replaceCurrentComponentXmlWith("component2.xml"); + } +} diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component2.java b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component2.java new file mode 100755 index 000000000..f558d4ea9 --- /dev/null +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/Component2.java @@ -0,0 +1,13 @@ +package org.eclipse.equinox.ds.tests.tb26.impl; + +import org.eclipse.equinox.ds.tests.tb26.Component; + +public class Component2 extends Component { + public String getName() { + return getClass().getName(); + } + + public void update() throws Exception { + replaceCurrentComponentXmlWith("component1.xml"); + } +} diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component1.xml b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component1.xml new file mode 100755 index 000000000..fc8ec082e --- /dev/null +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component1.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<root> + <scr:component + name="org.eclipse.equinox.ds.tests.tb26.Component1" + enabled="true" + immediate="true" + xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0"> + <implementation class="org.eclipse.equinox.ds.tests.tb26.impl.Component1"/> + <service> + <provide interface="org.eclipse.equinox.ds.tests.tb26.Component"/> + </service> + </scr:component> +</root> diff --git a/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component2.xml b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component2.xml new file mode 100755 index 000000000..5d2fc1f85 --- /dev/null +++ b/bundles/org.eclipse.equinox.ds.tests/bundles_src/tb26/org/eclipse/equinox/ds/tests/tb26/impl/component2.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<root> + <scr:component + name="org.eclipse.equinox.ds.tests.tb26.Component2" + enabled="true" + immediate="true" + xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0"> + <implementation class="org.eclipse.equinox.ds.tests.tb26.impl.Component2"/> + <service> + <provide interface="org.eclipse.equinox.ds.tests.tb26.Component"/> + </service> + </scr:component> +</root> diff --git a/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java b/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java index f68b48d76..819f0e768 100644 --- a/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java +++ b/bundles/org.eclipse.equinox.ds.tests/src/org/eclipse/equinox/ds/tests/tbc/DSTest.java @@ -11,13 +11,18 @@ *******************************************************************************/ package org.eclipse.equinox.ds.tests.tbc; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.net.URL; import java.util.ArrayList; import java.util.Dictionary; import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import junit.framework.TestCase; @@ -2935,6 +2940,69 @@ public class DSTest extends TestCase { Bundle b = installer.installBundle(bundle); return b; } + + private Bundle installBundleAsDirectory(String bundle) throws Exception { + BundleContext context = getContext(); + String location = installer.getBundleLocation(bundle); + String reference = "reference:"; + if (location.startsWith(reference)) + // Remove the "reference" protocol from the URL. + // (1) So that when running from a workspace, the test will modify a + // copy of the component.xml. + // (2) When running from a server, to get a readable input stream when + // extracting the JAR into a directory. + location = location.substring(location.indexOf(':') + 1); + if (!location.endsWith(".jar")) + // If the bundle is already a directory, go ahead and install it in + // the typical fashion. Leave the "reference" protocol out. + return context.installBundle(location); + // The bundle is a JAR file and needs to be extracted and copied as a + // directory to the data storage area of the test harness bundle. + File file = context.getBundle().getDataFile(bundle); + ZipInputStream in = new ZipInputStream(new URL(location).openStream()); + try { + for (ZipEntry ze = in.getNextEntry(); ze != null; ze = in.getNextEntry()) { + String name = ze.getName(); + // Is the entry a directory? + if (ze.isDirectory()) + // If so, continue to the next entry. Directories will be + // created later. + continue; + // If not, the contents of the file must be copied. + File destination; + // Does the file entry contain a directory? + int index = name.lastIndexOf('/'); + if (index == -1) + // If not, just create the destination file. + destination = new File(file, name); + else { + // If so, make sure the directory exists. + File dir = new File(file, name.substring(0, index)); + dir.mkdirs(); + // Then create the destination file. + destination = new File(dir, name.substring(index)); + } + // Now copy the contents of the file entry to the destination. + byte[] bytes = new byte[1024]; + int read; + FileOutputStream out = new FileOutputStream(destination); + try { + while ((read = in.read(bytes)) != -1) + out.write(bytes, 0, read); + } + finally { + out.close(); + } + in.closeEntry(); + } + } + finally { + in.close(); + } + // Add the "reference" protocol back when running from a server so the + // framework sees the modified component.xml in the bundle data storage. + return context.installBundle(reference + file.toURI()); + } private void uninstallBundle(Bundle bundle) throws BundleException { installer.uninstallBundle(bundle); @@ -2998,5 +3066,50 @@ public class DSTest extends TestCase { sleep0(2 * timeout); } } - + + /* + * This test requires the bundle to be installed as a directory using a + * reference URL. Otherwise, necessary file updates will not occur, and the + * test will no longer be valid. + */ + public void testComponentDefinitionReloadedOnBundleUpdateInDevModeWhenUsingWildcardInServiceComponentHeader() throws Exception { + // Enable component caching in DS. + System.setProperty("equinox.ds.dbstore", Boolean.TRUE.toString()); + // Set dev mode. + System.setProperty("osgi.checkConfiguration", Boolean.TRUE.toString()); + + String serviceName = "org.eclipse.equinox.ds.tests.tb26.Component"; + // component.xml = conmponent1.xml initially. + Bundle b = installBundleAsDirectory("tb26"); + try { + b.start(); + waitBundleStart(); + + // The component service should be Component1. + BundleContext context = getContext(); + ServiceReference<?> ref = context.getServiceReference(serviceName); + assertNotNull(ref); + Object service = context.getService(ref); + Class clazz = service.getClass(); + assertEquals("org.eclipse.equinox.ds.tests.tb26.impl.Component1", clazz.getName()); + + // Update component.xml with component2.xml. + clazz.getMethod("update", (Class[])null).invoke(service, (Object[])null); + + // Force a component update in DS. + b.stop(); + b.start(); + waitBundleStart(); + + // The component service should now be Component2. + ref = context.getServiceReference(serviceName); + assertNotNull(ref); + service = context.getService(ref); + clazz = service.getClass(); + assertEquals("org.eclipse.equinox.ds.tests.tb26.impl.Component2", clazz.getName()); + } + finally { + uninstallBundle(b); + } + } } |