/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */
package org.apache.qpid.server.txn;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.qpid.server.message.MessageInstance;
import org.apache.qpid.server.message.ServerMessage;
import org.apache.qpid.server.queue.BaseQueue;
import org.apache.qpid.server.queue.MockMessageInstance;
import org.apache.qpid.server.store.MessageDurability;
import org.apache.qpid.server.store.MessageEnqueueRecord;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.TransactionLogResource;
import org.apache.qpid.server.txn.MockStoreTransaction.TransactionState;
import org.apache.qpid.test.utils.QpidTestCase;

/**
 * A unit test ensuring that LocalTransactionTest creates a long-lived store transaction
 * that spans many dequeue/enqueue operations of enlistable messages.  Verifies
 * that the long-lived transaction is properly committed and rolled back, and that
 * post transaction actions are correctly fired.
 *
 */
public class LocalTransactionTest extends QpidTestCase
{
    private ServerTransaction _transaction = null;  // Class under test
    
    private BaseQueue _queue;
    private List<BaseQueue> _queues;
    private Collection<MessageInstance> _queueEntries;
    private ServerMessage _message;
    private MockAction _action1;
    private MockAction _action2;
    private MockStoreTransaction _storeTransaction;
    private MessageStore _transactionLog;


    @Override
    protected void setUp() throws Exception
    {
        super.setUp();
        
        _storeTransaction = createTestStoreTransaction(false);
        _transactionLog = MockStoreTransaction.createTestTransactionLog(_storeTransaction);
        _action1 = new MockAction();
        _action2 = new MockAction();
        
        _transaction = new LocalTransaction(_transactionLog);
        
    }


