glassfishtestngjboss-arquillianglassfish-embedded

Arquillian - programmatic configuration


I am writing integration tests using Arquillian with embedded glassfish 3.1.2.2 using TestNG. I want to be able to run those tests in parallel, and for this case i need to dynamically configure glassfish ports and database name (we already have this set-up, and I want to reuse it of arquillian tests). What I am missing is a 'before container start' hook, where I could prepare the database, lookup free ports and update my glassfish configuration (domain.xml, could also be glassfish-resources.xml). Is there a 'clean' solution for this, or my usecase was not foreseen by Arquillian developers?

The hacky way I solved it currently is to override arquillian's beforeSuite method but this one gets called twice - at test startup and then in the container (therefore my pathetic static flag). Secondly, this solution would not work for JUnit based tests as there's no way to intercept arquillian's before suite:

public class FullContainerIT extends Arquillian {

    private static boolean dbInitialized;

    //@RunAsClient <-supported by @Test only
    @Override
    @BeforeSuite(groups = "arquillian", inheritGroups = true)
    public void arquillianBeforeSuite() throws Exception {
        if (dbInitialized == false) {
            initializeDb();
            dbInitialized = true;
        }
        super.arquillianBeforeSuite();
    }
}

Some ideas I had:
+ having @BeforeSuite @RunAsClient seems to be what I need, but @RunAsClient is supported for @Test only;
+ I have seen org.jboss.arquillian.container.spi.event.container.BeforeStart event in Arquillian JavaDocs, but I have no clue how to listen to Arquillian events;
+ I have seen there is a possibility to have @Deployment creating a ShrinkWrap Descriptor, but these do not support Glassfish resources.


Solution

  • I found a clean solution for my problem on JBoss forum. You can register a LoadableExtension SPI and modify the arquillian config (loaded from xml). This is where I can create a database and filter glassfish-resources.xml with proper values. The setup looks like this:

    package com.example.extenstion;
    
    public class AutoDiscoverInstanceExtension 
                     implements org.jboss.arquillian.core.spi.LoadableExtension {
    
        @Override
        public void register(ExtensionBuilder builder) {
            builder.observer(LoadContainerConfiguration.class);
        }
    }
    
    package com.example.extenstion;
    
    public class LoadContainerConfiguration {
    
        public void registerInstance(@Observes ContainerRegistry, ServiceLoader serviceLoader) {
    
            //Do the necessary setup here
            String filteredFilename = doTheFiltering();
    
            //Get the container defined in arquillian.xml and modify it
            //"default" is the container's qualifier 
            Container definition = registry.getContainer("default");
            definition.getContainerConfiguration()
                    .property("resourcesXml", filteredFilename);
        }
    }
    

    You also need to configure the SPI Extension by creating a file
    META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension
    with this contents:

    com.example.extenstion.AutoDiscoverInstanceExtension