6 Replies Latest reply on Dec 21, 2010 11:41 AM by aslak

    ArchiveProvider annotation

    thomas.diesler

      The current @ArchiveProvider approach works like this

       

         Archive<?> fooArchive = container.getTestArchive("foo");
         Bundle fooBundle = container.installBundle(fooArchive);
      
         Archive<?> barArchive = container.getTestArchive("bar");
         Bundle barBundle = container.installBundle(barArchive);
      
      
         @ArchiveProvider
         public static JavaArchive getBundleArchive(final String archiveName)
         {
            final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, archiveName);
            if (archiveName.equals("foo")) {
               archive.addClasses(FooService.class, FooActivator.class);
            }
            else if (archiveName.equals("bar")) {
               archive.addClasses(BarService.class, BarActivator.class);
            }
            return archive;
         }
      

       

      Because the @ArchiveProvider does not have a descriminator there can only be one. The switch logic must be implemented in the provider method.

       

      Instead, I suggest it works like this

       

         Archive<?> fooArchive = container.getTestArchive("foo");
         Bundle fooBundle = container.installBundle(fooArchive);
      
         Archive<?> barArchive = container.getTestArchive("bar");
         Bundle barBundle = container.installBundle(barArchive);
      
         @ArchiveProvider("foo")
         public static JavaArchive getFooArchive()
         {
            final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "foo");
            archive.addClasses(FooService.class, FooActivator.class);
            return archive;
         }
      
         @ArchiveProvider("bar")
         public static JavaArchive getBarArchive()
         {
            final JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "bar");
            archive.addClasses(BarService.class, BarActivator.class);
            return archive;
         }
      
      

       

      The provider method with name parameter should be preserved for dynamic archive provisioning. i.e. The test case decides at runtime what archives it needs.

        • 1. Re: ArchiveProvider annotation
          bosschaert

          Yes, that would be a nice addition, as you say the parameterized version is used by performance tests where it is not known in advance what the archives will be (the test decides that based on the number of bundles to be deployed).

           

          This would mean we support both:

           

          {code}@ArchiveProvider("foo")

          public static JavaArchive getFooArchive()

          { ... }{code}

           

          and

           

          {code}@ArchiveProvider

          public static JavaArchive getBundleArchive(String archiveName)

          { ... }{code} 

          • 2. Re: ArchiveProvider annotation
            aslak

            Arq .next has @Deployment(name = "qualifier", startup = true | false, testable = true | false)

             

            Name = used to identify a deployment for manual deployment using the Deployer API or when using @Test @DeploymentTarget(name = "") to target a TestMethod against a specific Deployment(multiple deployments against multiple containers are allowed)

             

            Startup = boolean to say if this should be deployed during TestClass startup or should be done manually via the Deployer API

             

            Testable = boolean to say if this should be enriched for IN_CONTAINER testing or not. (basically a @Run pr deployment)

            • 3. Re: ArchiveProvider annotation
              thomas.diesler

              How about the use case where a test method itself uses a certain deployment API to deploy an archive? This would be needed to test the deployment API itself

              • 4. Re: ArchiveProvider annotation
                aslak

                To describe the full scenario:

                 

                   @Deployment(name = "dep1", testable = true, startup = true) @Target("server-1")
                   public static Archive<?> createDeployment() { ... }
                
                   @Deployment(name = "dep2", testable = false, startup = false) @Target("server-2")
                   public static Archive<?> createDeployment2() { ... }
                
                   @ArquillianResource
                   private Deployer deployer;
                
                   @Test @DeploymentTarget("dep1")
                   public void shouldBeAbleTo() {
                     deployer.deploy("dep2");
                   }
                

                 

                Here we have 2 named deployment, dep1 and dep2.

                • dep1 will be deployed to server-1 during startup and will be enriched for incontainer testing.
                • dep2 is targeted against server-2, but will not be deployed during startup nor will it be incontainer enriched.

                 

                The @Test method is marked to be targeted against deployment dep1, and dep1 is testable so it will run incontainer on server-1.

                The injectable Arquillian resource, Deployer, that is called during @Test execution on server-1 will do a callback to the client. The client will then look at the named deployment dep2 and determine that it should deploy that against target server-2.

                 

                Just to add some more info to the logic here:

                • dep2 could point to the same server as from where you are calling for a manual deployment
                • dep2 could be marked testable as well
                  • if dep2 is testable, the next @Test method could target dep2 for incontainer testing of a manual deployed archive
                • what server-1 and server-2 are is defined in arquillian.xml. Refered to by a qualifier so the backing container can easly be swapped.
                • when a deployment is not marked as testable, but a @Test method is targeting it via @DeploymentTarget, AS_CLIENT runmode is used.
                • when a deployment is marked as testable, you can override IN_CONTAINER runmode on method level by using @Run(AS_CLIENT)
                • injection of Arquillian resource Deployer is supported in both IN_CONTAINER and AS_CLIENT

                 

                 


                • 5. Re: ArchiveProvider annotation
                  thomas.diesler

                  Very good.

                   

                  Are injected ARQ resources available in @Before or even @BeforeClass ?

                  • 6. Re: ArchiveProvider annotation
                    aslak

                    They will be available in @Before, havn't given @BeforeClass much though yet..

                     

                    I don't remember, did you file a jira on static before class enrichment?