1

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.

Joe Almore
  • 4,036
  • 9
  • 52
  • 77

1 Answers1

0

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
   }
}
Aslak Knutsen
  • 706
  • 3
  • 4
  • Hi thanks for your answer. Interesting, and what if I place the `start()` and `deploy()` bodies in a single test method, would that allow me to test different framework properties on each test method? – Joe Almore Mar 23 '15 at 23:50
  • Yes, that's doable. You would need to split the test methods only if you want to execute something incontainer when deployed. You can't test inside something you haven't deployed yet. Updated answer. *note* container.mode = managed is managed in a Class scope, meaning it will only be automatically undeployed/stopped in AfterClass. If you want to test multiple start/stop sequences in a single TestClass you need to manually undeploy/stop the container per @ Test as well. You can simply do that in @ After. – Aslak Knutsen Mar 24 '15 at 08:58
  • Thanks, it works. Just one detail, using this configuration if I want to add a bundle dependency to the test (e.g. to `org.osgi.compendium-5.0.0.jar`), do I have to create a separate method with `@Deployment` or is there any better way to it? – Joe Almore Mar 24 '15 at 22:18
  • Not sure I understand. Wouldn't you just add that as a dependency in the MANIFEST in the archive defined in deployment() already ? – Aslak Knutsen Mar 30 '15 at 15:51
  • I created a new question for it, [here](http://stackoverflow.com/questions/29378462/arquillian-osgi-bundle-dependencies) you can read the details. – Joe Almore Mar 31 '15 at 21:01