Use ArrayDeque for TransactionInvokerImpl.pendingTransactions
[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 package org.opendaylight.ovsdb.southbound.transactions.md;
9
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.powermock.reflect.Whitebox.getInternalState;
19
20 import com.google.common.collect.ImmutableList;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Queue;
26 import java.util.concurrent.ExecutorService;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.mockito.Mock;
31 import org.mockito.junit.MockitoJUnitRunner;
32 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
33 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
34 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
35 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
36 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
37
38 @RunWith(MockitoJUnitRunner.class)
39 public class TransactionInvokerImplTest {
40     @Mock
41     private BindingTransactionChain chain;
42     @Mock
43     private DataBroker db;
44
45     @Before
46     public void setUp() {
47         doReturn(chain).when(db).createTransactionChain(any(TransactionChainListener.class));
48         doNothing().when(chain).close();
49     }
50
51     @Test
52     public void testConstructor() throws InterruptedException {
53         try (TransactionInvokerImpl invoker = new TransactionInvokerImpl(db)) {
54             verify(db).createTransactionChain(any(TransactionChainListener.class));
55             assertNotNull(getInternalState(invoker, "executor"));
56         }
57     }
58
59     @Test
60     public void testInvoke() {
61         final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, new ArrayList<>());
62         final TransactionCommand command = mock(TransactionCommand.class);
63         invoker.invoke(command);
64
65         Queue<TransactionCommand> inputQueue = getInternalState(invoker, "inputQueue");
66         assertEquals(1, inputQueue.size());
67         assertTrue(inputQueue.contains(command));
68     }
69
70     @Test
71     public void testOnTransactionChainFailed() {
72         final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, new ArrayList<>());
73
74         final AsyncTransaction<?, ?> transaction = mock(AsyncTransaction.class);
75         invoker.onTransactionChainFailed(chain, transaction, new Throwable());
76
77         final Queue<?> failedQueue = getInternalState(invoker, "failedTransactionQueue");
78         assertEquals(1, failedQueue.size());
79         assertTrue(failedQueue.contains(transaction));
80     }
81
82     @Test
83     public void testExtractResubmitCommands() {
84         final ReadWriteTransaction tx1 = mock(ReadWriteTransaction.class);
85         final ReadWriteTransaction tx2 = mock(ReadWriteTransaction.class);
86         final ReadWriteTransaction tx3 = mock(ReadWriteTransaction.class);
87
88         final Map<ReadWriteTransaction,TransactionCommand> transactionToCommand = new HashMap<>();
89         transactionToCommand.put(tx1, mock(TransactionCommand.class));
90         final TransactionCommand cmd2 = mock(TransactionCommand.class);
91         transactionToCommand.put(tx2, cmd2);
92         final TransactionCommand cmd3 = mock(TransactionCommand.class);
93         transactionToCommand.put(tx3, cmd3);
94
95         final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db,
96             // Given pending transaction order ...
97             ImmutableList.of(tx1, tx2, tx3),
98             // .. if tx2 fails ...
99             Collections.singletonList(tx2),
100             transactionToCommand);
101
102         // .. we want to replay tx2 and tx3
103         assertEquals(ImmutableList.of(cmd2, cmd3), invoker.extractResubmitCommands());
104     }
105
106     @Test
107     public void testResetTransactionQueue() {
108         final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList(),
109             Collections.singletonList(mock(ReadWriteTransaction.class)), Collections.emptyMap());
110
111         invoker.resetTransactionQueue();
112
113         assertNotNull(getInternalState(invoker, "pendingTransactions"));
114         assertNotNull(getInternalState(invoker, "transactionToCommand"));
115         final Queue<?> failedTransactionQueue = getInternalState(invoker, "failedTransactionQueue");
116         assertEquals(0, failedTransactionQueue.size());
117     }
118
119     @Test
120     public void testRecordPendingTransaction() {
121         final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList());
122
123         final TransactionCommand command = mock(TransactionCommand.class);
124         final ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
125         invoker.recordPendingTransaction(command, transaction);
126
127         Queue<ReadWriteTransaction> testPendingTransactions = getInternalState(invoker, "pendingTransactions");
128         assertEquals(1, testPendingTransactions.size());
129         assertTrue(testPendingTransactions.contains(transaction));
130
131         assertEquals(Collections.singletonMap(transaction, command), getInternalState(invoker, "transactionToCommand"));
132     }
133
134     @Test
135     public void testExtractCommands() throws InterruptedException {
136         final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList());
137
138         final TransactionCommand command = mock(TransactionCommand.class);
139         invoker.invoke(command);
140
141         assertEquals(Collections.singletonList(command), invoker.extractCommands());
142     }
143
144     @Test
145     public void testExtractCommandsFromQueue() throws InterruptedException {
146         final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList());
147
148         final TransactionCommand command = mock(TransactionCommand.class);
149         invoker.invoke(command);
150
151         assertEquals(Collections.singletonList(command), invoker.extractCommandsFromQueue());
152     }
153
154     @Test
155     public void testClose() throws InterruptedException {
156         final ExecutorService executor = mock(ExecutorService.class);
157         doNothing().when(executor).shutdown();
158
159         try (TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, executor)) {
160             // No-op, but invokes close
161         }
162
163         verify(executor).shutdown();
164     }
165 }