Sunday, 4 November 2012

OSGi Testing: make your integration/functional tests clearer. A sample with PaxExam

Hello,

two years ago I've posted about small library that I used for my OSGi integration tests. During the last tree weeks I made some changes in it:
  • Sources were moved to GitHub
  • Maven groupId and artifactId were changed
  • Initialization process of OSGi assertions was simplified and does not require BundleContext
  • New utility and assertion methods for Bundles were added.

What is the difference?

You can compare two test methods that test the same functionality.
    /**
     * Test bundle and service without OSGi assertions/utils
     *
     * @throws org.osgi.framework.BundleException
     *                              bundle start/stop problems
     * @throws org.osgi.framework.InvalidSyntaxException
     *                              filter creation problems
     * @throws InterruptedException wait exception
     */
    @Test
    public void test_Without_OSGiAssertions() throws BundleException, InterruptedException, InvalidSyntaxException {
        ServiceTracker packageAdminTracker = new ServiceTracker(getBundleContext(), PackageAdmin.class.getName(), null);
        packageAdminTracker.open();
        PackageAdmin packageAdmin = (PackageAdmin) packageAdminTracker.getService();
        assertNotNull(packageAdmin);
        packageAdminTracker.close();
        Bundle[] bundles = packageAdmin.getBundles("org.knowhowlab.osgi.testing.it.test.bundle", null);
        // asserts that test bundle is installed
        assertNotNull(bundles);
        // gets bundle instance
        Bundle bundle = bundles[0];
        // asserts that test bundle is resolved
        assertTrue(bundle.getState() == Bundle.INSTALLED || bundle.getState() == Bundle.RESOLVED);
        ServiceTracker serviceTracker1 = new ServiceTracker(getBundleContext(), "org.knowhowlab.osgi.testing.it.testbundle.service.Echo", null);
        serviceTracker1.open();
        assertEquals(0, serviceTracker1.size());
        // start bundle
        bundle.start();
        // asserts that test bundle is active
        assertEquals(Bundle.ACTIVE, bundle.getState());
        // asserts that test service is available within 2 seconds
        assertNotNull(serviceTracker1.waitForService(2000));
        // asserts that test service with custom properties is available
        ServiceTracker serviceTracker2 = new ServiceTracker(getBundleContext(), FrameworkUtil.createFilter(
                "(&(" + Constants.OBJECTCLASS + "=org.knowhowlab.osgi.testing.it.testbundle.service.Echo)" +
                        "(testkey=testvalue))"), null);
        serviceTracker2.open();
        assertTrue(serviceTracker2.size() > 0);
        // gets service by class and filter
        Echo echo = (Echo) serviceTracker2.getService();
        // asserts service method call
        assertEquals("test", echo.echo("test"));
        // stops bundle
        bundle.stop();
        // asserts that test bundle is resolved
        assertEquals(Bundle.RESOLVED, bundle.getState());
        // asserts that test service is unregistered
        assertEquals(0, serviceTracker1.size());
    }

    /**
     * The same Test bundle and service with OSGi assertions/utils
     *
     * @throws org.osgi.framework.BundleException
     *          bundle start/stop problems
     * @throws org.osgi.framework.InvalidSyntaxException
     *          filter creation problems
     */
    @Test
    public void test_With_OSGiAssertions() throws BundleException, InvalidSyntaxException {
        // asserts that test bundle is installed
        assertBundleAvailable("org.knowhowlab.osgi.testing.it.test.bundle");
        // asserts that test bundle is resolved
        assertBundleState(Bundle.INSTALLED | Bundle.RESOLVED, "org.knowhowlab.osgi.testing.it.test.bundle", 5, TimeUnit.SECONDS);
        // gets bundle instance
        Bundle bundle = findBundle(bc, "org.knowhowlab.osgi.testing.it.test.bundle");
        // asserts that test service is unavailable
        assertServiceUnavailable("org.knowhowlab.osgi.testing.it.testbundle.service.Echo");
        // start bundle
        bundle.start();
        // asserts that test bundle is active
        assertBundleState(Bundle.ACTIVE, "org.knowhowlab.osgi.testing.it.test.bundle");
        // asserts that test service is available within 2 seconds
        assertServiceAvailable("org.knowhowlab.osgi.testing.it.testbundle.service.Echo", 2, TimeUnit.SECONDS);
        // asserts that test service with custom properties is available
        assertServiceAvailable(and(create(Echo.class), eq("testkey", "testvalue")));
        // gets service by class and filter
        Echo echo = ServiceUtils.getService(getBundleContext(), Echo.class, eq("testkey", "testvalue"));
        // asserts service method call
        assertEquals("test", echo.echo("test"));
        // stops bundle
        bundle.stop();
        // asserts that test bundle is resolved
        assertBundleState(Bundle.RESOLVED, "org.knowhowlab.osgi.testing.it.test.bundle");
        // asserts that test service is unregistered
        assertServiceUnavailable(Echo.class);
    }

