FELIX-2033: Provide an easy to use layer for writing pax-exam test for Karaf
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@906084 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/itests/pom.xml b/karaf/itests/pom.xml
index 022dfa9..20aeea6 100644
--- a/karaf/itests/pom.xml
+++ b/karaf/itests/pom.xml
@@ -56,62 +56,12 @@
<version>1.2.1</version>
</dependency>
- <!-- The assembly and all the dependencies -->
- <dependency>
- <groupId>org.apache.felix.karaf</groupId>
- <artifactId>apache-felix-karaf</artifactId>
- <type>xml</type>
- <classifier>features</classifier>
- <scope>test</scope>
- </dependency>
-
<dependency>
<groupId>org.apache.felix.karaf.tooling</groupId>
<artifactId>org.apache.felix.karaf.tooling.testing</artifactId>
<scope>test</scope>
</dependency>
-
- <!-- Pax EXAM -->
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-container-default</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.ops4j.pax.exam</groupId>
- <artifactId>pax-exam-junit-extender-impl</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.5</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
- <repositories>
- <repository>
- <id>ops4j.releases</id>
- <url>http://repository.ops4j.org/maven2</url>
- </repository>
- </repositories>
- <pluginRepositories>
- <pluginRepository>
- <id>ops4j.releases</id>
- <url>http://repository.ops4j.org/maven2</url>
- </pluginRepository>
- </pluginRepositories>
+ </dependencies>
<build>
<plugins>
@@ -153,26 +103,6 @@
</plugins>
</build>
</profile>
- <!--
- <profile>
- <activation>
- <os>
- <family>Windows</family>
- </os>
- </activation>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- <configuration>
- <skip>true</skip>
- </configuration>
- </plugin>
- </plugins>
- </build>
- </profile>
- -->
</profiles>
</project>
diff --git a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/CoreTest.java b/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/CoreTest.java
index fb3d014..a0f7534 100644
--- a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/CoreTest.java
+++ b/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/CoreTest.java
@@ -16,11 +16,7 @@
*/
package org.apache.felix.karaf.shell.itests;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Dictionary;
-import java.util.List;
-
+import org.apache.felix.karaf.testing.AbstractIntegrationTest;
import org.apache.felix.karaf.testing.Helper;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -28,7 +24,6 @@
import org.ops4j.pax.exam.junit.Configuration;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;
import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
import org.osgi.service.command.CommandProcessor;
import org.osgi.service.command.CommandSession;
@@ -36,12 +31,11 @@
import static org.junit.Assert.fail;
import static org.ops4j.pax.exam.CoreOptions.equinox;
import static org.ops4j.pax.exam.CoreOptions.felix;
-import static org.ops4j.pax.exam.CoreOptions.options;
import static org.ops4j.pax.exam.CoreOptions.systemProperty;
import static org.ops4j.pax.exam.OptionUtils.combine;
@RunWith(JUnit4TestRunner.class)
-public class CoreTest extends org.apache.felix.karaf.testing.AbstractIntegrationTest {
+public class CoreTest extends AbstractIntegrationTest {
@Test
public void testHelp() throws Exception {
diff --git a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/FeaturesTest.java b/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/FeaturesTest.java
index 49f5fc4..a3b29c0 100644
--- a/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/FeaturesTest.java
+++ b/karaf/itests/src/test/java/org/apache/felix/karaf/shell/itests/FeaturesTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.felix.karaf.shell.itests;
+import org.apache.felix.karaf.testing.AbstractIntegrationTest;
import org.apache.felix.karaf.testing.Helper;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +36,7 @@
import static org.ops4j.pax.exam.container.def.PaxRunnerOptions.scanFeatures;
@RunWith(JUnit4TestRunner.class)
-public class FeaturesTest extends org.apache.felix.karaf.testing.AbstractIntegrationTest {
+public class FeaturesTest extends AbstractIntegrationTest {
@Test
public void testFeatures() throws Exception {
diff --git a/karaf/pom.xml b/karaf/pom.xml
index ae3ff8f..ba3a783 100644
--- a/karaf/pom.xml
+++ b/karaf/pom.xml
@@ -87,7 +87,7 @@
<geronimo.servlet.version>1.1.2</geronimo.servlet.version>
<jansi.version>1.1</jansi.version>
<jetty.bundle.version>6.1.14_1</jetty.bundle.version>
- <junit.version>3.8.2_1</junit.version>
+ <junit.version>4.7_1</junit.version>
<jline.version>0.9.95-20091026.080844</jline.version>
<log4j.version>1.2.14</log4j.version>
<maven.version>2.0.9</maven.version>
diff --git a/karaf/tooling/testing/pom.xml b/karaf/tooling/testing/pom.xml
index 4008c9b..7f29aba 100644
--- a/karaf/tooling/testing/pom.xml
+++ b/karaf/tooling/testing/pom.xml
@@ -39,6 +39,13 @@
</properties>
<dependencies>
+ <!-- The assembly and all the dependencies -->
+ <dependency>
+ <groupId>org.apache.felix.karaf</groupId>
+ <artifactId>apache-felix-karaf</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
<!-- Pax EXAM -->
<dependency>
<groupId>org.ops4j.pax.exam</groupId>
@@ -57,9 +64,8 @@
<artifactId>pax-exam-junit-extender-impl</artifactId>
</dependency>
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.5</version>
+ <groupId>org.apache.servicemix.bundles</groupId>
+ <artifactId>org.apache.servicemix.bundles.junit</artifactId>
</dependency>
</dependencies>
diff --git a/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/Helper.java b/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/Helper.java
index f41a716..1243eb9 100644
--- a/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/Helper.java
+++ b/karaf/tooling/testing/src/main/java/org/apache/felix/karaf/testing/Helper.java
@@ -16,31 +16,20 @@
*/
package org.apache.felix.karaf.testing;
+import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.ops4j.pax.exam.CoreOptions;
-import org.ops4j.pax.exam.Inject;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.options.MavenArtifactProvisionOption;
import org.ops4j.pax.exam.options.SystemPropertyOption;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
import static org.ops4j.pax.exam.CoreOptions.bootClasspathLibrary;
import static org.ops4j.pax.exam.CoreOptions.frameworkStartLevel;
@@ -48,42 +37,222 @@
import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
import static org.ops4j.pax.exam.OptionUtils.combine;
+/**
+ * Helper class for setting up a pax-exam test environment for karaf.
+ *
+ * A simple configuration for pax-exam can be create using the following
+ * code:
+ * <pre>
+ * @Configuration
+ * public static Option[] configuration() throws Exception{
+ * return combine(
+ * // Default karaf environment
+ * Helper.getDefaultOptions(),
+ * // Test on both equinox and felix
+ * equinox(), felix()
+ * );
+ * }
+ * </pre>
+ *
+ */
public final class Helper {
private Helper() {
}
+ /**
+ * Create an provisioning option for the specified maven artifact
+ * (groupId and artifactId), using the version found in the list
+ * of dependencies of this maven project.
+ *
+ * @param groupId the groupId of the maven bundle
+ * @param artifactId the artifactId of the maven bundle
+ * @return the provisioning option for the given bundle
+ */
public static MavenArtifactProvisionOption mavenBundle(String groupId, String artifactId) {
- return CoreOptions.mavenBundle().groupId(groupId).artifactId(artifactId).versionAsInProject();
+ return CoreOptions.mavenBundle(groupId, artifactId).versionAsInProject();
}
- /*
- * Explode the dictionary into a ,-delimited list of key=value pairs
+ /**
+ * Return a map of system properties for karaf.
+ * The default karaf home directory is "target/karaf.home".
+ *
+ * @return a list of system properties for karaf
*/
- private static String explode(Dictionary dictionary) {
- Enumeration keys = dictionary.keys();
- StringBuffer result = new StringBuffer();
- while (keys.hasMoreElements()) {
- Object key = keys.nextElement();
- result.append(String.format("%s=%s", key, dictionary.get(key)));
- if (keys.hasMoreElements()) {
- result.append(", ");
- }
- }
- return result.toString();
+ public static Properties getDefaultSystemOptions() {
+ return getDefaultSystemOptions("target/karaf.home");
}
- /*
- * Provides an iterable collection of references, even if the original array is null
+ /**
+ * Return a map of system properties for karaf,
+ * using the specified folder for the karaf home directory.
+ *
+ * @param karafHome the karaf home directory
+ * @return a list of system properties for karaf
*/
- private static final Collection<ServiceReference> asCollection(ServiceReference[] references) {
- List<ServiceReference> result = new LinkedList<ServiceReference>();
- if (references != null) {
- for (ServiceReference reference : references) {
- result.add(reference);
+ public static Properties getDefaultSystemOptions(String karafHome) {
+ Properties sysProps = new Properties();
+ sysProps.setProperty("karaf.name", "root");
+ sysProps.setProperty("karaf.home", karafHome);
+ sysProps.setProperty("karaf.base", karafHome);
+ sysProps.setProperty("karaf.startLocalConsole", "false");
+ sysProps.setProperty("karaf.startRemoteShell", "false");
+ sysProps.setProperty("org.osgi.framework.startlevel.beginning", "100");
+ return sysProps;
+ }
+
+ /**
+ * Return an array of pax-exam options to correctly configure the osgi
+ * framework for karaf.
+ *
+ * @return default pax-exam options for karaf osgi framework
+ */
+ public static Option[] getDefaultConfigOptions() {
+ return getDefaultConfigOptions(getDefaultSystemOptions(),
+ getResource("/org/apache/felix/karaf/testing/config.properties"));
+ }
+
+ /**
+ * Return an array of pax-exam options to configure the osgi
+ * framework for karaf, given the system properties and the
+ * location of the osgi framework properties file.
+ *
+ * @param sysProps karaf system properties
+ * @param configProperties the URL to load the osgi framework properties from
+ * @return pax-exam options for karaf osgi framework
+ */
+ public static Option[] getDefaultConfigOptions(Properties sysProps, URL configProperties) {
+ // Load props
+ Properties configProps = loadProperties(configProperties);
+ // Set system props
+ for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements();) {
+ String key = (String) e.nextElement();
+ configProps.setProperty(key, sysProps.getProperty(key));
+ }
+ // Perform variable substitution for system properties.
+ for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ configProps.setProperty(name, substVars(configProps.getProperty(name), name, null, configProps));
+ }
+ // Transform to sys props options
+ List<Option> options = new ArrayList<Option>();
+ for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ String value = configProps.getProperty(name);
+ value = value.replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
+ options.add(new SystemPropertyOption(name).value(value));
+ }
+ if (configProps.getProperty("org.osgi.framework.startlevel.beginning") != null) {
+ options.add(frameworkStartLevel(Integer.parseInt(configProps.getProperty("org.osgi.framework.startlevel.beginning"))));
+ }
+ return options.toArray(new Option[options.size()]);
+ }
+
+ /**
+ * Return an array of pax-exam options for the provisioning of karaf system bundles.
+ *
+ * @return an array of pax-exam options for provisioning karaf system bundles
+ */
+ public static Option[] getDefaultProvisioningOptions() {
+ return getDefaultProvisioningOptions(getDefaultSystemOptions(),
+ getResource("/org/apache/felix/karaf/testing/startup.properties"));
+ }
+
+ /**
+ * Return an array of pax-exam options for the provisioning of karaf system bundles,
+ * given the karaf system properties and the location of the startup bundles config file.
+ *
+ * @param sysProps karaf system properties
+ * @param startupProperties the URL to load the system bundles from
+ * @return an array of pax-exam options for provisioning karaf system bundles
+ */
+ public static Option[] getDefaultProvisioningOptions(Properties sysProps, URL startupProperties) {
+ Properties startupProps = loadProperties(startupProperties);
+ // Perform variable substitution for system properties.
+ for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ startupProps.setProperty(name, substVars(startupProps.getProperty(name), name, null, sysProps));
+ }
+ // Transform to sys props options
+ List<Option> options = new ArrayList<Option>();
+ options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf.jaas", "org.apache.felix.karaf.jaas.boot")).afterFramework());
+ options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf", "org.apache.felix.karaf.main")).afterFramework());
+ for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
+ String name = (String) e.nextElement();
+ String value = startupProps.getProperty(name);
+ MavenArtifactProvisionOption opt = convertToMaven(name);
+ if (opt.getURL().contains("org.apache.felix.karaf.features")) {
+ opt.noStart();
+ }
+ opt.startLevel(Integer.parseInt(value));
+ options.add(opt);
+ }
+ options.add(mavenBundle("org.apache.felix.karaf.tooling", "org.apache.felix.karaf.tooling.testing"));
+ // We need to add pax-exam-junit here when running with the ibm
+ // jdk to avoid the following exception during the test run:
+ // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration
+ if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
+ options.add(wrappedBundle(maven("org.ops4j.pax.exam", "pax-exam-junit")));
+ }
+ return options.toArray(new Option[options.size()]);
+ }
+
+ /**
+ * Return an array of options for setting up a pax-exam test environment for karaf.
+ *
+ * @return an array of pax-exam options
+ */
+ public static Option[] getDefaultOptions() {
+ return combine(getDefaultConfigOptions(), getDefaultProvisioningOptions());
+ }
+
+ /**
+ * Retrieve the pax-exam option for provisioning the given maven bundle.
+ *
+ * @param options the list of pax-exam options
+ * @param groupId the maven group id
+ * @param artifactId the maven artifact id
+ * @return the pax-exam provisioning option for the bundle or <code>null</code> if not found
+ */
+ public static MavenArtifactProvisionOption findMaven(Option[] options, String groupId, String artifactId) {
+ for (Option option : options) {
+ if (option instanceof MavenArtifactProvisionOption) {
+ MavenArtifactProvisionOption mvn = (MavenArtifactProvisionOption) option;
+ if (mvn.getURL().startsWith("mvn:" + groupId + "/" + artifactId + "/")) {
+ return mvn;
+ }
}
}
- return result;
+ return null;
+ }
+
+ private static Properties loadProperties(URL location) {
+ try {
+ Properties props = new Properties();
+ InputStream is = location.openStream();
+ try {
+ props.load(is);
+ } finally {
+ is.close();
+ }
+ return props;
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to load properties from " + location, e);
+ }
+ }
+
+ private static URL getResource(String location) {
+ URL url = null;
+ if (Thread.currentThread().getContextClassLoader() != null) {
+ url = Thread.currentThread().getContextClassLoader().getResource(location);
+ }
+ if (url == null) {
+ url = Helper.class.getResource(location);
+ }
+ if (url == null) {
+ throw new RuntimeException("Unable to find resource " + location);
+ }
+ return url;
}
private static final String DELIM_START = "${";
@@ -226,481 +395,4 @@
}
}
- public static Properties getDefaultSystemOptions() {
- return getDefaultSystemOptions("target/karaf.home");
- }
-
- public static Properties getDefaultSystemOptions(String karafHome) {
- Properties sysProps = new Properties();
- sysProps.setProperty("karaf.name", "root");
- sysProps.setProperty("karaf.home", karafHome);
- sysProps.setProperty("karaf.base", karafHome);
- sysProps.setProperty("karaf.startLocalConsole", "false");
- sysProps.setProperty("karaf.startRemoteShell", "false");
- sysProps.setProperty("org.osgi.framework.startlevel.beginning", "100");
- return sysProps;
- }
-
- public static Option[] getDefaultConfigOptions() throws Exception {
- return getDefaultConfigOptions(getDefaultSystemOptions(),
- getResource("/org/apache/felix/karaf/testing/config.properties"));
- }
-
- public static Option[] getDefaultConfigOptions(Properties sysProps, URL configProperties) throws Exception {
- // Load props
- Properties configProps = new Properties();
- InputStream is = configProperties.openStream();
- try {
- configProps.load(is);
- } finally {
- is.close();
- }
- // Set system props
- for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements();) {
- String key = (String) e.nextElement();
- configProps.setProperty(key, sysProps.getProperty(key));
- }
- // Perform variable substitution for system properties.
- for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
- String name = (String) e.nextElement();
- configProps.setProperty(name, substVars(configProps.getProperty(name), name, null, configProps));
- }
- // Transform to sys props options
- List<Option> options = new ArrayList<Option>();
- for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
- String name = (String) e.nextElement();
- String value = configProps.getProperty(name);
- value = value.replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
- options.add(new SystemPropertyOption(name).value(value));
- System.err.println("sysprop: " + name + " = " + value);
- }
- if (configProps.getProperty("org.osgi.framework.startlevel.beginning") != null) {
- options.add(frameworkStartLevel(Integer.parseInt(configProps.getProperty("org.osgi.framework.startlevel.beginning"))));
- }
- return options.toArray(new Option[options.size()]);
- }
-
- public static Option[] getDefaultProvisioningOptions() throws Exception {
- return getDefaultProvisioningOptions(getDefaultSystemOptions(),
- getResource("/org/apache/felix/karaf/testing/startup.properties"));
- }
-
- private static URL getResource(String location) throws Exception {
- URL url = null;
- if (Thread.currentThread().getContextClassLoader() != null) {
- url = Thread.currentThread().getContextClassLoader().getResource(location);
- }
- if (url == null) {
- url = Helper.class.getResource(location);
- }
- System.err.println("Trying to load resource: " + location + ". Found: " + url);
- return url;
- }
-
- public static Option[] getDefaultProvisioningOptions(Properties sysProps, URL configProperties) throws Exception {
- Properties startupProps = new Properties();
- InputStream is = configProperties.openStream();
- try {
- startupProps.load(is);
- } finally {
- is.close();
- }
- // Perform variable substitution for system properties.
- for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
- String name = (String) e.nextElement();
- startupProps.setProperty(name, substVars(startupProps.getProperty(name), name, null, sysProps));
- }
- // Transform to sys props options
- List<Option> options = new ArrayList<Option>();
- options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf.jaas", "org.apache.felix.karaf.jaas.boot")).afterFramework());
- options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf", "org.apache.felix.karaf.main")).afterFramework());
- for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
- String name = (String) e.nextElement();
- String value = startupProps.getProperty(name);
- MavenArtifactProvisionOption opt = convertToMaven(name);
- if (opt.getURL().contains("org.apache.felix.karaf.features")) {
- opt.noStart();
- }
- opt.startLevel(Integer.parseInt(value));
- options.add(opt);
- }
- options.add(mavenBundle("org.apache.felix.karaf.tooling", "org.apache.felix.karaf.tooling.testing"));
- // We need to add pax-exam-junit here when running with the ibm
- // jdk to avoid the following exception during the test run:
- // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration
- if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
- options.add(wrappedBundle(maven("org.ops4j.pax.exam", "pax-exam-junit")));
- }
- return options.toArray(new Option[options.size()]);
- }
-
- public static Option[] getDefaultOptions() throws Exception {
- return combine(getDefaultConfigOptions(), getDefaultProvisioningOptions());
- }
-
- public static MavenArtifactProvisionOption findMaven(Option[] options, String groupId, String artifactId) {
- for (Option option : options) {
- if (option instanceof MavenArtifactProvisionOption) {
- MavenArtifactProvisionOption mvn = (MavenArtifactProvisionOption) option;
- if (mvn.getURL().startsWith("mvn:" + groupId + "/" + artifactId + "/")) {
- return mvn;
- }
- }
- }
- return null;
- }
-
- public abstract static class AbstractIntegrationTest {
-
- public static final long DEFAULT_TIMEOUT = 30000;
-
- @Inject
- protected BundleContext bundleContext;
-
- protected <T> T getOsgiService(Class<T> type, long timeout) {
- return getOsgiService(type, null, timeout);
- }
-
- protected <T> T getOsgiService(Class<T> type) {
- return getOsgiService(type, null, DEFAULT_TIMEOUT);
- }
-
- protected <T> T getOsgiService(Class<T> type, String filter, long timeout) {
- ServiceTracker tracker = null;
- try {
- String flt;
- if (filter != null) {
- if (filter.startsWith("(")) {
- flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")" + filter + ")";
- } else {
- flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")(" + filter + "))";
- }
- } else {
- flt = "(" + Constants.OBJECTCLASS + "=" + type.getName() + ")";
- }
- Filter osgiFilter = FrameworkUtil.createFilter(flt);
- tracker = new ServiceTracker(bundleContext, osgiFilter, null);
- tracker.open(true);
- // Note that the tracker is not closed to keep the reference
- // This is buggy, as the service reference may change i think
- Object svc = type.cast(tracker.waitForService(timeout));
- if (svc == null) {
- Dictionary dic = bundleContext.getBundle().getHeaders();
- System.err.println("Test bundle headers: " + explode(dic));
-
- for (ServiceReference ref : asCollection(bundleContext.getAllServiceReferences(null, null))) {
- System.err.println("ServiceReference: " + ref);
- }
-
- for (ServiceReference ref : asCollection(bundleContext.getAllServiceReferences(null, flt))) {
- System.err.println("Filtered ServiceReference: " + ref);
- }
-
- throw new RuntimeException("Gave up waiting for service " + flt);
- }
- return type.cast(svc);
- } catch (InvalidSyntaxException e) {
- throw new IllegalArgumentException("Invalid filter", e);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }
-
- protected Bundle installBundle(String groupId, String artifactId) throws Exception {
- MavenArtifactProvisionOption mvnUrl = mavenBundle(groupId, artifactId);
- return bundleContext.installBundle(mvnUrl.getURL());
- }
-
- protected Bundle getInstalledBundle(String symbolicName) {
- for (Bundle b : bundleContext.getBundles()) {
- if (b.getSymbolicName().equals(symbolicName)) {
- return b;
- }
- }
- return null;
- }
-
- public static MavenArtifactProvisionOption mavenBundle(String groupId, String artifactId) {
- return CoreOptions.mavenBundle().groupId(groupId).artifactId(artifactId).versionAsInProject();
- }
-
- /*
- * Explode the dictionary into a ,-delimited list of key=value pairs
- */
- private static String explode(Dictionary dictionary) {
- Enumeration keys = dictionary.keys();
- StringBuffer result = new StringBuffer();
- while (keys.hasMoreElements()) {
- Object key = keys.nextElement();
- result.append(String.format("%s=%s", key, dictionary.get(key)));
- if (keys.hasMoreElements()) {
- result.append(", ");
- }
- }
- return result.toString();
- }
-
- /*
- * Provides an iterable collection of references, even if the original array is null
- */
- private static final Collection<ServiceReference> asCollection(ServiceReference[] references) {
- List<ServiceReference> result = new LinkedList<ServiceReference>();
- if (references != null) {
- for (ServiceReference reference : references) {
- result.add(reference);
- }
- }
- return result;
- }
-
- private static final String DELIM_START = "${";
- private static final String DELIM_STOP = "}";
-
- /**
- * <p>
- * This method performs property variable substitution on the
- * specified value. If the specified value contains the syntax
- * <tt>${<prop-name>}</tt>, where <tt><prop-name></tt>
- * refers to either a configuration property or a system property,
- * then the corresponding property value is substituted for the variable
- * placeholder. Multiple variable placeholders may exist in the
- * specified value as well as nested variable placeholders, which
- * are substituted from inner most to outer most. Configuration
- * properties override system properties.
- * </p>
- *
- * @param val The string on which to perform property substitution.
- * @param currentKey The key of the property being evaluated used to
- * detect cycles.
- * @param cycleMap Map of variable references used to detect nested cycles.
- * @param configProps Set of configuration properties.
- * @return The value of the specified string after system property substitution.
- * @throws IllegalArgumentException If there was a syntax error in the
- * property placeholder syntax or a recursive variable reference.
- */
- private static String substVars(String val, String currentKey,
- Map<String, String> cycleMap, Properties configProps)
- throws IllegalArgumentException {
- // If there is currently no cycle map, then create
- // one for detecting cycles for this invocation.
- if (cycleMap == null) {
- cycleMap = new HashMap<String, String>();
- }
-
- // Put the current key in the cycle map.
- cycleMap.put(currentKey, currentKey);
-
- // Assume we have a value that is something like:
- // "leading ${foo.${bar}} middle ${baz} trailing"
-
- // Find the first ending '}' variable delimiter, which
- // will correspond to the first deepest nested variable
- // placeholder.
- int stopDelim = val.indexOf(DELIM_STOP);
-
- // Find the matching starting "${" variable delimiter
- // by looping until we find a start delimiter that is
- // greater than the stop delimiter we have found.
- int startDelim = val.indexOf(DELIM_START);
- while (stopDelim >= 0) {
- int idx = val.indexOf(DELIM_START, startDelim + DELIM_START.length());
- if ((idx < 0) || (idx > stopDelim)) {
- break;
- } else if (idx < stopDelim) {
- startDelim = idx;
- }
- }
-
- // If we do not have a start or stop delimiter, then just
- // return the existing value.
- if ((startDelim < 0) && (stopDelim < 0)) {
- return val;
- }
- // At this point, we found a stop delimiter without a start,
- // so throw an exception.
- else if (((startDelim < 0) || (startDelim > stopDelim))
- && (stopDelim >= 0)) {
- throw new IllegalArgumentException(
- "stop delimiter with no start delimiter: "
- + val);
- }
-
- // At this point, we have found a variable placeholder so
- // we must perform a variable substitution on it.
- // Using the start and stop delimiter indices, extract
- // the first, deepest nested variable placeholder.
- String variable =
- val.substring(startDelim + DELIM_START.length(), stopDelim);
-
- // Verify that this is not a recursive variable reference.
- if (cycleMap.get(variable) != null) {
- throw new IllegalArgumentException(
- "recursive variable reference: " + variable);
- }
-
- // Get the value of the deepest nested variable placeholder.
- // Try to configuration properties first.
- String substValue = (configProps != null)
- ? configProps.getProperty(variable, null)
- : null;
- if (substValue == null) {
- // Ignore unknown property values.
- substValue = System.getProperty(variable, "");
- }
-
- // Remove the found variable from the cycle map, since
- // it may appear more than once in the value and we don't
- // want such situations to appear as a recursive reference.
- cycleMap.remove(variable);
-
- // Append the leading characters, the substituted value of
- // the variable, and the trailing characters to get the new
- // value.
- val = val.substring(0, startDelim)
- + substValue
- + val.substring(stopDelim + DELIM_STOP.length(), val.length());
-
- // Now perform substitution again, since there could still
- // be substitutions to make.
- val = substVars(val, currentKey, cycleMap, configProps);
-
- // Return the value.
- return val;
- }
-
- private static MavenArtifactProvisionOption convertToMaven(String location) {
- String[] p = location.split("/");
- if (p.length >= 4 && p[p.length-1].startsWith(p[p.length-3] + "-" + p[p.length-2])) {
- MavenArtifactProvisionOption opt = new MavenArtifactProvisionOption();
- int artifactIdVersionLength = p[p.length-3].length() + 1 + p[p.length-2].length(); // (artifactId + "-" + version).length
- if (p[p.length-1].charAt(artifactIdVersionLength) == '-') {
- opt.classifier((p[p.length-1].substring(artifactIdVersionLength + 1, p[p.length-1].lastIndexOf('.'))));
- }
- StringBuffer sb = new StringBuffer();
- for (int j = 0; j < p.length - 3; j++) {
- if (j > 0) {
- sb.append('.');
- }
- sb.append(p[j]);
- }
- opt.groupId(sb.toString());
- opt.artifactId(p[p.length-3]);
- opt.version(p[p.length-2]);
- opt.type(p[p.length-1].substring(p[p.length-1].lastIndexOf('.') + 1));
- return opt;
- } else {
- throw new IllegalArgumentException("Unable to extract maven information from " + location);
- }
- }
-
- public static Properties getDefaultSystemOptions() {
- return getDefaultSystemOptions("target/karaf.home");
- }
-
- public static Properties getDefaultSystemOptions(String karafHome) {
- Properties sysProps = new Properties();
- sysProps.setProperty("karaf.name", "root");
- sysProps.setProperty("karaf.home", karafHome);
- sysProps.setProperty("karaf.base", karafHome);
- sysProps.setProperty("karaf.startLocalConsole", "false");
- sysProps.setProperty("karaf.startRemoteShell", "false");
- sysProps.setProperty("org.osgi.framework.startlevel.beginning", "100");
- return sysProps;
- }
-
- public static Option[] getDefaultConfigOptions() throws Exception {
- return getDefaultConfigOptions(getDefaultSystemOptions(),
- Helper.class.getResource("/config.properties"));
- }
-
- public static Option[] getDefaultConfigOptions(Properties sysProps, URL configProperties) throws Exception {
- // Load props
- Properties configProps = new Properties();
- InputStream is = configProperties.openStream();
- try {
- configProps.load(is);
- } finally {
- is.close();
- }
- // Set system props
- for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements();) {
- String key = (String) e.nextElement();
- configProps.setProperty(key, sysProps.getProperty(key));
- }
- // Perform variable substitution for system properties.
- for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
- String name = (String) e.nextElement();
- configProps.setProperty(name, substVars(configProps.getProperty(name), name, null, configProps));
- }
- // Transform to sys props options
- List<Option> options = new ArrayList<Option>();
- for (Enumeration e = configProps.propertyNames(); e.hasMoreElements();) {
- String name = (String) e.nextElement();
- String value = configProps.getProperty(name);
- value = value.replaceAll("\r", "").replaceAll("\n", "").replaceAll(" ", "");
- options.add(new SystemPropertyOption(name).value(value));
- }
- if (configProps.getProperty("org.osgi.framework.startlevel.beginning") != null) {
- options.add(frameworkStartLevel(Integer.parseInt(configProps.getProperty("org.osgi.framework.startlevel.beginning"))));
- }
- return options.toArray(new Option[options.size()]);
- }
-
- public static Option[] getDefaultProvisioningOptions() throws Exception {
- return getDefaultProvisioningOptions(getDefaultSystemOptions(),
- Helper.class.getResource("/startup.properties"));
- }
-
- public static Option[] getDefaultProvisioningOptions(Properties sysProps, URL configProperties) throws Exception {
- Properties startupProps = new Properties();
- InputStream is = configProperties.openStream();
- try {
- startupProps.load(is);
- } finally {
- is.close();
- }
- // Perform variable substitution for system properties.
- for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
- String name = (String) e.nextElement();
- startupProps.setProperty(name, substVars(startupProps.getProperty(name), name, null, sysProps));
- }
- // Transform to sys props options
- List<Option> options = new ArrayList<Option>();
- options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf.jaas", "org.apache.felix.karaf.jaas.boot")).afterFramework());
- options.add(bootClasspathLibrary(mavenBundle("org.apache.felix.karaf", "org.apache.felix.karaf.main")).afterFramework());
- for (Enumeration e = startupProps.propertyNames(); e.hasMoreElements();) {
- String name = (String) e.nextElement();
- String value = startupProps.getProperty(name);
- MavenArtifactProvisionOption opt = convertToMaven(name);
- if (opt.getURL().contains("org.apache.felix.karaf.features")) {
- opt.noStart();
- }
- opt.startLevel(Integer.parseInt(value));
- options.add(opt);
- }
- // We need to add pax-exam-junit here when running with the ibm
- // jdk to avoid the following exception during the test run:
- // ClassNotFoundException: org.ops4j.pax.exam.junit.Configuration
- if ("IBM Corporation".equals(System.getProperty("java.vendor"))) {
- options.add(wrappedBundle(maven("org.ops4j.pax.exam", "pax-exam-junit")));
- }
- return options.toArray(new Option[options.size()]);
- }
-
- public static Option[] getDefaultOptions() throws Exception {
- return combine(getDefaultConfigOptions(), getDefaultProvisioningOptions());
- }
-
- public static MavenArtifactProvisionOption findMaven(Option[] options, String groupId, String artifactId) {
- for (Option option : options) {
- if (option instanceof MavenArtifactProvisionOption) {
- MavenArtifactProvisionOption mvn = (MavenArtifactProvisionOption) option;
- if (mvn.getURL().startsWith("mvn:" + groupId + "/" + artifactId + "/")) {
- return mvn;
- }
- }
- }
- return null;
- }
- }
}
\ No newline at end of file