package org.opendaylight.ovsdb.southbound.transactions.md; import static org.junit.Assert.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction; import org.opendaylight.controller.md.sal.common.api.data.TransactionChain; import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeNetdev; import org.powermock.api.mockito.PowerMockito; import org.powermock.api.support.membermodification.MemberModifier; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.reflect.Whitebox; import com.google.common.util.concurrent.CheckedFuture; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; @PrepareForTest({TransactionInvokerImpl.class}) @RunWith(PowerMockRunner.class) public class TransactionInvokerImplTest { private static final int QUEUE_SIZE = 10000; @Mock private BindingTransactionChain chain; @Mock private DataBroker db; private BlockingQueue inputQueue = new LinkedBlockingQueue(QUEUE_SIZE); private BlockingQueue successfulTransactionQueue = new LinkedBlockingQueue(QUEUE_SIZE); private BlockingQueue> failedTransactionQueue = new LinkedBlockingQueue>(QUEUE_SIZE); @Mock private ExecutorService executor; private Map transactionToCommand = new HashMap(); private List pendingTransactions = new ArrayList(); private TransactionInvokerImpl transactionInvokerImpl; @Before public void setUp() throws Exception { transactionInvokerImpl = PowerMockito.mock(TransactionInvokerImpl.class, Mockito.CALLS_REAL_METHODS); MemberModifier.field(TransactionInvokerImpl.class, "chain").set(transactionInvokerImpl, chain); MemberModifier.field(TransactionInvokerImpl.class, "db").set(transactionInvokerImpl, db); } @Test public void testTransactionInvokerImpl() throws Exception { MemberModifier.field(TransactionInvokerImpl.class, "inputQueue").set(transactionInvokerImpl, inputQueue); when(db.createTransactionChain(any(TransactionChainListener.class))).thenReturn(mock(BindingTransactionChain.class)); TransactionInvokerImpl transactionInvokerImpl1 = new TransactionInvokerImpl(db); verify(db).createTransactionChain(any(TransactionChainListener.class)); assertNotNull(Whitebox.getInternalState(transactionInvokerImpl1, "executor")); } @Test public void testInvoke() throws Exception { MemberModifier.field(TransactionInvokerImpl.class, "inputQueue").set(transactionInvokerImpl, inputQueue); TransactionCommand command = mock(TransactionCommand.class); transactionInvokerImpl.invoke(command); BlockingQueue testInputQueue = Whitebox.getInternalState(transactionInvokerImpl, "inputQueue"); assertTrue(testInputQueue.contains(command)); } @Test public void testOnTransactionChainFailed() throws Exception { MemberModifier.field(TransactionInvokerImpl.class, "failedTransactionQueue").set(transactionInvokerImpl, failedTransactionQueue); TransactionChain chain = mock(TransactionChain.class); AsyncTransaction transaction = mock(AsyncTransaction.class); Throwable cause = mock(Throwable.class); transactionInvokerImpl.onTransactionChainFailed(chain, transaction, cause); BlockingQueue> testFailedTransactionQueue = Whitebox.getInternalState(transactionInvokerImpl, "failedTransactionQueue"); assertTrue(testFailedTransactionQueue.contains(transaction)); } @SuppressWarnings("rawtypes") @Test public void testExtractResubmitCommands() throws Exception { AsyncTransaction transaction = mock(ReadWriteTransaction.class); failedTransactionQueue.put(transaction); MemberModifier.field(TransactionInvokerImpl.class, "failedTransactionQueue").set(transactionInvokerImpl, failedTransactionQueue); AsyncTransaction tx1 = mock(ReadWriteTransaction.class); AsyncTransaction tx2 = mock(ReadWriteTransaction.class); pendingTransactions.add((ReadWriteTransaction) tx1); pendingTransactions.add((ReadWriteTransaction) transaction); pendingTransactions.add((ReadWriteTransaction) tx2); MemberModifier.field(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl, pendingTransactions); List transactions= new ArrayList(); transactions.add((ReadWriteTransaction) tx1); TransactionCommand txCommand = mock(TransactionCommand.class); transactionToCommand.put((ReadWriteTransaction) tx1, txCommand); transactionToCommand.put((ReadWriteTransaction) tx2, txCommand); transactionToCommand.put((ReadWriteTransaction) transaction, txCommand); MemberModifier.field(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl, transactionToCommand); PowerMockito.suppress(MemberModifier.method(TransactionInvokerImpl.class, "resetTransactionQueue")); List testCommands = new ArrayList(); testCommands.add(txCommand); assertEquals(testCommands, Whitebox.invokeMethod(transactionInvokerImpl, "extractResubmitCommands")); } @Test public void testResetTransactionQueue() throws Exception { doNothing().when(chain).close(); when(db.createTransactionChain(any(TransactionInvokerImpl.class))).thenReturn(chain); failedTransactionQueue.add(mock(AsyncTransaction.class)); MemberModifier.field(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl, pendingTransactions); MemberModifier.field(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl, transactionToCommand); MemberModifier.field(TransactionInvokerImpl.class, "failedTransactionQueue").set(transactionInvokerImpl, failedTransactionQueue); MemberModifier.field(TransactionInvokerImpl.class, "successfulTransactionQueue").set(transactionInvokerImpl, successfulTransactionQueue); Whitebox.invokeMethod(transactionInvokerImpl, "resetTransactionQueue"); assertNotNull(Whitebox.getInternalState(transactionInvokerImpl, "pendingTransactions")); assertNotNull(Whitebox.getInternalState(transactionInvokerImpl, "transactionToCommand")); BlockingQueue> testFailedTransactionQueue = Whitebox.getInternalState(transactionInvokerImpl, "failedTransactionQueue"); assertEquals(0, testFailedTransactionQueue.size()); } @Test public void testRecordPendingTransaction() throws Exception { TransactionCommand command = mock(TransactionCommand.class); ReadWriteTransaction transaction= mock(ReadWriteTransaction.class); MemberModifier.field(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl, pendingTransactions); MemberModifier.field(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl, transactionToCommand); Whitebox.invokeMethod(transactionInvokerImpl, "recordPendingTransaction", command, transaction); List testPendingTransactions = Whitebox.getInternalState(transactionInvokerImpl, "pendingTransactions"); assertEquals(1, testPendingTransactions.size()); Map testTransactionToCommand = Whitebox.getInternalState(transactionInvokerImpl, "transactionToCommand"); assertEquals(1, testTransactionToCommand.size()); } @Test public void testExtractCommands() throws Exception { List commands = new ArrayList<>(); PowerMockito.doReturn(commands).when(transactionInvokerImpl, "extractResubmitCommands"); List resubmitCommands = new ArrayList<>(); resubmitCommands.add(mock(TransactionCommand.class)); PowerMockito.doReturn(resubmitCommands).when(transactionInvokerImpl, "extractCommandsFromQueue"); List testCommands = new ArrayList<>(); testCommands.addAll(resubmitCommands); assertEquals(testCommands, Whitebox.invokeMethod(transactionInvokerImpl, "extractCommands")); } @Test public void testExtractCommandsFromQueue() throws Exception { TransactionCommand command = mock(TransactionCommand.class); inputQueue.add(command); MemberModifier.field(TransactionInvokerImpl.class, "inputQueue").set(transactionInvokerImpl, inputQueue); List testResult = new ArrayList(); testResult.add(command); assertEquals(testResult, Whitebox.invokeMethod(transactionInvokerImpl, "extractCommandsFromQueue")); } @Test public void testForgetSuccessfulTransactions() throws Exception { ReadWriteTransaction transaction = mock(ReadWriteTransaction.class); successfulTransactionQueue.add(transaction); pendingTransactions.add(transaction); transactionToCommand.put(transaction, mock(TransactionCommand.class)); MemberModifier.field(TransactionInvokerImpl.class, "successfulTransactionQueue").set(transactionInvokerImpl, successfulTransactionQueue); MemberModifier.field(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl, pendingTransactions); MemberModifier.field(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl, transactionToCommand); Whitebox.invokeMethod(transactionInvokerImpl, "forgetSuccessfulTransactions"); List testPendingTransactions = Whitebox.getInternalState(transactionInvokerImpl, "pendingTransactions"); Map testTransactionToCommand = Whitebox.getInternalState(transactionInvokerImpl, "transactionToCommand"); assertTrue(testPendingTransactions.isEmpty()); assertTrue(testTransactionToCommand.isEmpty()); } @Test public void testClose() throws Exception { MemberModifier.field(TransactionInvokerImpl.class, "executor").set(transactionInvokerImpl, executor); doNothing().when(executor).shutdown(); transactionInvokerImpl.close(); verify(executor).shutdown(); } }