How to use the library with PaxExam

Add Maven dependencies to your integration tests pom.xml
        <dependency>
            <groupId>org.knowhowlab.osgi</groupId>
            <artifactId>org.knowhowlab.osgi.testing.utils</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.knowhowlab.osgi</groupId>
            <artifactId>org.knowhowlab.osgi.testing.assertions</artifactId>
            <version>1.0.0</version>
        </dependency>

Include library bundles into PaxExam tests
@Configuration
protected static Option[] baseConfiguration() {
   return options(
...
mavenBundle().groupId("org.knowhowlab.osgi").artifactId("org.knowhowlab.osgi.testing.utils").version(System.getProperty("project.version")),

mavenBundle().groupId("org.knowhowlab.osgi").artifactId("org.knowhowlab.osgi.testing.assertions").version(System.getProperty("project.version")),
...
    );
}

Use in your PaxExam integration tests:
// assert bundle with symbolic name "org.knowhowlab.osgi.testing.utils" is installed into OSGi framework
assertBundleState(Bundle.ACTIVE, "org.knowhowlab.osgi.testing.utils", 5, TimeUnit.SECONDS);
// assert bundle with symbolic name "org.knowhowlab.osgi.testing.utils" is installed into OSGi framework
assertBundleAvailable("org.knowhowlab.osgi.testing.utils");
// assert bundle with symbolic name "org.knowhowlab.osgi.testing.utils" and version "1.0.1"
// is installed into OSGi framework
assertBundleAvailable("org.knowhowlab.osgi.testing.utils", new Version("1.0.1"));
// assert bundle with symbolic name "org.knowhowlab.osgi.testing.utils" and version "2.0.0"
// is not installed into OSGi framework
assertBundleUnavailable("org.knowhowlab.osgi.testing.utils", new Version("2.0.0"));

// assert PackageAdmin service is available in OSGi registry
assertServiceAvailable(PackageAdmin.class, 5, TimeUnit.SECONDS);
// assert MonitorAdmin service is unavailable in OSGi registry
assertServiceUnavailable("org.osgi.service.monitor.MonitorAdmin");
// assert StartLevel service is available in OSGi registry
assertServiceAvailable(StartLevel.class);
// assert PackageAdmin service is available in OSGi registry
assertServiceAvailable(FilterUtils.create(PackageAdmin.class));
// assert MonitorAdmin service is unavailable in OSGi registry
assertServiceUnavailable(FilterUtils.create("org.osgi.service.monitor.MonitorAdmin"));

Here you can find the last sources of the sample.

Thank you for your attention. Your feedback is welcome as usual.
Best Regards.

1 comment:

  1. I do found it informative and quite handy as well, hopefully this would remain same it's been appearing here, looking forward the best use of the sufficient ideas. Visit college paper for best papers.

    ReplyDelete