package bitronix.tm.integration.spring;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
import java.sql.SQLException;
import java.util.Iterator;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import bitronix.tm.mock.events.ConnectionCloseEvent;
import bitronix.tm.mock.events.EventRecorder;
import bitronix.tm.mock.events.XAConnectionCloseEvent;
import bitronix.tm.resource.ResourceRegistrar;
import bitronix.tm.resource.jdbc.PoolingDataSource;
public class LifecycleTest {
private static final Logger log = LoggerFactory.getLogger(LifecycleTest.class);
private static final String DS_UNIQUE_NAME = "btm-spring-test-ds1";
@Before @After
public void clearEvents() {
EventRecorder.clear();
}
@Test
public void testLifecycle() throws SQLException {
ClassPathXmlApplicationContext applicationContext = null;
try {
applicationContext = new ClassPathXmlApplicationContext("test-context.xml");
// run a transactional bean method, making sure the minimum pool size (of 1) is exceeded
verifyTransactionalMethod(applicationContext, 2);
EventRecorder.clear();
// make sure that a refresh closes all connections
int totalPoolSize = getTotalPoolSize(applicationContext);
assertEquals(3, totalPoolSize);
applicationContext.refresh();
verifyConnectionsClosed(totalPoolSize);
// run the transactional bean method again after refresh
EventRecorder.clear();
verifyTransactionalMethod(applicationContext, 1);
}
finally {
if (applicationContext != null) {
applicationContext.close();
}
}
assertNull(ResourceRegistrar.get(DS_UNIQUE_NAME));
}
private int getTotalPoolSize(ApplicationContext applicationContext) {
int totalPoolSize = 0;
for (PoolingDataSource ds : applicationContext.getBeansOfType(PoolingDataSource.class).values()) {
totalPoolSize += ds.getTotalPoolSize();
}
return totalPoolSize;
}
private void verifyConnectionsClosed(int totalPoolSize) {
if (log.isDebugEnabled()) {
log.debug(EventRecorder.dumpToString());
}
Iterator<?> it = EventRecorder.iterateEvents();
for (int i = 0; i < totalPoolSize; i++) {
assertEquals(ConnectionCloseEvent.class, it.next().getClass());
assertEquals(XAConnectionCloseEvent.class, it.next().getClass());
}
assertFalse(it.hasNext());
}
private void verifyTransactionalMethod(ApplicationContext applicationContext, int count) throws SQLException {
assertNotNull(ResourceRegistrar.get(DS_UNIQUE_NAME));
TransactionalBean bean = applicationContext.getBean(TransactionalBean.class);
bean.doSomethingTransactional(count);
bean.verifyEvents(count);
}
}