5 Replies Latest reply on Dec 10, 2012 11:31 AM by paul.robinson

    Arquillian Transaction Extension

    paul.robinson

      All,

       

      As a member of the JBoss Transactions team, I've spent some time looking at the transaction extension. From what I have seen so far, I can certainly say that it looks interesting! I have a few queries that I'd like to raise here and also propose some areas where we could contribute to the project.

       

      Discussion Points

       

      1. What is the purpose of rollback after the test completes and do you have a specific use-case? I think some people use it to undo any work done by the test, leaving the DB clean ready for the next test. The problem with this approach is that it doesn't provide a real test as it doesn't test the ORM->DB interaction. DB specific things could be done to ensure the DB is interacted with (trigger a flush), but this is specific to the scenario where the RM is a DB. Also, this flush behaviour is probably better placed in the Arquillian Persistence Extension, rather than ATE. We discussed this in more detail, almost a year ago here, and didn't really come up with a satisfactory conclusion.

       

       

      2. How do you revert the test resources after a test, if you instruct it to commit? It can't be done in the @After or @Before as they run in the same TX. If you update a resource in the test and then negate the update in @After, you would leave nothing to commit when the transaction commits. Another problem with this, is that you may need to consume a message, produced by the test, in order to tidy up from the test. This message will not be available until the after the transaction has committed, and thus not available in the @After.

       

      Maybe we need some general support for compensation or setup that happens after or before (respectively) the test in its own transaction? I see you have this support in the persistence extension by way of specifying a yaml file that states what the DB should look like before the test runs (Which, BTW, I assume runs outside of the test's transaction?). This is great for databases, but not for other types of RM.

       

       

      3. It doesn't look like you can combine different transaction types in the same test suite, due to the fact that only one type can be present on the classpath at once. This would be a problem for our TXBridge tests that bridge  a JTA transaction to a WS-AT transaction and visa-versa. Here some tests start a JTA transaction and others start a WSAT transaction. Of course, we would need a WS-AT plugin for ATE for this to be an issue: more about that later.

       

       

      4. I don't think you can assert anything after the transaction has completed. Clearly you can't assert anything in the test method for checking the state after the commit/rollback, but also you can't assert in the @After method (which is probably bad practice anyway?) as it is executed in the same transaction as the test. Maybe we could add an attribute to the @After and @Before to state that it should be executed in either the SAME, NEW, or NONE transaction?

       

      However, I do wonder whether application developers need to assert anything after the test's transaction has committed? As a transactions middleware developer, I would need that facility because I am testing the Transaction Service. Application developers can assume the transaction service works, so don't need to assert after commit/rollback? WDYT?

       

       

      5. A test can only run 1 transaction. We have some tests that run two transactions. Again this could  possibly only be an issue to transaction middleware developers, rather than the vast majority of the target audience.

       

       

      6. When implementing a transaction extension you have an @TransactionScoped injection which seems to be used to squirrel away the UserTransaction and have the right one made available during the lifecycle of the test. Can someone explain how the lifecycle of the @TransactionScoped variable is managed by ATE? Is it tied to the transaction lifecycle? If so, I can't see how this is managed as ATE doesn't know anything of the actual transaction type (JTA/Spring/WS-AT etc). Maybe I have the wrong end of the stick here?

       

       

      Contribution

      As I mentioned earlier I'd be happy to contribute some developer time to this project. In particular we were thinking that an XTS transaction type (WS-AT and WS-BA) implementation could be useful for our users. I assume this impl would live in the JBossTS project?

       

      Also, we noticed that you don't yet have a quickstart for the project. I can contribute one of these if you'd like?

       

      I'll also continue to review this project and come back with any feedback/new-features etc.

       

      Cheers,

       

      Paul.

        • 1. Re: Arquillian Transaction Extension
          aslak

          Paul Robinson wrote:

           

          1. What is the purpose of rollback after the test completes and do you have a specific use-case? I think some people use it to undo any work done by the test, leaving the DB clean ready for the next test. The problem with this approach is that it doesn't provide a real test as it doesn't test the ORM->DB interaction. DB specific things could be done to ensure the DB is interacted with (trigger a flush), but this is specific to the scenario where the RM is a DB. Also, this flush behaviour is probably better placed in the Arquillian Persistence Extension, rather than ATE. We discussed this in more detail, almost a year ago here, and didn't really come up with a satisfactory conclusion.

           

          Yea, this has been discussed many times. The main reason why it's there is because that's what Spring Testing does. It's an illusion of a test, but you can test some of the applicaiton logic that use something that use a transactional resource manager, even tho it never actually goes all the way. And yea, a Flush option in APE to force the datasource interaction would be a nice feature (probably only required when transaction is set to rollback).

           

           

          2. How do you revert the test resources after a test, if you instruct it to commit? It can't be done in the @After or @Before as they run in the same TX. If you update a resource in the test and then negate the update in @After, you would leave nothing to commit when the transaction commits. Another problem with this, is that you may need to consume a message, produced by the test, in order to tidy up from the test. This message will not be available until the after the transaction has committed, and thus not available in the @After.

           

          Maybe we need some general support for compensation or setup that happens after or before (respectively) the test in its own transaction? I see you have this support in the persistence extension by way of specifying a yaml file that states what the DB should look like before the test runs (Which, BTW, I assume runs outside of the test's transaction?). This is great for databases, but not for other types of RM.

          Good point. In APE this is handled seperatly via it's CleanUp strategies.

           

          I'm not sure if any Tests/Examples actually use the same transaction as Test in Before/After at this point, maybe just moving it down to only around Test will do. With a option to set @Transactional on Before/After if needed, but that would be a separate transaction unless requested/linked somehow in API?

           

          Maybe a similar concept as UsingDataSet/ShouldMatchData set would fit for JMS as well. Prepare a queue with data, make sure the state after is same as expected.

           

           

           

          3. It doesn't look like you can combine different transaction types in the same test suite, due to the fact that only one type can be present on the classpath at once. This would be a problem for our TXBridge tests that bridge  a JTA transaction to a WS-AT transaction and visa-versa. Here some tests start a JTA transaction and others start a WSAT transaction. Of course, we would need a WS-AT plugin for ATE for this to be an issue: more about that later.

          Currently only one manager pr Test, and only one Provider pr Suite.

           

          One option would be to allow multiple @Transactional(manager="") annotations on a Test method, or possible introduce a programmable TransactionManager API as well.

           

          @ArquillianResource
          TransactionManager tm;
          
          
          tm.begin("JTA", "manager");
          tm.begin("WS-AT", "manager");
          ..
          
          

           

           

          4. I don't think you can assert anything after the transaction has completed. Clearly you can't assert anything in the test method for checking the state after the commit/rollback, but also you can't assert in the @After method (which is probably bad practice anyway?) as it is executed in the same transaction as the test. Maybe we could add an attribute to the @After and @Before to state that it should be executed in either the SAME, NEW, or NONE transaction?

           

          However, I do wonder whether application developers need to assert anything after the test's transaction has committed? As a transactions middleware developer, I would need that facility because I am testing the Transaction Service. Application developers can assume the transaction service works, so don't need to assert after commit/rollback? WDYT?

          See 2

           

           

          5. A test can only run 1 transaction. We have some tests that run two transactions. Again this could  possibly only be an issue to transaction middleware developers, rather than the vast majority of the target audience.

          See 3

           

          6. When implementing a transaction extension you have an @TransactionScoped injection which seems to be used to squirrel away the UserTransaction and have the right one made available during the lifecycle of the test. Can someone explain how the lifecycle of the @TransactionScoped variable is managed by ATE? Is it tied to the transaction lifecycle? If so, I can't see how this is managed as ATE doesn't know anything of the actual transaction type (JTA/Spring/WS-AT etc). Maybe I have the wrong end of the stick here?

          @TransactionalScope is a internal Arquillian Scope to act as a shared object store for things related to the current Transaction. Currently spans from Before to After. Not directly related to the actual Transaction in any way, just the lifespan of the Transaction Extension.

           

           

          Contribution

          As I mentioned earlier I'd be happy to contribute some developer time to this project. In particular we were thinking that an XTS transaction type (WS-AT and WS-BA) implementation could be useful for our users. I assume this impl would live in the JBossTS project?

           

          Also, we noticed that you don't yet have a quickstart for the project. I can contribute one of these if you'd like?

           

          I'll also continue to review this project and come back with any feedback/new-features etc.

          This is excellent news!

           

          I assume WS-AT and WS-BA is fairly tied to a specific TM impl with no User facing API/SPI alla UserTransaction? If so they probably should live in JBossTS project. If there is a API that makes sense to reuse on ATE level, there could be an abstract WS impl in ATE and WS-ATE TM specific impls provided by JBossTS.

          • 2. Re: Arquillian Transaction Extension
            paul.robinson

            Aslak,

             

            Thanks for the input. It looks like we've now got a few threads of discussion to explore. I'll start a separate discussion for each...

            Aslak Knutsen wrote:

             

            Paul Robinson wrote:

             

            1. What is the purpose of rollback after the test completes and do you have a specific use-case? I think some people use it to undo any work done by the test, leaving the DB clean ready for the next test. The problem with this approach is that it doesn't provide a real test as it doesn't test the ORM->DB interaction. DB specific things could be done to ensure the DB is interacted with (trigger a flush), but this is specific to the scenario where the RM is a DB. Also, this flush behaviour is probably better placed in the Arquillian Persistence Extension, rather than ATE. We discussed this in more detail, almost a year ago here, and didn't really come up with a satisfactory conclusion.

             

            Yea, this has been discussed many times. The main reason why it's there is because that's what Spring Testing does. It's an illusion of a test, but you can test some of the applicaiton logic that use something that use a transactional resource manager, even tho it never actually goes all the way. And yea, a Flush option in APE to force the datasource interaction would be a nice feature (probably only required when transaction is set to rollback).

             

            Ok, that makes sense. It fits a use-case that some people have, but doesn't necessarily fit into our philosophy of "write real tests". Which is fine as we should provide features that users want, not just what we think they should have.

             

            If we want to discuss this further we can continue the existing thread: https://community.jboss.org/thread/176884

             

             

            Aslak Knutsen wrote:

            2. How do you revert the test resources after a test, if you instruct it to commit? It can't be done in the @After or @Before as they run in the same TX. If you update a resource in the test and then negate the update in @After, you would leave nothing to commit when the transaction commits. Another problem with this, is that you may need to consume a message, produced by the test, in order to tidy up from the test. This message will not be available until the after the transaction has committed, and thus not available in the @After.

             

            Maybe we need some general support for compensation or setup that happens after or before (respectively) the test in its own transaction? I see you have this support in the persistence extension by way of specifying a yaml file that states what the DB should look like before the test runs (Which, BTW, I assume runs outside of the test's transaction?). This is great for databases, but not for other types of RM.

            Good point. In APE this is handled seperatly via it's CleanUp strategies.

             

            I'm not sure if any Tests/Examples actually use the same transaction as Test in Before/After at this point, maybe just moving it down to only around Test will do. With a option to set @Transactional on Before/After if needed, but that would be a separate transaction unless requested/linked somehow in API?

             

            Maybe a similar concept as UsingDataSet/ShouldMatchData set would fit for JMS as well. Prepare a queue with data, make sure the state after is same as expected.

             

            I've pulled this out into: https://community.jboss.org/thread/213736 & https://community.jboss.org/thread/213734

             

             

             

            3. It doesn't look like you can combine different transaction types in the same test suite, due to the fact that only one type can be present on the classpath at once. This would be a problem for our TXBridge tests that bridge  a JTA transaction to a WS-AT transaction and visa-versa. Here some tests start a JTA transaction and others start a WSAT transaction. Of course, we would need a WS-AT plugin for ATE for this to be an issue: more about that later.

            Currently only one manager pr Test, and only one Provider pr Suite.

             

            One option would be to allow multiple @Transactional(manager="") annotations on a Test method, or possible introduce a programmable TransactionManager API as well.

             

            @ArquillianResource
            TransactionManager tm;
             
             
            tm.begin("JTA", "manager");
            tm.begin("WS-AT", "manager");
            ..
             
            

             

            I've pulled this out into: https://community.jboss.org/thread/213742

             

             

             

            Contribution

            As I mentioned earlier I'd be happy to contribute some developer time to this project. In particular we were thinking that an XTS transaction type (WS-AT and WS-BA) implementation could be useful for our users. I assume this impl would live in the JBossTS project?

             

            Also, we noticed that you don't yet have a quickstart for the project. I can contribute one of these if you'd like?

             

            I'll also continue to review this project and come back with any feedback/new-features etc.

            This is excellent news!

             

            I assume WS-AT and WS-BA is fairly tied to a specific TM impl with no User facing API/SPI alla UserTransaction? If so they probably should live in JBossTS project. If there is a API that makes sense to reuse on ATE level, there could be an abstract WS impl in ATE and WS-ATE TM specific impls provided by JBossTS.

             

            Yes, there are no standardized API/SPI for WS-TX so the provider will be very JBossTS specific. I'll add it to our project. I have a prototype now, but it doesn't work. I'm having a problem defining dependencies. I'll bring that up in a separate discussion on the user forum.

             

            Can you give me a pointer to where the ATE with JTA quickstart would live? Also, a pointer to any examples/guidelines would be good so that I can make it consistent. I'll start a discussion with a proposal of what the quickstart will actually demonstrate and what example scenario will be used. Hopefully I'll then have some time in December to work on this.

             

            Paul.

            • 3. Re: Arquillian Transaction Extension
              aslak

              Thanks for splitting this up.

               

              Can you give me a pointer to where the ATE with JTA quickstart would live? Also, a pointer to any examples/guidelines would be good so that I can make it consistent. I'll start a discussion with a proposal of what the quickstart will actually demonstrate and what example scenario will be used. Hopefully I'll then have some time in December to work on this.

               

              Paul.

              If we start with a quick example we can use the showcase repository: https://github.com/arquillian/arquillian-showcase

               

              Use the README.md file to describe the example.

               

              We'll have a web view of this on arquillian.org when I find some time to finish it up. Current version can be seen in staging: https://staging-arquillian.rhcloud.com/showcase/

               

              As it evolves we can convert it into a full Guide: http://arquillian.org/guides/

              • 4. Re: Arquillian Transaction Extension
                aslak
                • 5. Re: Arquillian Transaction Extension
                  paul.robinson

                  Aslak,

                   

                  I've been thinking about the usecase for the simple ATE Quickstart.

                   

                  Requirements:

                   

                  1) Needs to have a sensible+practical use-case. We could simply test that a JTA transaction is active during the test run, but I think this would be too artificial.

                  2) It shouldn't showcase something that would be better done with APE. Therefore anything JPA related is out.

                   

                  Ideas:

                   

                  The only ideas I can come up with at present are:

                   

                  JMS

                  The test adds a message to a queue and the @After removes any existing messages. The problems with this are:

                   

                  1) We need an update to ATE to ensure that @After runs in a different TX to @Test (See: https://community.jboss.org/thread/213734)

                  2) We can't assert that the message was added in the queue as it would advocate assertions in @After.

                  3) We can't receive the message in @Test as it won't be available until the TX has committed.

                  4) How sensible+practical is it to have a test that just sends a message?

                  5) It will only run (easily) in a container that has a JMS provider already deployed.

                   

                  Non JPA DB

                  As APE is JPA only (I believe), some users may want to have similar support from other DS with XA datasources. For example a NoSQL datastore. We could create some data in the @Test and revert the DB in @After. This suffers from similar problems to the JMS idea, though.

                   

                  Did you, or anyone else, have any particular ideas?

                   

                  Paul.