test failures on multiple spring test classes

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

test failures on multiple spring test classes

jetlag
I have a maven/spring/hibernate bitronix project connecting to two databases - oracle and db/2.

everything seems to run fine, and my junit test behaves as expected...

until i have 2 junit tests, each pointing to the same context.xml. each test starts with:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:integration-test-context.xml")
@Transactional
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class ServiceImplIntegrationTest {

then i inject the two DAO's (defined in the context) into the test. whichever runs second gets an error that the datasources are already registered with the transaction manager. if i set the uniqueName different for each test i get this:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'btmConfig' defined in URL [file:/d:
/workspaces/crm-dev/domains/redemption/redemption-impl/target/test-classes/META-INF/spring/redemption/service-dao-context.xml]: Error
setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (
1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'serverId' threw exception; nested exception
is java.lang.IllegalStateException: cannot change the configuration while the transaction manager is running


if i keep same uniqueName, i get this:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'IHG:name=serviceContainer/dao/OracleDataSource' defined in URL [file:/d:/workspaces/crm-dev/domains/redemption/redemption-impl/target/test-classes/META-INF/spring/redemption/db-oracle-context.xml]: Invocation of init method failed; nested exception is bitronix.tm.resource.ResourceConfigurationException: cannot create JDBC datasource named odsdb
...
Caused by: java.lang.IllegalArgumentException: resource with uniqueName 'odsdb' has already been registered at bitronix.tm.resource.ResourceRegistrar.register(ResourceRegistrar.java:55) [btm-2.0.1.jar:2.0.1]

i even tried closing out the datasources after each test in @After method. I got the same error as above.



any thoughts?
Reply | Threaded
Open this post in threaded view
|

Re: test failures on multiple spring test classes

snicoll
Hi,

You cannot use two contexts with the Spring integration thing as Spring will load the context in parallel for optimization purposes. This leads BTM, which is supposed to be a singleton, to be created twice (hence the error). Make sure you have a single base class with those annotations and that you don't start a second context where BTM is involved.

HTH,
S.

On Thu, Nov 4, 2010 at 4:40 PM, jetlag <[hidden email]> wrote:

I have a maven/spring/hibernate bitronix project connecting to two databases
- oracle and db/2.

everything seems to run fine, and my junit test behaves as expected...

until i have 2 junit tests, each pointing to the same context.xml. each test
starts with:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:integration-test-context.xml")
@Transactional
@TransactionConfiguration(transactionManager = "transactionManager",
defaultRollback = true)
public class ServiceImplIntegrationTest {

then i inject the two DAO's (defined in the context) into the test.
whichever runs second gets an error that the datasources are already
registered with the transaction manager. if i set the uniqueName different
for each test i get this:

Caused by: org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'btmConfig' defined in URL [file:/d:
/workspaces/crm-dev/domains/redemption/redemption-impl/target/test-classes/META-INF/spring/redemption/service-dao-context.xml]:
Error
setting property values; nested exception is
org.springframework.beans.PropertyBatchUpdateException; nested
PropertyAccessExceptions (
1) are:
PropertyAccessException 1:
org.springframework.beans.MethodInvocationException: Property 'serverId'
threw exception; nested exception
is java.lang.IllegalStateException: cannot change the configuration while
the transaction manager is running


if i keep same uniqueName, i get this:

Caused by: org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'IHG:name=serviceContainer/dao/OracleDataSource'
defined in URL
[file:/d:/workspaces/crm-dev/domains/redemption/redemption-impl/target/test-classes/META-INF/spring/redemption/db-oracle-context.xml]:
Invocation of init method failed; nested exception is
bitronix.tm.resource.ResourceConfigurationException: cannot create JDBC
datasource named odsdb
...
Caused by: java.lang.IllegalArgumentException: resource with uniqueName
'odsdb' has already been registered at
bitronix.tm.resource.ResourceRegistrar.register(ResourceRegistrar.java:55)
[btm-2.0.1.jar:2.0.1]

i even tried closing out the datasources after each test in @After method. I
got the same error as above.



any thoughts?
--
View this message in context: http://old.nabble.com/test-failures-on-multiple-spring-test-classes-tp30133286p30133286.html
Sent from the Bitronix Transaction Manager mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email



Reply | Threaded
Open this post in threaded view
|

Re: test failures on multiple spring test classes

jetlag
I am only using one context per test class and the test classes are instantiated in serial. The spring runner should be clearing the context between tests I would think. The problem is that I cannot predict the order of the tests so dont know which would get called first. They both test bitronix functionality within spring, so they both need to have the transaction manager loaded.

Is the problem mainly that the bitronix classes have a life outside the context they are defined in, but since spring doesnt know about that, it tries to re-config them?

is there anything i can do to shut it all down between tests? i've tried the shutdown method but then the next test says it cant start because the manager is shutting down...

snippets:

dao context:


  <bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices">
    <property name="serverId" value="spring-btm" />
  </bean>


  <bean id="BitronixTransactionManager" factory-method="getTransactionManager"
        class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig" destroy-method="shutdown" />

  <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager" ref="BitronixTransactionManager" />
    <property name="userTransaction" ref="BitronixTransactionManager" />
  </bean>

one of the two datasource contexts:

  <bean name="fmdsDataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init" destroy-method="close">
    <property name="className" value="com.ibm.db2.jcc.DB2XADataSource" />
    <property name="uniqueName" value="${redemption.xa.fmds.uniqueName}" />
    <property name="maxPoolSize" value="${redemption.datasource.pool.maxLimit}" />
    <property name="driverProperties">
      <props>
        <prop key="driverType">4</prop>
        <prop key="serverName">${redemption.db2.servername}</prop>
        <prop key="portNumber">${redemption.db2.port}</prop>
        <prop key="databaseName">${redemption.db2.databasename}</prop>
        <prop key="user">${redemption.db2.user}</prop>
        <prop key="password">${redemption.db2.password}</prop>
      </props>
    </property>
  </bean>




snicoll wrote
Hi,

You cannot use two contexts with the Spring integration thing as Spring will
load the context in parallel for optimization purposes. This leads BTM,
which is supposed to be a singleton, to be created twice (hence the error).
Make sure you have a single base class with those annotations and that you
don't start a second context where BTM is involved.

HTH,
S.

On Thu, Nov 4, 2010 at 4:40 PM, jetlag <matthew.sandoz@ihg.com> wrote:

>
> I have a maven/spring/hibernate bitronix project connecting to two
> databases
> - oracle and db/2.
>
> everything seems to run fine, and my junit test behaves as expected...
>
> until i have 2 junit tests, each pointing to the same context.xml. each
> test
> starts with:
>
> @RunWith(SpringJUnit4ClassRunner.class)
> @ContextConfiguration(locations = "classpath:integration-test-context.xml")
> @Transactional
> @TransactionConfiguration(transactionManager = "transactionManager",
> defaultRollback = true)
> public class ServiceImplIntegrationTest {
>
> then i inject the two DAO's (defined in the context) into the test.
> whichever runs second gets an error that the datasources are already
> registered with the transaction manager. if i set the uniqueName different
> for each test i get this:
>
> Caused by: org.springframework.beans.factory.BeanCreationException: Error
> creating bean with name 'btmConfig' defined in URL [file:/d:
>
> /workspaces/crm-dev/domains/redemption/redemption-impl/target/test-classes/META-INF/spring/redemption/service-dao-context.xml]:
> Error
> setting property values; nested exception is
> org.springframework.beans.PropertyBatchUpdateException; nested
> PropertyAccessExceptions (
> 1) are:
> PropertyAccessException 1:
> org.springframework.beans.MethodInvocationException: Property 'serverId'
> threw exception; nested exception
> is java.lang.IllegalStateException: cannot change the configuration while
> the transaction manager is running
>
>
> if i keep same uniqueName, i get this:
>
> Caused by: org.springframework.beans.factory.BeanCreationException: Error
> creating bean with name 'IHG:name=serviceContainer/dao/OracleDataSource'
> defined in URL
>
> [file:/d:/workspaces/crm-dev/domains/redemption/redemption-impl/target/test-classes/META-INF/spring/redemption/db-oracle-context.xml]:
> Invocation of init method failed; nested exception is
> bitronix.tm.resource.ResourceConfigurationException: cannot create JDBC
> datasource named odsdb
> ...
> Caused by: java.lang.IllegalArgumentException: resource with uniqueName
> 'odsdb' has already been registered at
> bitronix.tm.resource.ResourceRegistrar.register(ResourceRegistrar.java:55)
> [btm-2.0.1.jar:2.0.1]
>
> i even tried closing out the datasources after each test in @After method.
> I
> got the same error as above.
>
>
>
> any thoughts?
> --
> View this message in context:
> http://old.nabble.com/test-failures-on-multiple-spring-test-classes-tp30133286p30133286.html
> Sent from the Bitronix Transaction Manager mailing list archive at
> Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: test failures on multiple spring test classes

Ludovic Orban-2
What the spring runner should be doing is re-initialize the transaction manager before each test and shut it down after each test. What it should also do is re-create the connection pool(s) before each test and close them after each test as well.

This exception:

  java.lang.IllegalStateException: cannot change the configuration while the transaction manager is running

clearly shows that the transaction maanger is NOT being shutdown properly after each test and that exception:

  java.lang.IllegalArgumentException: resource with uniqueName 'odsdb' has already been registered

proves that the connection pool(s) are NOT being closed after each test.


If you tried manually calling BitronixTransactionManager.shutdown() at the end of your test but your next test fails complaining that the transaction manager is busy shutting down this tends to prove that Stephane was right guessing that tests are executed in parallel: the only way to make BTM complain about shutting down is when BitronixTransactionManager.shutdown() has been called and another thread is calling BitronixTransactionManager.begin().

Please also note that BitronixTransactionManager.shutdown() is a blocking call that can last many seconds, the reason being that BTM gives some time to the currently active transactions to terminate before abruptly terminating them. If you have some pending transaction you forgot to commit / rollback this will make the shutdown() method run for 60 seconds by default.


As a summary, either your tests are executing in parallel or BTM's resources aren't being cleaned up between each test.


2010/11/4 jetlag <[hidden email]>

I am only using one context per test class and the test classes are
instantiated in serial. The spring runner should be clearing the context
between tests I would think. The problem is that I cannot predict the order
of the tests so dont know which would get called first. They both test
bitronix functionality within spring, so they both need to have the
transaction manager loaded.

Is the problem mainly that the bitronix classes have a life outside the
context they are defined in, but since spring doesnt know about that, it
tries to re-config them?

is there anything i can do to shut it all down between tests? i've tried the
shutdown method but then the next test says it cant start because the
manager is shutting down...

Reply | Threaded
Open this post in threaded view
|

Re: test failures on multiple spring test classes

jetlag
I got it to work - thanks for your excellent and timely advice. Spring test runner was not shutting down context between tests in the suite. They were running in serial, but the contexts were simultaneously open. If anyone else has this issue, the easiest thing to do until Spring 3.0 where this may be fixed according to some emails I read (I am running 2.5.x) is to do the following:

1.  Make the tests ApplicationContextAware
2. set a static variable = to the context when it comes in on the setter
3. in @AfterClass method, call shutdown on the context

There may be a much more elegant solution but this works. it will not help if the tests are executed in parallel. For parallel tests, it might be better to try moving the BTM out of the context altogether.

Thanks again,

Matthew


Ludovic Orban-2 wrote
What the spring runner should be doing is re-initialize the transaction
manager before each test and shut it down after each test. What it should
also do is re-create the connection pool(s) before each test and close them
after each test as well.

This exception:

  java.lang.IllegalStateException: cannot change the configuration while the
transaction manager is running

clearly shows that the transaction maanger is NOT being shutdown properly
after each test and that exception:

  java.lang.IllegalArgumentException: resource with uniqueName 'odsdb' has
already been registered

proves that the connection pool(s) are NOT being closed after each test.


If you tried manually calling BitronixTransactionManager.shutdown() at the
end of your test but your next test fails complaining that the transaction
manager is busy shutting down this tends to prove that Stephane was right
guessing that tests are executed in parallel: the only way to make BTM
complain about shutting down is when BitronixTransactionManager.shutdown()
has been called and another thread is calling
BitronixTransactionManager.begin().

Please also note that BitronixTransactionManager.shutdown() is a blocking
call that can last many seconds, the reason being that BTM gives some time
to the currently active transactions to terminate before abruptly
terminating them. If you have some pending transaction you forgot to commit
/ rollback this will make the shutdown() method run for 60 seconds by
default.


As a summary, either your tests are executing in parallel or BTM's resources
aren't being cleaned up between each test.


2010/11/4 jetlag <matthew.sandoz@ihg.com>

>
> I am only using one context per test class and the test classes are
> instantiated in serial. The spring runner should be clearing the context
> between tests I would think. The problem is that I cannot predict the order
> of the tests so dont know which would get called first. They both test
> bitronix functionality within spring, so they both need to have the
> transaction manager loaded.
>
> Is the problem mainly that the bitronix classes have a life outside the
> context they are defined in, but since spring doesnt know about that, it
> tries to re-config them?
>
> is there anything i can do to shut it all down between tests? i've tried
> the
> shutdown method but then the next test says it cant start because the
> manager is shutting down...
>
>
Reply | Threaded
Open this post in threaded view
|

Re: test failures on multiple spring test classes

baraber
I'm using spring 3.0.3.RELEASE and I seem to have the same problem.  I wanted to try your work-around, but realized I didn't understand one thing :
How do you shutdown the context ?  I didn't find any "shutdown" method in the ApplicationContext provided with ApplicationContextAware.  Could you explain a little bit more or juste post your snippet ?
jetlag wrote
I got it to work - thanks for your excellent and timely advice. Spring test runner was not shutting down context between tests in the suite. They were running in serial, but the contexts were simultaneously open. If anyone else has this issue, the easiest thing to do until Spring 3.0 where this may be fixed according to some emails I read (I am running 2.5.x) is to do the following:

1.  Make the tests ApplicationContextAware
2. set a static variable = to the context when it comes in on the setter
3. in @AfterClass method, call shutdown on the context

There may be a much more elegant solution but this works. it will not help if the tests are executed in parallel. For parallel tests, it might be better to try moving the BTM out of the context altogether.

Thanks again,

Matthew
Reply | Threaded
Open this post in threaded view
|

Re: test failures on multiple spring test classes

jetlag
You will have to cast it to an AbstractApplicationContext. Then you can shut it down.
baraber wrote
I'm using spring 3.0.3.RELEASE and I seem to have the same problem.  I wanted to try your work-around, but realized I didn't understand one thing :
How do you shutdown the context ?  I didn't find any "shutdown" method in the ApplicationContext provided with ApplicationContextAware.  Could you explain a little bit more or juste post your snippet ?
jetlag wrote
I got it to work - thanks for your excellent and timely advice. Spring test runner was not shutting down context between tests in the suite. They were running in serial, but the contexts were simultaneously open. If anyone else has this issue, the easiest thing to do until Spring 3.0 where this may be fixed according to some emails I read (I am running 2.5.x) is to do the following:

1.  Make the tests ApplicationContextAware
2. set a static variable = to the context when it comes in on the setter
3. in @AfterClass method, call shutdown on the context

There may be a much more elegant solution but this works. it will not help if the tests are executed in parallel. For parallel tests, it might be better to try moving the BTM out of the context altogether.

Thanks again,

Matthew
Reply | Threaded
Open this post in threaded view
|

Re: test failures on multiple spring test classes

baraber
Oh, thank you.  Hope spring will shutdown its context between tests in a futur release.
jetlag wrote
You will have to cast it to an AbstractApplicationContext. Then you can shut it down.
baraber wrote
I'm using spring 3.0.3.RELEASE and I seem to have the same problem.  I wanted to try your work-around, but realized I didn't understand one thing :
How do you shutdown the context ?  I didn't find any "shutdown" method in the ApplicationContext provided with ApplicationContextAware.  Could you explain a little bit more or juste post your snippet ?
jetlag wrote
I got it to work - thanks for your excellent and timely advice. Spring test runner was not shutting down context between tests in the suite. They were running in serial, but the contexts were simultaneously open. If anyone else has this issue, the easiest thing to do until Spring 3.0 where this may be fixed according to some emails I read (I am running 2.5.x) is to do the following:

1.  Make the tests ApplicationContextAware
2. set a static variable = to the context when it comes in on the setter
3. in @AfterClass method, call shutdown on the context

There may be a much more elegant solution but this works. it will not help if the tests are executed in parallel. For parallel tests, it might be better to try moving the BTM out of the context altogether.

Thanks again,

Matthew
Reply | Threaded
Open this post in threaded view
|

Re: test failures on multiple spring test classes

jetlag
i think it would be nice if they just added some annotations to control the general behavior. they do have @DirtiesContext, but i think thats with 3 and im using 2.5.6. also i think its per method.

best would probably be something like:

@Test(testContextSetupStrategy=TestContextSetupStrategy.BEFORE_EACH_TEST, testContextTeardownStrategy=TestContextTeardownStrategy.AFTER_EACH_TEST)

then you could use method level annotations for exceptions to that behaviour if appropriate...

baraber wrote
Oh, thank you.  Hope spring will shutdown its context between tests in a futur release.
Reply | Threaded
Open this post in threaded view
|

Re: test failures on multiple spring test classes

Ludovic Orban-2
In reply to this post by jetlag
#1: Yes, this is by design, both for good and bad reasons I'm not going to enumerate here. Just remember that once the transaction manager started you cannot change its config anymore until shutdown gets called.

#2: Could be Spring's fault or your fault, I can't know for sure without looking at your stuff. The trick here is to ensure Spring properly cleans its context after each test method and also make sure it doesn't run tests in parallel in the same JVM.