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