/*
 *
 * 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.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
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());
    }

    public void testEnqueueInvokesTransactionObserver() throws Exception
    {
        final TransactionObserver
                transactionObserver = mock(TransactionObserver.class);
        _transaction = new LocalTransaction(_transactionLog, transactionObserver);

        _message = createTestMessage(true);
        _queues = createTestBaseQueues(new boolean[] {false, true, false, true});

        _transaction.enqueue(_queues, _message, null);

        verify(transactionObserver).onMessageEnqueue(_transaction, _message);

        ServerMessage message2 = createTestMessage(true);
        _transaction.enqueue(createQueue(true), message2, null);

        verify(transactionObserver).onMessageEnqueue(_transaction, message2);
        verifyNoMoreInteractions(transactionObserver);
    }

    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.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());
    }

}
