diff options
Diffstat (limited to 'sdo-java/tags/1.1/impl/src/test/java/org/apache/tuscany/sdo/test/osgi/OSGiTestCase.java')
-rw-r--r-- | sdo-java/tags/1.1/impl/src/test/java/org/apache/tuscany/sdo/test/osgi/OSGiTestCase.java | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/sdo-java/tags/1.1/impl/src/test/java/org/apache/tuscany/sdo/test/osgi/OSGiTestCase.java b/sdo-java/tags/1.1/impl/src/test/java/org/apache/tuscany/sdo/test/osgi/OSGiTestCase.java new file mode 100644 index 0000000000..5a67fc41c5 --- /dev/null +++ b/sdo-java/tags/1.1/impl/src/test/java/org/apache/tuscany/sdo/test/osgi/OSGiTestCase.java @@ -0,0 +1,354 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sdo.test.osgi; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; + +import org.apache.felix.framework.Felix; +import org.apache.felix.main.Main; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; + +import junit.framework.TestCase; + +/* + * This test runs the SDO implementation test suite under a Felix OSGi runtime + */ +public class OSGiTestCase extends TestCase { + + private Felix felix; + private BundleContext bundleContext; + private ClassLoader contextClassLoader; + + protected void setUp() throws Exception { + + contextClassLoader = Thread.currentThread().getContextClassLoader(); + + super.setUp(); + + // Start a Felix OSGi runtime + File profileDir = new File(".felix"); + if (profileDir.isDirectory()) + deleteDirectory(profileDir); + else + profileDir.delete(); + profileDir.mkdir(); + + Properties props = Main.loadConfigProperties(); + props.put("felix.cache.profiledir", profileDir.getAbsolutePath()); + props.put("felix.embedded.execution", "true"); + props.put("org.osgi.framework.system.packages", + "org.osgi.framework; version=1.3.0," + + "org.osgi.service.packageadmin; version=1.2.0, " + + "org.osgi.service.startlevel; version=1.0.0, " + + "org.osgi.service.url; version=1.0.0, " + "javax.xml, " + + "javax.xml.parsers, " + "javax.xml.namespace, " + + "org.xml.sax, " + "org.xml.sax.helpers, " + "org.xml.sax.ext, " + + "org.w3c.dom, " + "org.w3c.dom.events, " + "javax.xml.stream, " + + "javax.xml.transform, " + "javax.xml.transform.dom, " + + "javax.xml.transform.stream, " + "org.objectweb.asm, " + + "junit.framework"); + + List activators = new ArrayList(); + Felix felix = new Felix(props, activators); + felix.start(); + bundleContext = felix.getBundleContext(); + } + + protected void tearDown() throws Exception { + + super.tearDown(); + Thread.currentThread().setContextClassLoader(contextClassLoader); + + if (felix != null) { + felix.stop(); + felix = null; + } + } + + // Install SDO spec, SDO lib, SDO impl, and its EMF dependencies + // Create a test bundle containing all the SDO tests, and run the entire + // test suite inside an OSGi container + public void test() throws Exception { + + ArrayList bundles = new ArrayList(); + FilenameFilter jarFileFilter = new JarFileFilter(); + + File apiDir = new File("../sdo-api/target"); + File[] apiJars = apiDir.listFiles(jarFileFilter); + for (int i = 0; i < apiJars.length; i++) { + Bundle bundle = bundleContext + .installBundle(apiJars[i].toURL().toString()); + bundles.add(bundle); + } + + File libDir = new File("../lib/target"); + File[] libJars = libDir.listFiles(jarFileFilter); + for (int i = 0; i < libJars.length; i++) { + Bundle bundle = bundleContext + .installBundle(libJars[i].toURL().toString()); + bundles.add(bundle); + } + + if (!(contextClassLoader instanceof URLClassLoader)) + return; + + URL[] classPathURLs = ((URLClassLoader) contextClassLoader).getURLs(); + for (int i = 0; i < classPathURLs.length; i++) { + String url = classPathURLs[i].toString(); + if (url.indexOf("eclipse") > 0 && url.endsWith(".jar")) { + Bundle bundle = installEclipseBundle(classPathURLs[i]); + if (bundle != null) + bundles.add(bundle); + } + } + + // When this test is run during the build, sdo.impl.jar would not yet have + // been created + // Create this bundle - use the manifest file provided in the test + // directory, which works + // with Felix. + Bundle implBundle = installBundle("file:sdo.impl", + "../impl/target/test-classes/osgi/sdo.impl.mf", + new String[] { "../impl/target/classes" }); + bundles.add(implBundle); + + // Start all the installed bundles + for (int i = 0; i < bundles.size(); i++) { + Bundle bundle = (Bundle) bundles.get(i); + try { + bundle.start(); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("Could not start bundle " + bundle); + // don't stop on first failure, so we document all failures + // any failure will be re-triggered by the testBundle.start() call below + } + } + + // Install the test bundle - it contains all the test classes. The bundle + // activator for + // this class runs the entire test suite + Bundle testBundle = installBundle("file:sdo.osgi.test", + "../impl/target/test-classes/osgi/sdo.osgi.test.mf", + new String[] { "../impl/target/test-classes" }); + + TestClassLoader testClassLoader = new TestClassLoader(testBundle, + contextClassLoader); + Thread.currentThread().setContextClassLoader(testClassLoader); + + // The test suite is run inside an OSGi container by this call. + testBundle.start(); + } + + // Delete any old Felix configuration files left over from previous runs + private static void deleteDirectory(File dir) { + + File[] files = dir.listFiles(); + for (int i = 0; i < files.length; i++) { + if (files[i].isDirectory()) + deleteDirectory(files[i]); + else + files[i].delete(); + } + dir.delete(); + + } + + // Create and install a bundle with the specified manifest file + // The bundle contains all files from the list of directories specified + public Bundle installBundle(String bundleLocation, String manifestFileName, + String[] dirNames) throws Exception { + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + File manifestFile = new File(manifestFileName); + Manifest manifest = new Manifest(); + manifest.read(new FileInputStream(manifestFile)); + + JarOutputStream jarOut = new JarOutputStream(out, manifest); + + for (int i = 0; i < dirNames.length; i++) { + File dir = new File(dirNames[i]); + addFilesToJar(dir, dirNames[i], jarOut); + } + + jarOut.close(); + out.close(); + + ByteArrayInputStream inStream = new ByteArrayInputStream(out.toByteArray()); + return bundleContext.installBundle(bundleLocation, inStream); + + } + + // Add all the files from a build directory into a jar file + // This method is used to create bundles on the fly + private void addFilesToJar(File dir, String rootDirName, + JarOutputStream jarOut) throws Exception { + + if (dir.getName().equals(".svn")) + return; + + File[] files = dir.listFiles(); + + for (int i = 0; i < files.length; i++) { + + if (files[i].isDirectory()) { + addFilesToJar(files[i], rootDirName, jarOut); + continue; + } + if (files[i].getName().endsWith("MANIFEST.MF")) + continue; + + String entryName = files[i].getPath().substring(rootDirName.length() + 1); + entryName = entryName.replaceAll("\\\\", "/"); + ZipEntry ze = new ZipEntry(entryName); + + jarOut.putNextEntry(ze); + FileInputStream file = new FileInputStream(files[i]); + byte[] fileContents = new byte[file.available()]; + file.read(fileContents); + jarOut.write(fileContents); + } + } + + // Install a bundle corresponding to an jar file from Eclipse (eg. EMF jars) + // These bundle manifest entries use Require-Bundle of + // eclipse core runtime. The Plugin class from the Eclipse runtime + // is loaded by the bundle activator of some of these bundles. + // Since this test is run under Felix, remove the dependency on + // Eclipse runtime by removing the Require-Bundle and + // Bundle-Activator entries from the manifest + private Bundle installEclipseBundle(URL jarURL) throws Exception { + + JarInputStream jarInput = new JarInputStream(jarURL.openStream()); + + Manifest manifest = jarInput.getManifest(); + if (manifest == null) { + manifest = new Manifest(); + ZipEntry entry; + while ((entry = jarInput.getNextEntry()) != null) { + if (entry.getName().equals("META-INF/MANIFEST.MF")) { + byte bytes[] = new byte[(int) entry.getSize()]; + jarInput.read(bytes); + manifest.read(new ByteArrayInputStream(bytes)); + } + } + jarInput.close(); + jarInput = new JarInputStream(jarURL.openStream()); + } + if (manifest == null + || manifest.getMainAttributes() == null + || !manifest.getMainAttributes().containsKey( + new Attributes.Name("Bundle-SymbolicName"))) { + + return null; + } + manifest.getMainAttributes().remove(new Attributes.Name("Require-Bundle")); + manifest.getMainAttributes() + .remove(new Attributes.Name("Bundle-Activator")); + manifest.getMainAttributes().put( + new Attributes.Name("DynamicImport-Package"), "*"); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + JarOutputStream jarOut = new JarOutputStream(out, manifest); + ZipEntry entry; + byte bytes[] = new byte[1024]; + while ((entry = jarInput.getNextEntry()) != null) { + if (!entry.getName().equals("META-INF/MANIFEST.MF")) { + jarOut.putNextEntry((JarEntry) entry); + int len; + while ((len = jarInput.read(bytes)) != -1) { + jarOut.write(bytes, 0, len); + } + jarOut.closeEntry(); + } + jarInput.closeEntry(); + } + jarOut.close(); + out.close(); + jarInput.close(); + + ByteArrayInputStream byteStream = new ByteArrayInputStream(out + .toByteArray()); + + return bundleContext.installBundle(jarURL.toString(), byteStream); + + } + + // Filter used to list jar files from a directory + private class JarFileFilter implements FilenameFilter { + + public boolean accept(File dir, String name) { + if (name.endsWith(".jar") && !name.endsWith("javadoc.jar")) + return true; + else + return false; + } + + } + + // Test classloader - used as context classloader + private static class TestClassLoader extends ClassLoader { + + Bundle testBundle; + + private TestClassLoader(Bundle testBundle, ClassLoader parentClassLoader) { + super(parentClassLoader); + this.testBundle = testBundle; + } + + public Class loadClass(String className) throws ClassNotFoundException { + Class clazz = findLoadedClass(className); + if (clazz != null) + return clazz; + + try { + return testBundle.loadClass(className); + } catch (Exception e) { + } + return super.loadClass(className); + } + + public URL getResource(String resName) { + URL resource = testBundle.getResource(resName); + if (resource == null) + resource = super.getResource(resName); + return resource; + } + + } +} |