0 Replies Latest reply on Sep 7, 2010 11:40 AM by Thomas Diesler

    Major OSGi feature update

    Thomas Diesler Master

      This thread covers a major update in OSGi testing functionality.

       

      ARQ-193 Create auxillary OSGi test bundle
      ARQ-235 OSGi Framework does not get stopped
      ARQ-190 Remote OSGi bundle testing
      ARQ-272 Allow @Deployment to be optional
      ARQ-198 Install bundle from maven dependencies
      ARQ-194 Support multiple bundle deployments

       

      As always, the accumulated code is at http://github.com/jbosgi/arquillian/tree/jbosgi

       

      ARQ-193 Create auxillary OSGi test bundle

       

      In your ARQ test you can now do

       

      @RunWith(Arquillian.class)
      public class ARQ193GeneratedTestCase
      {
         @Deployment
         public static Archive<?> createDeployment()
         {
            return ShrinkWrap.create(JavaArchive.class, "empty-bundle");
         }
      
         @Inject
         public Bundle bundle;
      
         ...
      }
      

       

      ARQ  generates the OSGi manifest for you and also puts the test class in the  test archive. If there already is a manifest in the test archive, ARQ  appends the necessary infrastructure OSGi headers. The Import-Package  header is determined by scanning field, methods, annotations. ARQ cannot  however "guess" test specific OSGi headers like a potential  Bundle-Activator, etc

       

      For this to work I added the ARQ lifecycle Context to the DeploymentPackager

       

      public interface DeploymentPackager
      {
         /**
          * @param context The test lifecycle context
          * @param testDeployment Value object containing the application {@link Archive} and other auxiliary library {@link Archive}s. 
          * @return The prepared archive for deployment.
          */
         Archive<?> generateDeployment(Context context, TestDeployment testDeployment);
      }
      

       

      ARQ-235 OSGi Framework does not get stopped

       

      Instead  of relying on the DeployableContainer start/stop methods, we now  boostrap/shutdown the OSGi Framework as part of the deploy/undeploy  methods. This gives us @BeforeClass, @AfterClass behaviour (i.e. a fresh  OSGi Framework for every test case in the osgi-embedded scenario)

      This resolution is considered a hack and should be removed as soon as we have configurable container lifecycle.

       

      ARQ-190 Remote OSGi bundle testing

      This  feature is critical for the upcoming AS7/OSGi integration. The OSGi  RemoteDeployableContainer does not bootstrap a local OSGi Framework  instead it connects to a remote MBeanServer using a JSR-160 JMXConnector. The corresponding JMXConnectorServer is started by the jboss-osgi-jmx bundle, which must be deployed on the remote OSGi Framework.

       

      ARQ-272 Allow @Deployment to be optional

       

      You can now do

       

      @RunWith(Arquillian.class)
      public class ARQ272TestCase
      {
         @Inject
         public Bundle bundle;
      
         @Test
         public void testBundleInjection() throws Exception
         {
            assertNotNull("Bundle injected", bundle);
            assertEquals("Bundle RESOLVED", Bundle.RESOLVED, bundle.getState());
      
            assertEquals(ARQ272TestCase.class.getSimpleName(), bundle.getSymbolicName());
            bundle.loadClass(ARQ272TestCase.class.getName());
      
            bundle.stop();
            assertEquals("Bundle RESOLVED", Bundle.RESOLVED, bundle.getState());
      
            bundle.uninstall();
            assertEquals("Bundle UNINSTALLED", Bundle.UNINSTALLED, bundle.getState());
         }
      }
      

       

      Because  ARQ always adds the test class to the @Deployment archive, there is  little reason why an OSGi test must supply an empty archive. I modified  DeploymentAnnotationArchiveGenerator such that it generates an empty  archive if there is no @Deployment annotation in the test case.

       

      ARQ-198 Install bundle from maven dependencies

       

      OSGi test cases support injection of an OSGiContainer.  On that container there are a number of methods that let you install  bundles from the classpath and the local maven repository like this

       

         @Test
         public void testInstallBundleAlreadyInstalled() throws Exception
         {
            Bundle arqBundle = container.getBundle(ARQUILLIAN_OSGI_BUNDLE, null);
            assertNotNull("ARQ bundle installed", arqBundle);
            
            Bundle result = container.installBundle(ARQUILLIAN_OSGI_BUNDLE);
            assertEquals(arqBundle, result);
            
            result = container.installBundle("org.jboss.arquillian.protocol", ARQUILLIAN_OSGI_BUNDLE, getArquilianVersion());
            assertEquals(arqBundle, result);
         }
      

       

       

      ARQ-194 Support multiple bundle deployments

       

      OSGi test methods can now callback to the client and have a test bundle generated on demand. This is also done via the injected OSGiContainer.

       

      @RunWith(Arquillian.class)
      public class ARQ194TestCase 
      {
         @Inject
         public OSGiContainer container;
      
         @Test
         public void testGeneratedBundle() throws Exception
         {
            Archive<?> archive = container.getTestArchive("arq194-bundle");
            Bundle bundle = container.installBundle(archive);
      
            ...
         }
      
         public static class BundleArchiveProvider implements ArchiveProvider
         {
            public JavaArchive getTestArchive(String name)
            {
               final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, name);
               archive.addClasses(ARQ194Activator.class, ARQ194Service.class);
               return archive;
            }
         }
      } 
      
      

       

      The  test case contains an inner class that implements ArchiveProvider.  During test method execution the OSGiContainer calls back to the client  to invoke  ArchiveProvider.getTestArchive(String). The assets that are  packaged by in the JavaArchive are taken from the test client's  classpath and not from test bundle's OSGi class space.

       

      The  injected OSGiContainer works for embedded and remote OSGi Frameworks.  In case of the remote scenario, ARQ sets up two-way communication via  the JMX protocol

       

      --------------------------------------

       

      We are currently working on migrating all of our remaining Husky tests to Arquillian, which is a prerequisite for the upcoming 1.0.0.Beta9 release. I would reassign the above ARQ issues when we are done.

       

      cheers

      -thomas