1b237aecdb838d6d6a31b2deafeccb8ccb6322e5
[ovsdb.git] / southbound / southbound-impl / src / test / java / org / opendaylight / ovsdb / southbound / transactions / md / TransactionInvokerImplTest.java
1 /*
2  * Copyright (c) 2015 Inocybe Technologies and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.ovsdb.southbound.transactions.md;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.mockito.Matchers.any;
15 import static org.mockito.Mockito.doNothing;
16 import static org.mockito.Mockito.doReturn;
17 import static org.mockito.Mockito.mock;
18 import static org.mockito.Mockito.verify;
19 import static org.mockito.Mockito.when;
20 import static org.powermock.reflect.Whitebox.getField;
21
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.concurrent.BlockingQueue;
27 import java.util.concurrent.ExecutorService;
28 import java.util.concurrent.LinkedBlockingQueue;
29 import java.util.concurrent.atomic.AtomicBoolean;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.mockito.Mock;
34 import org.mockito.Mockito;
35 import org.mockito.junit.MockitoJUnitRunner;
36 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
37 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
38 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
39 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
40 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
41 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
42 import org.powermock.reflect.Whitebox;
43
44 @RunWith(MockitoJUnitRunner.class)
45 public class TransactionInvokerImplTest {
46
47     private static final int QUEUE_SIZE = 10000;
48     @Mock private BindingTransactionChain chain;
49     @Mock private DataBroker db;
50     private final BlockingQueue<TransactionCommand> inputQueue = new LinkedBlockingQueue<>(QUEUE_SIZE);
51     private final BlockingQueue<ReadWriteTransaction> successfulTxQ
52         = new LinkedBlockingQueue<>(QUEUE_SIZE);
53     private final BlockingQueue<AsyncTransaction<?, ?>> failedTransactionQ
54         = new LinkedBlockingQueue<>(QUEUE_SIZE);
55     @Mock private ExecutorService executor;
56     @Mock private AtomicBoolean runTask;
57     private final Map<ReadWriteTransaction,TransactionCommand> transactionToCommand
58         = new HashMap<>();
59     private final List<ReadWriteTransaction> pendingTransactions = new ArrayList<>();
60     private TransactionInvokerImpl transactionInvokerImpl;
61
62     @Before
63     public void setUp() throws Exception {
64         transactionInvokerImpl = mock(TransactionInvokerImpl.class, Mockito.CALLS_REAL_METHODS);
65         getField(TransactionInvokerImpl.class, "chain").set(transactionInvokerImpl, chain);
66         getField(TransactionInvokerImpl.class, "db").set(transactionInvokerImpl, db);
67     }
68
69     @Test
70     public void testTransactionInvokerImpl() throws Exception {
71         getField(TransactionInvokerImpl.class, "inputQueue").set(transactionInvokerImpl, inputQueue);
72         when(db.createTransactionChain(any(TransactionChainListener.class)))
73                 .thenReturn(mock(BindingTransactionChain.class));
74         TransactionInvokerImpl transactionInvokerImpl1 = new TransactionInvokerImpl(db);
75         verify(db).createTransactionChain(any(TransactionChainListener.class));
76         assertNotNull(Whitebox.getInternalState(transactionInvokerImpl1, "executor"));
77     }
78
79     @Test
80     public void testInvoke() throws Exception {
81         getField(TransactionInvokerImpl.class, "inputQueue").set(transactionInvokerImpl, inputQueue);
82         TransactionCommand command = mock(TransactionCommand.class);
83         transactionInvokerImpl.invoke(command);
84         BlockingQueue<TransactionCommand> testInputQueue = Whitebox.getInternalState(transactionInvokerImpl,
85                 "inputQueue");
86         assertTrue(testInputQueue.contains(command));
87     }
88
89     @Test
90     public void testOnTransactionChainFailed() throws Exception {
91         getField(TransactionInvokerImpl.class, "failedTransactionQueue").set(transactionInvokerImpl,
92                 failedTransactionQ);
93         AsyncTransaction<?, ?> transaction = mock(AsyncTransaction.class);
94         Throwable cause = mock(Throwable.class);
95         transactionInvokerImpl.onTransactionChainFailed(mock(TransactionChain.class), transaction, cause);
96         BlockingQueue<AsyncTransaction<?, ?>> testFailedTransactionQueue = Whitebox
97                 .getInternalState(transactionInvokerImpl, "failedTransactionQueue");
98         assertTrue(testFailedTransactionQueue.contains(transaction));
99     }
100
101     @SuppressWarnings("rawtypes")
102     @Test
103     public void testExtractResubmitCommands() throws Exception {
104         AsyncTransaction<?, ?> transaction = mock(ReadWriteTransaction.class);
105         failedTransactionQ.put(transaction);
106         getField(TransactionInvokerImpl.class, "failedTransactionQueue").set(transactionInvokerImpl,
107                 failedTransactionQ);
108
109         AsyncTransaction tx1 = mock(ReadWriteTransaction.class);
110         AsyncTransaction tx2 = mock(ReadWriteTransaction.class);
111         pendingTransactions.add((ReadWriteTransaction) tx1);
112         pendingTransactions.add((ReadWriteTransaction) transaction);
113         pendingTransactions.add((ReadWriteTransaction) tx2);
114         getField(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl,
115                 pendingTransactions);
116
117         List<ReadWriteTransaction> transactions = new ArrayList<>();
118         transactions.add((ReadWriteTransaction) tx1);
119
120         TransactionCommand txCommand = mock(TransactionCommand.class);
121         transactionToCommand.put((ReadWriteTransaction) tx1, txCommand);
122         transactionToCommand.put((ReadWriteTransaction) tx2, txCommand);
123         transactionToCommand.put((ReadWriteTransaction) transaction, txCommand);
124         getField(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl,
125                 transactionToCommand);
126         doNothing().when(transactionInvokerImpl).resetTransactionQueue();
127
128         List<TransactionCommand> testCommands = new ArrayList<>();
129         testCommands.add(txCommand);
130
131         assertEquals(testCommands, Whitebox.invokeMethod(transactionInvokerImpl, "extractResubmitCommands"));
132     }
133
134     @Test
135     public void testResetTransactionQueue() throws Exception {
136         doNothing().when(chain).close();
137         when(db.createTransactionChain(any(TransactionInvokerImpl.class))).thenReturn(chain);
138
139         failedTransactionQ.add(mock(AsyncTransaction.class));
140         getField(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl, pendingTransactions);
141         getField(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl,
142             transactionToCommand);
143         getField(TransactionInvokerImpl.class, "failedTransactionQueue").set(transactionInvokerImpl,
144             failedTransactionQ);
145         getField(TransactionInvokerImpl.class, "successfulTransactionQueue").set(transactionInvokerImpl, successfulTxQ);
146
147         Whitebox.invokeMethod(transactionInvokerImpl, "resetTransactionQueue");
148         assertNotNull(Whitebox.getInternalState(transactionInvokerImpl, "pendingTransactions"));
149         assertNotNull(Whitebox.getInternalState(transactionInvokerImpl, "transactionToCommand"));
150         BlockingQueue<AsyncTransaction<?, ?>> testFailedTransactionQueue = Whitebox
151                 .getInternalState(transactionInvokerImpl, "failedTransactionQueue");
152         assertEquals(0, testFailedTransactionQueue.size());
153     }
154
155     @Test
156     public void testRecordPendingTransaction() throws Exception {
157         TransactionCommand command = mock(TransactionCommand.class);
158         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
159         getField(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl, pendingTransactions);
160         getField(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl,
161             transactionToCommand);
162         Whitebox.invokeMethod(transactionInvokerImpl, "recordPendingTransaction", command, transaction);
163
164         List<ReadWriteTransaction> testPendingTransactions = Whitebox.getInternalState(transactionInvokerImpl,
165                 "pendingTransactions");
166         assertEquals(1, testPendingTransactions.size());
167
168         Map<ReadWriteTransaction, TransactionCommand> testTransactionToCommand = Whitebox
169                 .getInternalState(transactionInvokerImpl, "transactionToCommand");
170         assertEquals(1, testTransactionToCommand.size());
171     }
172
173     @Test
174     public void testExtractCommands() throws Exception {
175         List<TransactionCommand> commands = new ArrayList<>();
176         doReturn(commands).when(transactionInvokerImpl).extractResubmitCommands();
177
178         List<TransactionCommand> resubmitCommands = new ArrayList<>();
179         resubmitCommands.add(mock(TransactionCommand.class));
180         doReturn(resubmitCommands).when(transactionInvokerImpl).extractCommandsFromQueue();
181
182         List<TransactionCommand> testCommands = new ArrayList<>();
183         testCommands.addAll(resubmitCommands);
184
185         assertEquals(testCommands, Whitebox.invokeMethod(transactionInvokerImpl, "extractCommands"));
186     }
187
188     @Test
189     public void testExtractCommandsFromQueue() throws Exception {
190         TransactionCommand command = mock(TransactionCommand.class);
191         inputQueue.add(command);
192         getField(TransactionInvokerImpl.class, "inputQueue").set(transactionInvokerImpl, inputQueue);
193         List<TransactionCommand> testResult = new ArrayList<>();
194         testResult.add(command);
195         assertEquals(testResult, Whitebox.invokeMethod(transactionInvokerImpl, "extractCommandsFromQueue"));
196     }
197
198     @Test
199     public void testForgetSuccessfulTransactions() throws Exception {
200         ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
201         successfulTxQ.add(transaction);
202         pendingTransactions.add(transaction);
203         transactionToCommand.put(transaction, mock(TransactionCommand.class));
204         getField(TransactionInvokerImpl.class, "successfulTransactionQueue").set(transactionInvokerImpl, successfulTxQ);
205         getField(TransactionInvokerImpl.class, "pendingTransactions").set(transactionInvokerImpl, pendingTransactions);
206         getField(TransactionInvokerImpl.class, "transactionToCommand").set(transactionInvokerImpl,
207             transactionToCommand);
208
209         Whitebox.invokeMethod(transactionInvokerImpl, "forgetSuccessfulTransactions");
210
211         List<ReadWriteTransaction> testPendingTransactions = Whitebox.getInternalState(transactionInvokerImpl,
212                 "pendingTransactions");
213         Map<ReadWriteTransaction, TransactionCommand> testTransactionToCommand = Whitebox
214                 .getInternalState(transactionInvokerImpl, "transactionToCommand");
215         assertTrue(testPendingTransactions.isEmpty());
216         assertTrue(testTransactionToCommand.isEmpty());
217     }
218
219     @Test
220     public void testClose() throws Exception {
221         getField(TransactionInvokerImpl.class, "executor").set(transactionInvokerImpl, executor);
222         getField(TransactionInvokerImpl.class, "runTask").set(transactionInvokerImpl, runTask);
223         doNothing().when(executor).shutdown();
224         transactionInvokerImpl.close();
225         verify(executor).shutdown();
226     }
227 }