Search code examples
javaunit-testingosgiapache-felixarquillian-drone

Arquillian+OSGi+Test Different Framework Properties


I have an OSGi bundle which reads some properties from the config.properties file of Apache Felix during the activation process, and if this configuration is malformed or absent then the bundle should not start. For this, I am creating its respective Unit Test, I am using Arquillian for the tests. The problem arises when I want to provide different types of conf.properties to different Arquillian tests, in order to cover each scenario.

When Arquillian runs the tests it load a framework.properties file from the /test/resources/ folder to initialize Apache Felix, install the test bundles and run the tests. Now, my question is how can I provide a different framework.properties file for each test case?

Here is the Arquillian Unit Test I use:

@RunWith(Arquillian.class)
public class PersistenceLoaderTest {

    @Deployment
    public static Archive<?> createDeployment() {
        final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "persistence-arq.jar");

        archive.addClass(ProviderLoader.class);
        archive.setManifest(new Asset() {
            public InputStream openStream() {
                OSGiManifestBuilder builder = OSGiManifestBuilder.newInstance();
                builder.addBundleSymbolicName(archive.getName());
                builder.addBundleManifestVersion(2);                    
                builder.addImportPackages("org.osgi.service.startlevel", "org.osgi.service.url");
                builder.addImportPackages(ProviderLoader.class);
                return builder.openStream();
            }
        });

        return archive;
    }

    @ArquillianResource
    public Bundle bundle;

    @ArquillianResource
    BundleContext bundleContext;

    @Test
    public void loadFrameworkConfiguration(){
        // What goes here?
    }
}

And the framework.properties file:

# The Felix Framewok log level
#
# ERROR = 1;
# WARNING = 2;
# INFO = 3;
# DEBUG = 4;
felix.log.level=4

org.domain.database=mydb
org.domain.driver=org.hsqldb.jdbcDriver
org.domain.url=jdbc:hsqldb:file:
org.domain.username=sa
org.domain.password=

These are the property values I need to change and test them for different scenarios.


Solution

  • To my understanding this is Container level properties and not Deployment level properties, so you would need to restart the container for it to take effect.

    You could achieve this by setting the Container mode in arquillian.xml to manual.

    <arquillian>
       <container qualifier="manual_felix" mode="manual">
       </container>
    </arquillian>
    

    Then in a TestClass you can inject the ContainerController and start it with new properties for each run.

    @RunWith(Arquillian.class)
    public class TestA {
    
       @Deployment(name = "x", managed = false) @TargetsContainer("manual_felix")
       public static Archive<?> deployment() {
          return ShrinkWrap.create....
       }
    
       @ArquillianResource
       private ContainerController cc;
    
       @ArquillianResource
       private Deployer d;
    
    
       @Test @InSequence(1)
       public void start() {
          cc.start("manual_felix", new Config().add("frameworkProperties", "my-custom-properties-file"));
          d.deploy("x");
       }
    
       @Test @InSequence(2) @OperatesOnDeployment("x")
       public void shouldDoSomethingInsideX() {
           // executes inside container in context of X
       }
    }