2 * Copyright (c) 2015 Inocybe Technologies and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.ovsdb.southbound.transactions.md;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.mockito.ArgumentMatchers.any;
14 import static org.mockito.Mockito.doNothing;
15 import static org.mockito.Mockito.doReturn;
16 import static org.mockito.Mockito.mock;
17 import static org.mockito.Mockito.verify;
18 import static org.mockito.Mockito.when;
19 import static org.powermock.reflect.Whitebox.getField;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
25 import java.util.concurrent.BlockingQueue;
26 import java.util.concurrent.ExecutorService;
27 import java.util.concurrent.LinkedBlockingQueue;
28 import java.util.concurrent.atomic.AtomicBoolean;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.mockito.Mock;
33 import org.mockito.Mockito;
34 import org.mockito.junit.MockitoJUnitRunner;
35 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
36 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
37 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
38 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
39 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
40 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
41 import org.powermock.reflect.Whitebox;
43 @RunWith(MockitoJUnitRunner.class)
44 public class TransactionInvokerImplTest {
46 private static final int QUEUE_SIZE = 10000;
47 @Mock private BindingTransactionChain chain;
48 @Mock private DataBroker db;
49 private final BlockingQueue<TransactionCommand> inputQueue = new LinkedBlockingQueue<>(QUEUE_SIZE);
50 private final BlockingQueue<ReadWriteTransaction> successfulTxQ
51 = new LinkedBlockingQueue<>(QUEUE_SIZE);
52 private final BlockingQueue<AsyncTransaction<?, ?>> failedTransactionQ
53 = new LinkedBlockingQueue<>(QUEUE_SIZE);
54 @Mock private ExecutorService executor;
55 @Mock private AtomicBoolean runTask;
56 private final Map<ReadWriteTransaction,TransactionCommand> transactionToCommand
58 private final List<ReadWriteTransaction> pendingTransactions = new ArrayList<>();
59 private TransactionInvokerImpl transactionInvokerImpl;
62 public void setUp() throws Exception {
63 transactionInvokerImpl = mock(TransactionInvokerImpl.class, Mockito.CALLS_REAL_METHODS);
64 getField(TransactionInvokerImpl.class, "chain").set(transactionInvokerImpl, chain);
65 getField(TransactionInvokerImpl.class, "db").set(transactionInvokerImpl, db);
69 public void testTransactionInvokerImpl() throws Exception {
70 getField(TransactionInvokerImpl.class, "inputQueue").set(transactionInvokerImpl, inputQueue);
71 when(db.createTransactionChain(any(TransactionChainListener.class)))
72 .thenReturn(mock(BindingTransactionChain.class));
73 TransactionInvokerImpl transactionInvokerImpl1 = new TransactionInvokerImpl(db);
74 verify(db).createTransactionChain(any(TransactionChainListener.class));
75 assertNotNull(Whitebox.getInternalState(transactionInvokerImpl1, "executor"));
79 public void testInvoke() throws Exception {
80 getField(TransactionInvokerImpl.class, "inputQueue").set(transactionInvokerImpl, inputQueue);
81 TransactionCommand command = mock(TransactionCommand.class);
82 transactionInvokerImpl.invoke(command);
83 BlockingQueue<TransactionCommand> testInputQueue = Whitebox.getInternalState(transactionInvokerImpl,
85 assertTrue(testInputQueue.contains(command));
89 public void testOnTransactionChainFailed() throws Exception {
90 getField(TransactionInvokerImpl.class, "failedTransactionQueue").set(transactionInvokerImpl,
92 AsyncTransaction<?, ?> transaction = mock(AsyncTransaction.class);
93 Throwable cause = mock(Throwable.class);
94 transactionInvokerImpl.onTransactionChainFailed(mock(TransactionChain.class), transaction, cause);
95 BlockingQueue<AsyncTransaction<?, ?>> testFailedTransactionQueue = Whitebox
96 .getInternalState(transactionInvokerImpl, "failedTransactionQueue");
97 assertTrue(testFailedTransactionQueue.contains(transaction));
100 @SuppressWarnings("rawtypes")
102 public void testExtractResubmitCommands() throws Exception {
103 AsyncTransaction<?, ?> transaction = mock(ReadWriteTransaction.class);
104 failedTransactionQ.put(transaction);
105 getField(TransactionInvokerImpl.class, "failedTransactionQueue").set(transactionInvokerImpl,
108 AsyncTransaction tx1 = mock(ReadWriteTransaction.class);
109 AsyncTransaction tx2 = mock(ReadWriteTransaction.class);
110 pendingTransactions.add((ReadWriteTransaction) tx1);
111 pendingTransactions.add((ReadWriteTransaction) transaction);
112 pendingTransactions.add((ReadWriteTransaction) tx2);
113 getField(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl,
114 pendingTransactions);
116 List<ReadWriteTransaction> transactions = new ArrayList<>();
117 transactions.add((ReadWriteTransaction) tx1);
119 TransactionCommand txCommand = mock(TransactionCommand.class);
120 transactionToCommand.put((ReadWriteTransaction) tx1, txCommand);
121 transactionToCommand.put((ReadWriteTransaction) tx2, txCommand);
122 transactionToCommand.put((ReadWriteTransaction) transaction, txCommand);
123 getField(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl,
124 transactionToCommand);
125 doNothing().when(transactionInvokerImpl).resetTransactionQueue();
127 List<TransactionCommand> testCommands = new ArrayList<>();
128 testCommands.add(txCommand);
130 assertEquals(testCommands, Whitebox.invokeMethod(transactionInvokerImpl, "extractResubmitCommands"));
134 public void testResetTransactionQueue() throws Exception {
135 doNothing().when(chain).close();
136 when(db.createTransactionChain(any(TransactionInvokerImpl.class))).thenReturn(chain);
138 failedTransactionQ.add(mock(AsyncTransaction.class));
139 getField(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl, pendingTransactions);
140 getField(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl,
141 transactionToCommand);
142 getField(TransactionInvokerImpl.class, "failedTransactionQueue").set(transactionInvokerImpl,
145 Whitebox.invokeMethod(transactionInvokerImpl, "resetTransactionQueue");
146 assertNotNull(Whitebox.getInternalState(transactionInvokerImpl, "pendingTransactions"));
147 assertNotNull(Whitebox.getInternalState(transactionInvokerImpl, "transactionToCommand"));
148 BlockingQueue<AsyncTransaction<?, ?>> testFailedTransactionQueue = Whitebox
149 .getInternalState(transactionInvokerImpl, "failedTransactionQueue");
150 assertEquals(0, testFailedTransactionQueue.size());
154 public void testRecordPendingTransaction() throws Exception {
155 TransactionCommand command = mock(TransactionCommand.class);
156 ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
157 getField(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl, pendingTransactions);
158 getField(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl,
159 transactionToCommand);
160 Whitebox.invokeMethod(transactionInvokerImpl, "recordPendingTransaction", command, transaction);
162 List<ReadWriteTransaction> testPendingTransactions = Whitebox.getInternalState(transactionInvokerImpl,
163 "pendingTransactions");
164 assertEquals(1, testPendingTransactions.size());
166 Map<ReadWriteTransaction, TransactionCommand> testTransactionToCommand = Whitebox
167 .getInternalState(transactionInvokerImpl, "transactionToCommand");
168 assertEquals(1, testTransactionToCommand.size());
172 public void testExtractCommands() throws Exception {
173 List<TransactionCommand> commands = new ArrayList<>();
174 doReturn(commands).when(transactionInvokerImpl).extractResubmitCommands();
176 List<TransactionCommand> resubmitCommands = new ArrayList<>();
177 resubmitCommands.add(mock(TransactionCommand.class));
178 doReturn(resubmitCommands).when(transactionInvokerImpl).extractCommandsFromQueue();
180 List<TransactionCommand> testCommands = new ArrayList<>();
181 testCommands.addAll(resubmitCommands);
183 assertEquals(testCommands, Whitebox.invokeMethod(transactionInvokerImpl, "extractCommands"));
187 public void testExtractCommandsFromQueue() throws Exception {
188 TransactionCommand command = mock(TransactionCommand.class);
189 inputQueue.add(command);
190 getField(TransactionInvokerImpl.class, "inputQueue").set(transactionInvokerImpl, inputQueue);
191 List<TransactionCommand> testResult = new ArrayList<>();
192 testResult.add(command);
193 assertEquals(testResult, Whitebox.invokeMethod(transactionInvokerImpl, "extractCommandsFromQueue"));
197 public void testClose() throws Exception {
198 getField(TransactionInvokerImpl.class, "executor").set(transactionInvokerImpl, executor);
199 getField(TransactionInvokerImpl.class, "runTask").set(transactionInvokerImpl, runTask);
200 doNothing().when(executor).shutdown();
201 transactionInvokerImpl.close();
202 verify(executor).shutdown();