7 Replies Latest reply on Jul 20, 2010 7:23 AM by pmuir

    Arquillian test lifecycle

    pmuir

      I was chatting to Aslak today about the Arquillian lifecycle. I still think we've got it a bit upside down - but it looks like no one knew I thought this ;-) I think this is the reason why we are struggling with a number of things - ALRs complaint that Arquillian is fiddling with his archives, the problems with actually doing intelligent defaults for deployment, the difficulty in adding stuff to the resulting deployment etc.

       

      At the moment, Arquillian calls the @Deployment method, takes whatever the user outputs, does some magic (do we have a list of the rules?), and then sends it off to the container. I think we should invert two of these steps, such that the lifecycle becomes:

       

      1. Arquillian creates a Shrinkwrap archive containing the magic - the support clasess it needs for the current deployment scenario [1]
      2. It calls the @Deployment method, injecting the archive created in (1) as the only parameter
      3. The user then can add stuff/remove stuff from/to the deployment however they like [2], and returns it from the method. They can alternatively call Shrinkwrap themselves to create a new archive, ignoring the Arquillian magic.
      4. Arquillian then deploys whatever the user returns, unmodified.

       

      [1] Arquillian inspects the declared type of the parameter of the @Deployment method to establish what sort of archive to create. Typically, someone is going to use either WebArchive or EnterpriseArchive I think

      [2] There is some interesting problems with this approach, for example, if the user selects EarArchive, then how do we allow them easily to get to the ejb-archive and web-archive Arquillian populates the EarArchive with? Some thoughts on this later.

       

      Some examples (on pastebin, as there is no sane way to put code on this forum)

       

       

      Now, we have a much more flexible way to address a few of the issues we currently have:

       

      • When ALR wants to ignore Shrinkwrap magic, he just returns his own Archive. This is a obvious (you can see it in the code), and simple
      • When Matt wants to deploy multiple things at the same time (e.g. a standalone ejb-jar and a war), we can easily enhance Arquillian to allow returning a collection of Archives, each one of which will be deployed without running into thorny questions about which is *the* artifact to enhance
      • When I want to create a really complex deployment, it's easy to work out what is going on (e.g. Nik today asked why if he creates an Ear, the Test class is omitted - this is completely counterintuitive today, but with this scheme above, it's obvious)

       

      I'll follow up with a post about how you can then configure the defaults for your @Deployment

        • 1. Re: Arquillian test lifecycle
          aslak

          Pete Muir wrote:

          • When ALR wants to ignore Shrinkwrap magic, he just returns his own Archive. This is a obvious (you can see it in the code), and simple

          In this case we can also support a no-argument @Deployment method.

          Hmm.. does this mean we can remove the @Run(AS_CLIENT) ? If @Deployment method takes no arguments, we're not expect to do anything. We run locally.

           

          • When Matt wants to deploy multiple things at the same time (e.g. a standalone ejb-jar and a war), we can easily enhance Arquillian to allow returning a collection of Archives, each one of which will be deployed without running into thorny questions about which is *the* artifact to enhance

          This still leaves us with the issue of which Archive do we need to analyse to fetch the metadata about how to call the 'protocol' (/test/ ? /mywar/ ? etc) and doing deployment at 'any' given time(I believe we can open up for injection of a Deployer to solve this one).

          • 2. Re: Arquillian test lifecycle
            pmuir

            Aslak Knutsen wrote:

             

            Pete Muir wrote:

            • When ALR wants to ignore Shrinkwrap magic, he just returns his own Archive. This is a obvious (you can see it in the code), and simple

            In this case we can also support a no-argument @Deployment method.

            Hmm.. does this mean we can remove the @Run(AS_CLIENT) ? If @Deployment method takes no arguments, we're not expect to do anything. We run locally.

            Depends how concerned we are about backwards compatibility - we already said what an no-args @Deployment method would do...

             

            I also like the explictness of @Run(AS_CLIENT)...

             

            • When Matt wants to deploy multiple things at the same time (e.g. a standalone ejb-jar and a war), we can easily enhance Arquillian to allow returning a collection of Archives, each one of which will be deployed without running into thorny questions about which is *the* artifact to enhance

            This still leaves us with the issue of which Archive do we need to analyse to fetch the metadata about how to call the 'protocol' (/test/ ? /mywar/ ? etc) and doing deployment at 'any' given time(I believe we can open up for injection of a Deployer to solve this one).

             

            I think we use the one that we injected in the first place...

            • 3. Re: Arquillian test lifecycle
              pmuir

              We can now do support configuration like this http://pastebin.com/X78bMRPs and then use it like http://pastebin.com/XpwCkdjr

              • 4. Re: Arquillian test lifecycle
                dan.j.allen

                Gut reaction: brilliant. Or, in the spirit of current world events. Goooooooooooooal.

                 

                I've also felt that something was not right, though I wouldn't go so far to say I was complaining about it.

                 

                I spent much of Friday confused about why my archive wasn't turning out the way I wanted. I knew that Arquillian was doing magic, but unsure what I could do to change its behavior. Turning it upside down makes it much more clear.

                 

                I also wonder if we can get the container configuration that is currently being used injected as a second argument. Reason being, if it's GlassFish I might want to add one descriptor and if it's JBoss AS another. I don't couple my test to the container because it's a runtime choice. And if we support multiple executions of the same test class, one per target container, it's still called multiple times and thus safe.

                 

                http://pastebin.com/yHHpb1zx

                • 5. Re: Arquillian test lifecycle
                  dan.j.allen

                  Aslak Knutsen wrote:

                   

                  This still leaves us with the issue of which Archive do we need to analyse to fetch the metadata about how to call the 'protocol' (/test/ ? /mywar/ ? etc) and doing deployment at 'any' given time(I believe we can open up for injection of a Deployer to solve this one).

                   

                  Slight orthogonal to this point, I wonder if we could add a remote EJB protocol for invocation of the tests to allow the user to deploy an EJB-JAR only. Right now we are thinking of everything in terms of the servlet protocol.

                   

                  Also, thinking more about the servlet prototol, I wonder if we should make it a REST interface. That would make it easier to probe the test if it's paused in a debugger. It also makes the communication between runner and container cleaner...maybe even make reporting exceptions easier. Then there is also the possibility in the future of a permanently deployed test (obviously through a different mechanism than our primary runner).

                  • 6. Re: Arquillian test lifecycle
                    pmuir

                    To follow up, there is leakage of internals in this design, we went with a better, command orientated design, for altering archives created.

                    • 7. Re: Arquillian test lifecycle
                      pmuir

                      Dan Allen wrote:

                       

                      Also, thinking more about the servlet prototol, I wonder if we should make it a REST interface. That would make it easier to probe the test if it's paused in a debugger. It also makes the communication between runner and container cleaner...maybe even make reporting exceptions easier. Then there is also the possibility in the future of a permanently deployed test (obviously through a different mechanism than our primary runner).

                      Probably a good idea.