    /**
     * Tests the enqueue of a non persistent message to a single non durable queue.
     * Asserts that a store transaction has not been started.
     */
    public void testEnqueueToNonDurableQueueOfNonPersistentMessage() throws Exception
    {
        _message = createTestMessage(false);
        _queue = createQueue(false);
        
        _transaction.enqueue(_queue, _message, _action1);

        assertEquals("Enqueue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
        assertNotFired(_action1);
    }

    /**
     * Tests the enqueue of a persistent message to a durable queue.
     * Asserts that a store transaction has been started.
     */
    public void testEnqueueToDurableQueueOfPersistentMessage() throws Exception
    {
        _message = createTestMessage(true);
        _queue = createQueue(true);
        
        _transaction.enqueue(_queue, _message, _action1);

        assertEquals("Enqueue of persistent message to durable queue must cause message to be enqueued", 1, _storeTransaction.getNumberOfEnqueuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.STARTED, _storeTransaction.getState());
        assertNotFired(_action1);
    }

    /**
     * Tests the case where the store operation throws an exception.
     * Asserts that the transaction is aborted.
     */
    public void testStoreEnqueueCausesException() throws Exception
    {
        _message = createTestMessage(true);
        _queue = createQueue(true);
        
        _storeTransaction = createTestStoreTransaction(true);
        _transactionLog = MockStoreTransaction.createTestTransactionLog(_storeTransaction);
        _transaction = new LocalTransaction(_transactionLog);
        
        try
        {
            _transaction.enqueue(_queue, _message, _action1);
            fail("Exception not thrown");
        }
        catch (RuntimeException re)
        {
            // PASS
        } 

        assertTrue("Rollback action must be fired", _action1.isRollbackActionFired());
        assertEquals("Unexpected transaction state", TransactionState.ABORTED, _storeTransaction.getState());
        
        assertFalse("Post commit action must not be fired", _action1.isPostCommitActionFired());
        
    }
    
    /**
     * Tests the enqueue of a non persistent message to a many non durable queues.
     * Asserts that a store transaction has not been started.
     */
    public void testEnqueueToManyNonDurableQueuesOfNonPersistentMessage() throws Exception
    {
        _message = createTestMessage(false);
        _queues = createTestBaseQueues(new boolean[] {false, false, false});
        
        _transaction.enqueue(_queues, _message, _action1);

        assertEquals("Enqueue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
        assertNotFired(_action1);
    }
    
    /**
     * Tests the enqueue of a persistent message to a many non durable queues.
     * Asserts that a store transaction has not been started.
     */
    public void testEnqueueToManyNonDurableQueuesOfPersistentMessage() throws Exception
    {
        _message = createTestMessage(true);
        _queues = createTestBaseQueues(new boolean[] {false, false, false});
        
        _transaction.enqueue(_queues, _message, _action1);
  
        assertEquals("Enqueue of persistent message to non-durable queues must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
        assertNotFired(_action1);

    }

    /**
     * Tests the enqueue of a persistent message to many queues, some durable others not.
     * Asserts that a store transaction has been started.
     */
    public void testEnqueueToDurableAndNonDurableQueuesOfPersistentMessage() throws Exception
    {
        _message = createTestMessage(true);
        _queues = createTestBaseQueues(new boolean[] {false, true, false, true});
        
        _transaction.enqueue(_queues, _message, _action1);

        assertEquals("Enqueue of persistent message to durable/non-durable queues must cause messages to be enqueued", 2, _storeTransaction.getNumberOfEnqueuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.STARTED, _storeTransaction.getState());
        assertNotFired(_action1);

    }

    /**
     * Tests the case where the store operation throws an exception.
     * Asserts that the transaction is aborted.
     */
    public void testStoreEnqueuesCausesExceptions() throws Exception
    {
        _message = createTestMessage(true);
        _queues = createTestBaseQueues(new boolean[] {true, true});
        
        _storeTransaction = createTestStoreTransaction(true);
        _transactionLog = MockStoreTransaction.createTestTransactionLog(_storeTransaction);
        _transaction = new LocalTransaction(_transactionLog);
        
        try
        {
            _transaction.enqueue(_queues, _message, _action1);
            fail("Exception not thrown");
        }
        catch (RuntimeException re)
        {
            // PASS
        }

        assertTrue("Rollback action must be fired", _action1.isRollbackActionFired());
        assertEquals("Unexpected transaction state", TransactionState.ABORTED, _storeTransaction.getState());
        assertFalse("Post commit action must not be fired", _action1.isPostCommitActionFired());
    }

    /**
     * Tests the dequeue of a non persistent message from a single non durable queue.
     * Asserts that a store transaction has not been started.
     */
    public void testDequeueFromNonDurableQueueOfNonPersistentMessage() throws Exception
    {
        _message = createTestMessage(false);
        _queue = createQueue(false);

        _transaction.dequeue((MessageEnqueueRecord)null, _action1);

        assertEquals("Dequeue of non-persistent message must not cause message to be enqueued", 0, _storeTransaction.getNumberOfEnqueuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
        assertNotFired(_action1);

    }

    /**
     * Tests the dequeue of a persistent message from a single non durable queue.
     * Asserts that a store transaction has not been started.
     */
    public void testDequeueFromDurableQueueOfPersistentMessage() throws Exception
    {
        _message = createTestMessage(true);
        _queue = createQueue(true);
        
        _transaction.dequeue(mock(MessageEnqueueRecord.class), _action1);

        assertEquals("Dequeue of non-persistent message must cause message to be dequeued", 1, _storeTransaction.getNumberOfDequeuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.STARTED, _storeTransaction.getState());
        assertNotFired(_action1);
    }

    /**
     * Tests the case where the store operation throws an exception.
     * Asserts that the transaction is aborted.
     */
    public void testStoreDequeueCausesException() throws Exception
    {
        _message = createTestMessage(true);
        _queue = createQueue(true);
        
        _storeTransaction = createTestStoreTransaction(true);
        _transactionLog = MockStoreTransaction.createTestTransactionLog(_storeTransaction);
        _transaction = new LocalTransaction(_transactionLog);
        
        try
        {
            _transaction.dequeue(mock(MessageEnqueueRecord.class), _action1);
            fail("Exception not thrown");
        }
        catch (RuntimeException re)
        {
            // PASS
        }        
        
        assertTrue("Rollback action must be fired", _action1.isRollbackActionFired());
        assertEquals("Unexpected transaction state", TransactionState.ABORTED, _storeTransaction.getState());
        assertFalse("Post commit action must not be fired", _action1.isPostCommitActionFired());

    }

    /**
     * Tests the dequeue of a non persistent message from many non durable queues.
     * Asserts that a store transaction has not been started.
     */
    public void testDequeueFromManyNonDurableQueuesOfNonPersistentMessage() throws Exception
    {
        _queueEntries = createTestQueueEntries(new boolean[] {false, false, false}, new boolean[] {false, false, false});
        
        _transaction.dequeue(_queueEntries, _action1);

        assertEquals("Dequeue of non-persistent messages must not cause message to be dequeued", 0, _storeTransaction.getNumberOfDequeuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
        assertNotFired(_action1);
  
    }
    
    /**
     * Tests the dequeue of a persistent message from a many non durable queues.
     * Asserts that a store transaction has not been started.
     */
    public void testDequeueFromManyNonDurableQueuesOfPersistentMessage() throws Exception
    {
        _queueEntries = createTestQueueEntries(new boolean[] {false, false, false}, new boolean[] {true, true, true});
        
        _transaction.dequeue(_queueEntries, _action1);

        assertEquals("Dequeue of persistent message from non-durable queues must not cause message to be enqueued", 0, _storeTransaction.getNumberOfDequeuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
        assertNotFired(_action1);
    }

    /**
     * Tests the dequeue of a persistent message from many queues, some durable others not.
     * Asserts that a store transaction has not been started.
     */
    public void testDequeueFromDurableAndNonDurableQueuesOfPersistentMessage() throws Exception
    {
        // A transaction will exist owing to the 1st and 3rd.
        _queueEntries = createTestQueueEntries(new boolean[] {true, false, true, true}, new boolean[] {true, true, true, false});
        
        _transaction.dequeue(_queueEntries, _action1);

        assertEquals("Dequeue of persistent messages from durable/non-durable queues must cause messages to be dequeued", 2, _storeTransaction.getNumberOfDequeuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.STARTED, _storeTransaction.getState());
        assertNotFired(_action1);
    }
    
    /**
     * Tests the case where the store operation throws an exception.
     * Asserts that the transaction is aborted.
     */
    public void testStoreDequeuesCauseExceptions() throws Exception
    {
        // Transactions will exist owing to the 1st and 3rd queue entries in the collection
        _queueEntries = createTestQueueEntries(new boolean[] {true}, new boolean[] {true});
        
        _storeTransaction = createTestStoreTransaction(true);
        _transactionLog = MockStoreTransaction.createTestTransactionLog(_storeTransaction);
        _transaction = new LocalTransaction(_transactionLog);
        
        try
        {
            _transaction.dequeue(_queueEntries, _action1);
            fail("Exception not thrown");
        }
        catch (RuntimeException re)
        {
            // PASS
        }

        assertEquals("Unexpected transaction state", TransactionState.ABORTED, _storeTransaction.getState());
        assertTrue("Rollback action must be fired", _action1.isRollbackActionFired());
        assertFalse("Post commit action must not be fired",  _action1.isPostCommitActionFired());
    }
    
    /** 
     * Tests the add of a post-commit action.  Unlike AutoCommitTransactions, the post transaction actions
     * is added to a list to be fired on commit or rollback.
     */
    public void testAddingPostCommitActionNotFiredImmediately() throws Exception
    {
        
        _transaction.addPostTransactionAction(_action1);

        assertNotFired(_action1);
    }
    
    
    /**
     * Tests committing a transaction without work accepted without error and without causing store
     * enqueues or dequeues.
     */
    public void testCommitNoWork() throws Exception
    {
        
        _transaction.commit();
        
        assertEquals("Unexpected number of store dequeues", 0, _storeTransaction.getNumberOfDequeuedMessages());
        assertEquals("Unexpected number of store enqueues", 0, _storeTransaction.getNumberOfEnqueuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
    }
    
    /**
     * Tests rolling back a transaction without work accepted without error and without causing store
     * enqueues or dequeues.
     */
    public void testRollbackNoWork() throws Exception
    {
        
        _transaction.rollback();

        assertEquals("Unexpected number of store dequeues", 0, _storeTransaction.getNumberOfDequeuedMessages());
        assertEquals("Unexpected number of store enqueues", 0, _storeTransaction.getNumberOfEnqueuedMessages());
        assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
    }
    
    /** 
     * Tests the dequeuing of a message with a commit.  Test ensures that the underlying store transaction is 
     * correctly controlled and the post commit action is fired.
     */
    public void testCommitWork() throws Exception
    {
        
        _message = createTestMessage(true);
        _queue = createQueue(true);

        assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
        assertFalse("Post commit action must not be fired yet", _action1.isPostCommitActionFired());
        
        _transaction.dequeue(mock(MessageEnqueueRecord.class), _action1);
        assertEquals("Unexpected transaction state", TransactionState.STARTED, _storeTransaction.getState());
        assertFalse("Post commit action must not be fired yet", _action1.isPostCommitActionFired());
        
        _transaction.commit();
        
        assertEquals("Unexpected transaction state", TransactionState.COMMITTED, _storeTransaction.getState());
        assertTrue("Post commit action must be fired", _action1.isPostCommitActionFired());
    }
    
    /** 
     * Tests the dequeuing of a message with a rollback.  Test ensures that the underlying store transaction is 
     * correctly controlled and the post rollback action is fired.
     */
    public void testRollbackWork() throws Exception
    {
        
        _message = createTestMessage(true);
        _queue = createQueue(true);


        assertEquals("Unexpected transaction state", TransactionState.NOT_STARTED, _storeTransaction.getState());
        assertFalse("Rollback action must not be fired yet", _action1.isRollbackActionFired());

        _transaction.dequeue(mock(MessageEnqueueRecord.class), _action1);
        
        assertEquals("Unexpected transaction state", TransactionState.STARTED, _storeTransaction.getState());
        assertFalse("Rollback action must not be fired yet", _action1.isRollbackActionFired());

        _transaction.rollback();
        
        assertEquals("Unexpected transaction state", TransactionState.ABORTED, _storeTransaction.getState());
        assertTrue("Rollback action must be fired", _action1.isRollbackActionFired());

    }
    
    /**
     * Variation of testCommitWork with an additional post transaction action.
     * 
     */
    public void testCommitWorkWithAdditionalPostAction() throws Exception
    {
        
        _message = createTestMessage(true);
        _queue = createQueue(true);
        
        _transaction.addPostTransactionAction(_action1);
        _transaction.dequeue(mock(MessageEnqueueRecord.class), _action2);
        _transaction.commit();
        
        assertEquals("Unexpected transaction state", TransactionState.COMMITTED, _storeTransaction.getState());

        assertTrue("Post commit action1 must be fired", _action1.isPostCommitActionFired());
        assertTrue("Post commit action2 must be fired", _action2.isPostCommitActionFired());
        
        assertFalse("Rollback action1 must not be fired", _action1.isRollbackActionFired());
        assertFalse("Rollback action2 must not be fired", _action1.isRollbackActionFired());
    }

    /**
     * Variation of testRollbackWork with an additional post transaction action.
     * 
     */
    public void testRollbackWorkWithAdditionalPostAction() throws Exception
    {
        _message = createTestMessage(true);
        _queue = createQueue(true);
        
        _transaction.addPostTransactionAction(_action1);
        _transaction.dequeue(mock(MessageEnqueueRecord.class), _action2);
        _transaction.rollback();
        
        assertEquals("Unexpected transaction state", TransactionState.ABORTED, _storeTransaction.getState());

        assertFalse("Post commit action1 must not be fired", _action1.isPostCommitActionFired());
        assertFalse("Post commit action2 must not be fired", _action2.isPostCommitActionFired());
        
        assertTrue("Rollback action1 must be fired", _action1.isRollbackActionFired());
        assertTrue("Rollback action2 must be fired", _action1.isRollbackActionFired());
    }

    public void testFirstEnqueueRecordsTransactionStartAndUpdateTime() throws Exception
    {
        assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
        assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());

        _message = createTestMessage(true);
        _queue = createQueue(true);

        long startTime = System.currentTimeMillis();
        _transaction.enqueue(_queue, _message, _action1);

        assertTrue("Transaction start time should have been recorded", _transaction.getTransactionStartTime() >= startTime);
        assertEquals("Transaction update time should be the same as transaction start time", _transaction.getTransactionStartTime(), _transaction.getTransactionUpdateTime());
    }

    public void testSubsequentEnqueueAdvancesTransactionUpdateTimeOnly() throws Exception
    {
        assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
        assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());

        _message = createTestMessage(true);
        _queue = createQueue(true);

        _transaction.enqueue(_queue, _message, _action1);

        final long transactionStartTimeAfterFirstEnqueue = _transaction.getTransactionStartTime();
        final long transactionUpdateTimeAfterFirstEnqueue = _transaction.getTransactionUpdateTime();

        Thread.sleep(1);
        _transaction.enqueue(_queue, _message, _action2);

        final long transactionStartTimeAfterSecondEnqueue = _transaction.getTransactionStartTime();
        final long transactionUpdateTimeAfterSecondEnqueue = _transaction.getTransactionUpdateTime();

        assertEquals("Transaction start time after second enqueue should be unchanged", transactionStartTimeAfterFirstEnqueue, transactionStartTimeAfterSecondEnqueue);
        assertTrue("Transaction update time after second enqueue should be greater than first update time", transactionUpdateTimeAfterSecondEnqueue > transactionUpdateTimeAfterFirstEnqueue);
    }

    public void testFirstDequeueRecordsTransactionStartAndUpdateTime() throws Exception
    {
        assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
        assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());

        _message = createTestMessage(true);
        _queue = createQueue(true);

        long startTime = System.currentTimeMillis();
        _transaction.dequeue(mock(MessageEnqueueRecord.class), _action1);

        assertTrue("Transaction start time should have been recorded", _transaction.getTransactionStartTime() >= startTime);
        assertEquals("Transaction update time should be the same as transaction start time", _transaction.getTransactionStartTime(), _transaction.getTransactionUpdateTime());
    }

    public void testMixedEnqueuesAndDequeuesAdvancesTransactionUpdateTimeOnly() throws Exception
    {
        assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
        assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());

        _message = createTestMessage(true);
        _queue = createQueue(true);

        _transaction.enqueue(_queue, _message, _action1);

        final long transactionStartTimeAfterFirstEnqueue = _transaction.getTransactionStartTime();
        final long transactionUpdateTimeAfterFirstEnqueue = _transaction.getTransactionUpdateTime();

        Thread.sleep(1);
        _transaction.dequeue(mock(MessageEnqueueRecord.class), _action2);

        final long transactionStartTimeAfterFirstDequeue = _transaction.getTransactionStartTime();
        final long transactionUpdateTimeAfterFirstDequeue = _transaction.getTransactionUpdateTime();

        assertEquals("Transaction start time after first dequeue should be unchanged", transactionStartTimeAfterFirstEnqueue, transactionStartTimeAfterFirstDequeue);
        assertTrue("Transaction update time after first dequeue should be greater than first update time", transactionUpdateTimeAfterFirstDequeue > transactionUpdateTimeAfterFirstEnqueue);
    }

    public void testCommitResetsTransactionStartAndUpdateTime() throws Exception
    {
        assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
        assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());

        _message = createTestMessage(true);
        _queue = createQueue(true);

        long startTime = System.currentTimeMillis();
        _transaction.enqueue(_queue, _message, _action1);

        assertTrue(_transaction.getTransactionStartTime() >= startTime);
        assertTrue(_transaction.getTransactionUpdateTime() >= startTime);

        _transaction.commit();

        assertEquals("Transaction start time should be reset after commit", 0, _transaction.getTransactionStartTime());
        assertEquals("Transaction update time should be reset after commit", 0, _transaction.getTransactionUpdateTime());
    }

    public void testRollbackResetsTransactionStartAndUpdateTime() throws Exception
    {
        assertEquals("Unexpected transaction start time before test", 0, _transaction.getTransactionStartTime());
        assertEquals("Unexpected transaction update time before test", 0, _transaction.getTransactionUpdateTime());

        _message = createTestMessage(true);
        _queue = createQueue(true);

        long startTime = System.currentTimeMillis();
        _transaction.enqueue(_queue, _message, _action1);

        assertTrue(_transaction.getTransactionStartTime() >= startTime);
        assertTrue(_transaction.getTransactionUpdateTime() >= startTime);

        _transaction.rollback();

        assertEquals("Transaction start time should be reset after rollback", 0, _transaction.getTransactionStartTime());
        assertEquals("Transaction update time should be reset after rollback", 0, _transaction.getTransactionUpdateTime());
    }

    private Collection<MessageInstance> createTestQueueEntries(boolean[] queueDurableFlags, boolean[] messagePersistentFlags)
    {
        Collection<MessageInstance> queueEntries = new ArrayList<MessageInstance>();
        
        assertTrue("Boolean arrays must be the same length", queueDurableFlags.length == messagePersistentFlags.length);
        
        for(int i = 0; i < queueDurableFlags.length; i++)
        {
            final TransactionLogResource queue = createQueue(queueDurableFlags[i]);
            final ServerMessage message = createTestMessage(messagePersistentFlags[i]);
            final boolean hasRecord = queueDurableFlags[i] && messagePersistentFlags[i];
            queueEntries.add(new MockMessageInstance()
            {

                @Override
                public ServerMessage getMessage()
                {
                    return message;
                }

                @Override
                public TransactionLogResource getOwningResource()
                {
                    return queue;
                }

                @Override
                public MessageEnqueueRecord getEnqueueRecord()
                {
                    return hasRecord ? mock(MessageEnqueueRecord.class) : null;
                }
            });
        }
        
        return queueEntries;
    }

    private MockStoreTransaction createTestStoreTransaction(boolean throwException)
    {
        return new MockStoreTransaction(throwException);
    }
    
    private List<BaseQueue> createTestBaseQueues(boolean[] durableFlags)
    {
        List<BaseQueue> queues = new ArrayList<BaseQueue>();
        for (boolean b: durableFlags)
        {
            queues.add(createQueue(b));
        }
        
        return queues;
    }

    private BaseQueue createQueue(final boolean durable)
    {
        BaseQueue queue = mock(BaseQueue.class);
        when(queue.isDurable()).thenReturn(durable);
        when(queue.getMessageDurability()).thenReturn(durable ? MessageDurability.DEFAULT : MessageDurability.NEVER);
        return queue;
    }

    private ServerMessage createTestMessage(final boolean persistent)
    {
        return new MockServerMessage(persistent);
    }

    private void assertNotFired(MockAction action)
    {
        assertFalse("Rollback action must not be fired", action.isRollbackActionFired());
        assertFalse("Post commit action must not be fired", action.isPostCommitActionFired());
    }

}
