Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grails Connections behaving very differently in Integration test

We have a custom data source that extends BasicDataSource. We have overridden the getConnection method which does a couple things inside of it. When we run the webapp outside of testing, when we call a service from a controller it will grab a new connection and use that connection until the service is done. All is well. However, inside an integration test, the connection appears to be grabbed before the test even calls the controller. Flow below

Regular Run: call controller -> controller calls service method -> connection is grabbed -> service method is run and returns to controller

Integration Test: connection is grabbed -> call controller from test -> controller calls service method -> service method is run and returns to controller

Needless to say, this is giving us problems as having the correct connection is very important for our app. Thoughts?

Edit: Still getting significant issues with this. We've reached a point where we have to avoid creating integration tests, or do some manual connection switching (which defeats half the point of the tests)

DataSource.groovy

dataSource {
pooled = true
dialect="org.hibernate.dialect.OracleDialect"
properties {
    maxActive = 50
    maxIdle = 10
    initialSize = 10
    minEvictableIdleTimeMillis = 1800000
    timeBetweenEvictionRunsMillis = 1800000
    maxWait = 10000
    testWhileIdle = true
    numTestsPerEvictionRun = 3
    testOnBorrow = true
}

}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}
like image 336
Joseph Avatar asked Aug 12 '11 12:08

Joseph


1 Answers

This is not a final Answer, however I believe this is an explanation of what is going on:

  • Running as Web app: your Service class has a transactionManager which has a sessionFactory, which gets the connection! So in this case, assuming that you Service is 'transactional=true' all methods that you call in your services will have a 'Session.beginTransaction()' in the beginning of the method(there is a Grails`s Proxy to do that, when you set 'transactional=true'), which will call all that stack until getConnection().

  • Running as Integration Test: as Grails doesnt commit your DB changes, it always rollback them! I believe that when you are starting your Integration test, grails is creating a transaction right away! so it will be able to rollback it afterwards!(which make totally sense right!), you can confirm that taking a look at the class org.codehaus.groovy.grails.test.support.GrailsTestInterceptor. The method init() is called before your services in your integration test. So that`s why getConnection() is being called before everything!

Suggestion: You can try setting your integration test class as 'transaction=false' and see if getConnection() doesn't get call in the beginning! Go to Transactions section in here to see more! Just dont forget that in your test you will have to rollback your transaction! if your set transaction=false.

like image 130
Arthur Neves Avatar answered Nov 08 '22 05:11

Arthur Neves