6 Replies Latest reply on Sep 27, 2011 3:01 PM by pedrokowalski

    Multiple @Deployment for different container types in one test

    pedrokowalski

      Howdy aliens!

       

      Just want to make sure I understand what is the problem with the deployment for different containers, what is doable right now and what is not.

       

      I want to have multiple @Deployment annotations for different container types. One for Glassfish 3.1, one for AS7 - all in one test case. Now I want to execute some tests using one type of container and different tests using another type of container.

       

      As I understand, right now it's not achievable in a _single test run_?

       

      I can, however, define different deployments for different containers and can activate one or another using System property (PoC for my own purpose: http://pastebin.com/wj0f3XNX - don't mind usage of string as deployment name instead of custom annotation - didn't know about https://issues.jboss.org/browse/ARQ-293 before). This property activates maven profile which attaches the appropriate container type dependency.

       

      My question is - can I have both maven dependencies (for both container types) defined at the same time and choose one of those on per-test base, i.e. using arquillian.xml or some extension? In other words, can I omit the stage of using Maven profiles to choose the container adapter I want to run the tests with?

       

      I've looked at the <container> element in arquillian.xml and there is a <dependency> maven style element (https://issues.jboss.org/browse/ARQ-196) which looks promising. Unfortunately I can't find more detailed info what this element is for. Could it be used for the purpose I discussed above, like:

       

      <container qualifier="remote-gf3">

          <dependencies>

              <dependency>org.jboss.arquillian.container:arquillian-glassfish-remote-3.1:1.0.0.Final-SNAPSHOT</dependency>

          </dependencies>

      </container>

      <container qualifier="remote-as7">

          <dependencies>

              <dependency>org.jboss.as:jboss-as-arquillian-container-remote:7.0.2.Final</dependency>

          </dependencies>

      </container>

       

      Please correct me if I've made some wrong assumptions.

       

      TIA.

       

      Cheers!

      Pedro

       

      PS. Quite old discussion about the feature: https://community.jboss.org/message/561762#561762

        • 1. Re: Multiple @Deployment for different container types in one test
          aslak

          We have two different use cases here.

           

          1. Support multiple containers in one run, and target deployments individually

           

          This is supported today, but has some limitations. You can use the group element in arquillian.xml to configure multiple different configurations of a single container type and target deployments in the TestClass to them individually.

           

          <group>
            <container qualifier="c1" />
            <container qualifier="c2" />
          </group>
          

           

           

          @RunWith(Arquillian.class)
          public class TestClass {
          
            @Deployment(name = "d1") @TargetsContainer("c1")
            public static WebArchive deployToC1() {}
          
          
            @Deployment(name = "d2") @TargetsContainer("c2")
            public static WebArchive deployToC2() {}
            
            @Test @OperatesOnDeployment("d1")
            public void shouldRunInContextOfD1OnC1() {}
          
          
            @Test @OperatesOnDeployment("d2")
            public void shouldRunInContextOfD2OnC2() {}
            
          }
          

           

          What Arquillian will do in this scenario is to start/connect to both containers in the group within the same run, so both will be active.

          The limitation is that container c1 and c2 has to be of the same type, e.g. JBoss AS 7 Managed. The most common user will most likely run a single server type, so this is not to much of a hassle.

           

          Tho the original intent was to support mixes of different containers as well, e.g. c1 being a JBoss AS 7 container and c2 being a GlassFish 3.1 container. This is where the container/dependencies configuration came in. But we ran into to many ClassLoading issues at the time of impl, so the handling of dependencies has been removed from core. We will revisit this for 1.1+ by probably introducing something like JBoss Modules on the client side and let it handle the havy isolation / classloading issues.

           

           

          2. Support different deployments based on running container

           

          This is currently not supported directly by Arquillian today, with out relying on System Properties or other means. In this case you have the same single deployment that you want to deploy, but different contianers needs different versions of it. e.g. a CDI based deployment for Tomcat requires Weld Servlet, but not JBoss AS 6.

           

           

          <container qualifier="c1" />
          <container qualifier="c2" />
          

           

          @RunWith(Arquillian.class)
          public class TestClass {
          
            @Deployment @ActiveWhenContainerIs("c1")
            public static WebArchive deployToC1Types() {}
          
          
            @Deployment @ActiveWhenContainerIs("c2")
            public static WebArchive deployToC2Types() {}
            
            @Test 
            public void shouldRunInContextOfDeployment() {}
            
          }
          
          

           

           

          In this scenario, depending on which container is running, c1 or c2, the different deployment would be used. You would typically run the TestSuite against one specific container and have the TestClass 'configure' it self accordingly

           

          mvn test -Parquillian.launch=c1
          mvn test -Parquillian.launch=c2
          
          

           

          (@ActiveWhenContainerIs is a fictional annotation and just used for illustration)

          • 2. Re: Multiple @Deployment for different container types in one test
            pedrokowalski

            Thanks a lot Aslak for your time and detailed description.

             

            Ok, so at this moment, I think the second case would be more interesting.

            Is there a way to get information about which container is currently active? I guess that this container registers somehow in Arquillian-core so it should be possible?

             

            TIA.

             

            Cheers,

            Pedro

            • 3. Re: Multiple @Deployment for different container types in one test
              aslak

              In a Extension you can @Inject Instance<ContainerRegistry>, that will tell you all registered containers.

               

              And possible you can intercept the event DeployDeployment and not call proceed if the Deployment does not match the Container, that will basically cancel the Event for further processing.

               

              public void someMethod(@Observes EventContext<DeploymentEvent> context) {
                 if( 'something match' )
                 {
                   context.proceed();
                 }
              }
              

               

               

              But you have no link between @Deployment Method and Deployment which makes it hard to add MetaData for matching against without rescanning the TestClass (which might not give you a unique answer, and might not even come from the Class )

               

              For 1.1/2.0 there is planned some form of MetaData layer between what Arq operates on and how it is read, but currently we have some direct reflections calls and 'static' metadata (DeploymentDescription) that is not too helpful to a extension in this case where you want to add more data.

               

               

              For now, It's probably better to do the initial filtering in the DeploymentScenarioGenerator, before it's read into the DeploymentScenario.

              • 4. Re: Multiple @Deployment for different container types in one test
                pedrokowalski

                Aslak, should the observer of the EventContext<DeploymentEvent> (the method you posted) be fired when the method is in DeploymentScenarioGenerator registered as a LoadableExtension?

                 

                It doesn't fire in my case...

                • 5. Re: Multiple @Deployment for different container types in one test
                  aslak

                  There is a difference between a Service and a Observer in Arquillian, they can't be the same(or they can, but it won't be the same instance).

                   

                  DeploymentScenarioGenerator is a Service that 'some' Observer expose as a extension point.

                   

                  ExtensionBuilder.service(Interface, Impl) vs ExtensionBuilder.observer(Class)

                   

                  All Events are Observed by Observers.

                  • 6. Re: Multiple @Deployment for different container types in one test
                    pedrokowalski

                    Thanks a lot. I guess I will have to catch up with the Arquillian architecture :-)

                     

                    Cheers!