blob: a4cd5d2d3da6e1e4a7832da211181eb53448c697 [file] [log] [blame]
/*
* 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.geronimo.osgi.registry.itest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.geronimo.osgi.locator.Activator;
import org.apache.geronimo.osgi.locator.ProviderLocator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.ops4j.pax.exam.CoreOptions;
import static org.ops4j.pax.exam.CoreOptions.bundle;
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.provision;
import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
import org.ops4j.pax.exam.Customizer;
import org.ops4j.pax.exam.Inject;
import org.ops4j.pax.exam.Option;
import static org.ops4j.pax.exam.OptionUtils.combine;
import org.ops4j.pax.exam.junit.JUnit4TestRunner;
import org.ops4j.pax.exam.options.MavenArtifactProvisionOption;
import static org.ops4j.pax.swissbox.tinybundles.core.TinyBundles.*;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
@RunWith(JUnit4TestRunner.class)
public class OSGiServiceLocatorTest {
@Inject
protected BundleContext bundleContext;
@org.ops4j.pax.exam.junit.Configuration
public static Option[] configuration() throws Exception {
Option[] options = options(
// the target code we're testing...
mavenBundle("org.apache.geronimo.specs", "geronimo-osgi-registry"),
// bundle containing test resources
mavenBundle("org.apache.geronimo.specs", "geronimo-osgi-itesta"),
// this bundle opts out of the SPI-Provider status
mavenBundle("org.apache.geronimo.specs", "geronimo-osgi-itestb"),
mavenBundle("org.ops4j.pax.logging", "pax-logging-api"),
felix(),
equinox().version("3.5.0"),
// we want to specify an activator for the test probe bundle that
// is the standard one for adding the locator service to a spec
// bundle. We'll use our activator instance to perform class lookups
new Customizer()
{
@Override
public InputStream customizeTestProbe( InputStream testProbe )
throws IOException
{
return modifyBundle(testProbe)
// these two classes need to be in every participating bundle
.add(org.apache.geronimo.osgi.locator.Activator.class)
.add(org.apache.geronimo.osgi.locator.ProviderLocator.class)
// we don't have any direct references to this class, so force it to be
// included.
.add(org.apache.geronimo.osgi.registry.itest.TestTargetLocal.class)
// set the required activator also
.set(Constants.BUNDLE_ACTIVATOR, org.apache.geronimo.osgi.locator.Activator.class.getName())
// we need an import for activator to function properly.
.set(Constants.IMPORT_PACKAGE, "org.apache.geronimo.osgi.registry.api")
.build();
}
}
);
options = updateOptions(options);
return options;
}
@Test
public void testServiceLocator() throws Exception {
Bundle bundle1 = getInstalledBundle("org.apache.geronimo.specs.geronimo-osgi-itesta");
// now testing the services lookup and instantiation mechanism. These should all be satisfied by
// the extender rather than loaded from the classpath.
Object service = ProviderLocator.getService("org.apache.geronimo.osgi.registry.itest.TestTarget", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(service);
// this should return an instance created from the services definition
assertEquals("org.apache.geronimo.osgi.itesta.TestTarget2", service.getClass().getName());
// we expect a new instance on each call. Verify that the instances are different
Object service2 = ProviderLocator.getService("org.apache.geronimo.osgi.registry.itest.TestTarget", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(service2);
// this should return an instance created from the services definition
assertEquals("org.apache.geronimo.osgi.itesta.TestTarget2", service2.getClass().getName());
assertNotSame(service, service2);
// now testing a multiple instances get. This should only pick up the definition from the
// bundle that includes the SPI-Provider header (testa)
List services = ProviderLocator.getServices("org.apache.geronimo.osgi.registry.itest.TestTarget", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(services);
assertEquals(1, services.size());
// this should return an instance created from the services definition
assertEquals("org.apache.geronimo.osgi.itesta.TestTarget2", services.get(0).getClass().getName());
// these should be different instances
assertNotSame(service, services.get(0));
// this is multiple instances defined in a single services file.
services = ProviderLocator.getServices("org.apache.geronimo.osgi.registry.itesta.MultiTarget", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(services);
assertEquals(2, services.size());
// this should return an instance created from the services definition
assertEquals("org.apache.geronimo.osgi.itesta.TestTarget", services.get(0).getClass().getName());
assertEquals("org.apache.geronimo.osgi.itesta.TestTarget2", services.get(1).getClass().getName());
// this should not be found
service = ProviderLocator.getService("org.apache.geronimo.osgi.registry.itest.NotFound", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNull(service);
// again, not found. Should return an empty list
services = ProviderLocator.getServices("org.apache.geronimo.osgi.registry.itest.NotFound", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(services);
assertEquals(0, services.size());
// this should result in an exception
try {
service = ProviderLocator.getService("org.apache.geronimo.osgi.registry.itest.NoClass", this.getClass(), Thread.currentThread().getContextClassLoader());
fail("Expected ClassNotFoundException not thrown");
} catch (ClassNotFoundException e) {
}
// this should return an empty list
services = ProviderLocator.getServices("org.apache.geronimo.osgi.registry.itest.NoClass", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(services);
assertTrue(services.isEmpty());
// this should result in an exception
try {
service = ProviderLocator.getService("org.apache.geronimo.osgi.registry.itest.BadClass", this.getClass(), Thread.currentThread().getContextClassLoader());
fail("Expected Exception not thrown");
} catch (NullPointerException e) {
}
// but this should just give an empty list again
services = ProviderLocator.getServices("org.apache.geronimo.osgi.registry.itest.BadClass", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(services);
assertTrue(services.isEmpty());
// this should result in an exception
try {
service = ProviderLocator.getService("org.apache.geronimo.osgi.registry.itest.NoConstructor", this.getClass(), Thread.currentThread().getContextClassLoader());
fail("Expected Exception not thrown");
} catch (InstantiationException e) {
}
// and again, an empty list
services = ProviderLocator.getServices("org.apache.geronimo.osgi.registry.itest.NoConstructor", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(services);
assertTrue(services.isEmpty());
// this should result in an exception
try {
service = ProviderLocator.getService("org.apache.geronimo.osgi.registry.itest.NoAccess", this.getClass(), Thread.currentThread().getContextClassLoader());
fail("Expected Exception not thrown");
} catch (IllegalAccessException e) {
}
// empty list
services = ProviderLocator.getServices("org.apache.geronimo.osgi.registry.itest.NoAccess", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(services);
assertTrue(services.isEmpty());
// same set of tests, but this time we're looking for classes, not instances
Class<?> target = ProviderLocator.getServiceClass("org.apache.geronimo.osgi.registry.itest.TestTarget", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(target);
// this should return an instance created from the services definition
assertEquals("org.apache.geronimo.osgi.itesta.TestTarget2", target.getName());
// now testing a multiple instances get. This should pick up a definition from both
// jars on the class path
List<Class<?>> classes = ProviderLocator.getServiceClasses("org.apache.geronimo.osgi.registry.itest.TestTarget", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(classes);
assertEquals(1, classes.size());
// this should return an instance created from the services definition
assertEquals("org.apache.geronimo.osgi.itesta.TestTarget2", classes.get(0).getName());
// this is multiple instances defined in a single services file.
classes = ProviderLocator.getServiceClasses("org.apache.geronimo.osgi.registry.itesta.MultiTarget", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(classes);
assertEquals(2, classes.size());
// this should return an instance created from the services definition
assertEquals("org.apache.geronimo.osgi.itesta.TestTarget", classes.get(0).getName());
assertEquals("org.apache.geronimo.osgi.itesta.TestTarget2", classes.get(1).getName());
// this should not be found
target = ProviderLocator.getServiceClass("org.apache.geronimo.osgi.registry.itest.NotFound", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNull(target);
// again, not found. Should return an empty list
classes = ProviderLocator.getServiceClasses("org.apache.geronimo.osgi.registry.itest.NotFound", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(classes);
assertEquals(0, classes.size());
// this should result in an exception
try {
target = ProviderLocator.getServiceClass("org.apache.geronimo.osgi.registry.itest.NoClass", this.getClass(), Thread.currentThread().getContextClassLoader());
fail("Expected ClassNotFoundException not thrown");
} catch (ClassNotFoundException e) {
}
// an empty list again
classes = ProviderLocator.getServiceClasses("org.apache.geronimo.osgi.registry.itest.NoClass", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(classes);
assertTrue(classes.isEmpty());
// now stop the first bundle, which should remove the service defintions.
bundle1.stop();
// repeat the first queries, which should fail now
service = ProviderLocator.getService("org.apache.geronimo.osgi.registry.itest.TestTarget", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNull(service);
// this should revert to an empty list now.
services = ProviderLocator.getServices("org.apache.geronimo.osgi.registry.itest.TestTarget", this.getClass(), Thread.currentThread().getContextClassLoader());
assertNotNull(services);
assertEquals(0, services.size());
}
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();
}
protected static Option[] updateOptions(Option[] options) {
// 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"))) {
Option[] ibmOptions = options(
wrappedBundle(mavenBundle("org.ops4j.pax.exam", "pax-exam-junit"))
);
options = combine(ibmOptions, options);
}
return options;
}
}