package org.exist.storage.txn;
import org.easymock.EasyMockSupport;
import org.exist.EXistException;
import org.exist.storage.BrokerPool;
import org.exist.storage.NativeBroker;
import org.exist.storage.SystemTaskManager;
import org.exist.storage.journal.JournalManager;
import org.junit.Test;
import java.util.Optional;
import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertEquals;
/**
* @author Adam Retter <adam.retter@googlemail.com>
*/
public class TxnTest extends EasyMockSupport {
private BrokerPool mockBrokerPool;
private NativeBroker mockBroker;
@Test
public void commitTransaction() throws NoSuchFieldException, IllegalAccessException, EXistException {
final TransactionManager transact = createTestableTransactionManager();
final Txn transaction = transact.beginTransaction();
final CountingTxnListener listener = new CountingTxnListener();
transaction.registerListener(listener);
transaction.commit();
assertEquals(Txn.State.COMMITTED, transaction.getState());
assertEquals(1, listener.getCommit());
assertEquals(0, listener.getAbort());
verify(mockBrokerPool, mockBroker);
}
@Test
public void commitAndCloseTransaction() throws NoSuchFieldException, IllegalAccessException, EXistException {
final TransactionManager transact = createTestableTransactionManager();
final Txn transaction = transact.beginTransaction();
final CountingTxnListener listener = new CountingTxnListener();
transaction.registerListener(listener);
transaction.commit();
transaction.close();
assertEquals(Txn.State.CLOSED, transaction.getState());
assertEquals(1, listener.getCommit());
assertEquals(0, listener.getAbort());
verify(mockBrokerPool, mockBroker);
}
@Test
public void abortTransaction() throws NoSuchFieldException, IllegalAccessException, EXistException {
final TransactionManager transact = createTestableTransactionManager();
final Txn transaction = transact.beginTransaction();
final CountingTxnListener listener = new CountingTxnListener();
transaction.registerListener(listener);
transaction.abort();
assertEquals(Txn.State.ABORTED, transaction.getState());
assertEquals(0, listener.getCommit());
assertEquals(1, listener.getAbort());
verify(mockBrokerPool, mockBroker);
}
@Test
public void abortAndCloseTransaction() throws NoSuchFieldException, IllegalAccessException, EXistException {
final TransactionManager transact = createTestableTransactionManager();
final Txn transaction = transact.beginTransaction();
final CountingTxnListener listener = new CountingTxnListener();
transaction.registerListener(listener);
transaction.abort();
transaction.close();
assertEquals(Txn.State.CLOSED, transaction.getState());
assertEquals(0, listener.getCommit());
assertEquals(1, listener.getAbort());
verify(mockBrokerPool, mockBroker);
}
@Test
public void repeatedAbortOnlyAbortsTransactionOnce() throws NoSuchFieldException, IllegalAccessException, EXistException {
final TransactionManager transact = createTestableTransactionManager();
final Txn transaction = transact.beginTransaction();
final CountingTxnListener listener = new CountingTxnListener();
transaction.registerListener(listener);
//call 3 times, abort count should be one!
transaction.abort();
transaction.abort();
transaction.abort();
assertEquals(Txn.State.ABORTED, transaction.getState());
assertEquals(0, listener.getCommit());
assertEquals(1, listener.getAbort());
verify(mockBrokerPool, mockBroker);
}
@Test
public void closeWithoutCommitAbortsTransaction() throws NoSuchFieldException, IllegalAccessException, EXistException {
final TransactionManager transact = createTestableTransactionManager();
final Txn transaction = transact.beginTransaction();
final CountingTxnListener listener = new CountingTxnListener();
transaction.registerListener(listener);
transaction.close();
assertEquals(Txn.State.CLOSED, transaction.getState());
assertEquals(0, listener.getCommit());
assertEquals(1, listener.getAbort());
verify(mockBrokerPool, mockBroker);
}
@Test
public void repeatedCloseWithoutCommitOnlyAbortsTransactionOnce() throws NoSuchFieldException, IllegalAccessException, EXistException {
final TransactionManager transact = createTestableTransactionManager();
final Txn transaction = transact.beginTransaction();
final CountingTxnListener listener = new CountingTxnListener();
transaction.registerListener(listener);
//call 3 times, abort count should be one!
transaction.close();
transaction.close();
transaction.close();
assertEquals(Txn.State.CLOSED, transaction.getState());
assertEquals(0, listener.getCommit());
assertEquals(1, listener.getAbort());
verify(mockBrokerPool, mockBroker);
}
private class CountingTxnListener implements TxnListener {
private int commit = 0;
private int abort = 0;
@Override
public void commit() {
commit++;
}
@Override
public void abort() {
abort++;
}
public int getCommit() {
return commit;
}
public int getAbort() {
return abort;
}
}
private TransactionManager createTestableTransactionManager() throws NoSuchFieldException, IllegalAccessException, EXistException {
mockBrokerPool = createMock(BrokerPool.class);
mockBroker = createMock(NativeBroker.class);
expect(mockBrokerPool.getBroker()).andReturn(mockBroker).atLeastOnce();
mockBroker.close();
expectLastCall().atLeastOnce();
final JournalManager mockJournalManager = createMock(JournalManager.class);
final SystemTaskManager mockTaskManager = createMock(SystemTaskManager.class);
replay(mockBrokerPool, mockBroker);
return new TransactionManager(mockBrokerPool, Optional.of(mockJournalManager), mockTaskManager);
}
}