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.powermock.reflect.Whitebox.getInternalState;
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;
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;
39 @RunWith(MockitoJUnitRunner.class)
40 public class TransactionInvokerImplTest {
42 private BindingTransactionChain chain;
44 private DataBroker db;
48 doReturn(chain).when(db).createTransactionChain(any(TransactionChainListener.class));
49 doNothing().when(chain).close();
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"));
61 public void testInvoke() {
62 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, new ArrayList<>());
63 final TransactionCommand command = mock(TransactionCommand.class);
64 invoker.invoke(command);
66 Queue<TransactionCommand> inputQueue = getInternalState(invoker, "inputQueue");
67 assertEquals(1, inputQueue.size());
68 assertTrue(inputQueue.contains(command));
72 public void testOnTransactionChainFailed() {
73 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, new ArrayList<>());
75 final AsyncTransaction<?, ?> transaction = mock(AsyncTransaction.class);
76 invoker.onTransactionChainFailed(chain, transaction, new Throwable());
78 final Queue<?> failedQueue = getInternalState(invoker, "failedTransactionQueue");
79 assertEquals(1, failedQueue.size());
80 assertTrue(failedQueue.contains(transaction));
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);
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);
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);
103 // .. we want to replay tx2 and tx3
104 assertEquals(ImmutableList.of(cmd2, cmd3), invoker.extractResubmitCommands());
108 public void testResetTransactionQueue() {
109 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList(),
110 Collections.singletonList(mock(ReadWriteTransaction.class)), Collections.emptyMap());
112 invoker.resetTransactionQueue();
114 assertNotNull(getInternalState(invoker, "pendingTransactions"));
115 assertNotNull(getInternalState(invoker, "transactionToCommand"));
116 final Queue<?> failedTransactionQueue = getInternalState(invoker, "failedTransactionQueue");
117 assertEquals(0, failedTransactionQueue.size());
121 public void testRecordPendingTransaction() {
122 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList());
124 final TransactionCommand command = mock(TransactionCommand.class);
125 final ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
126 invoker.recordPendingTransaction(command, transaction);
128 List<ReadWriteTransaction> testPendingTransactions = getInternalState(invoker, "pendingTransactions");
129 assertEquals(1, testPendingTransactions.size());
130 assertTrue(testPendingTransactions.contains(transaction));
132 assertEquals(Collections.singletonMap(transaction, command), getInternalState(invoker, "transactionToCommand"));
136 public void testExtractCommands() throws InterruptedException {
137 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList());
139 final TransactionCommand command = mock(TransactionCommand.class);
140 invoker.invoke(command);
142 assertEquals(Collections.singletonList(command), invoker.extractCommands());
146 public void testExtractCommandsFromQueue() throws InterruptedException {
147 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList());
149 final TransactionCommand command = mock(TransactionCommand.class);
150 invoker.invoke(command);
152 assertEquals(Collections.singletonList(command), invoker.extractCommandsFromQueue());
156 public void testClose() throws InterruptedException {
157 final ExecutorService executor = mock(ExecutorService.class);
158 doNothing().when(executor).shutdown();
160 try (TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, executor)) {
161 // No-op, but invokes close
164 verify(executor).shutdown();