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;
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;
38 @RunWith(MockitoJUnitRunner.class)
39 public class TransactionInvokerImplTest {
41 private BindingTransactionChain chain;
43 private DataBroker db;
47 doReturn(chain).when(db).createTransactionChain(any(TransactionChainListener.class));
48 doNothing().when(chain).close();
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"));
60 public void testInvoke() {
61 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, new ArrayList<>());
62 final TransactionCommand command = mock(TransactionCommand.class);
63 invoker.invoke(command);
65 Queue<TransactionCommand> inputQueue = getInternalState(invoker, "inputQueue");
66 assertEquals(1, inputQueue.size());
67 assertTrue(inputQueue.contains(command));
71 public void testOnTransactionChainFailed() {
72 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, new ArrayList<>());
74 final AsyncTransaction<?, ?> transaction = mock(AsyncTransaction.class);
75 invoker.onTransactionChainFailed(chain, transaction, new Throwable());
77 final Queue<?> failedQueue = getInternalState(invoker, "failedTransactionQueue");
78 assertEquals(1, failedQueue.size());
79 assertTrue(failedQueue.contains(transaction));
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);
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);
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);
102 // .. we want to replay tx2 and tx3
103 assertEquals(ImmutableList.of(cmd2, cmd3), invoker.extractResubmitCommands());
107 public void testResetTransactionQueue() {
108 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList(),
109 Collections.singletonList(mock(ReadWriteTransaction.class)), Collections.emptyMap());
111 invoker.resetTransactionQueue();
113 assertNotNull(getInternalState(invoker, "pendingTransactions"));
114 assertNotNull(getInternalState(invoker, "transactionToCommand"));
115 final Queue<?> failedTransactionQueue = getInternalState(invoker, "failedTransactionQueue");
116 assertEquals(0, failedTransactionQueue.size());
120 public void testRecordPendingTransaction() {
121 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList());
123 final TransactionCommand command = mock(TransactionCommand.class);
124 final ReadWriteTransaction transaction = mock(ReadWriteTransaction.class);
125 invoker.recordPendingTransaction(command, transaction);
127 Queue<ReadWriteTransaction> testPendingTransactions = getInternalState(invoker, "pendingTransactions");
128 assertEquals(1, testPendingTransactions.size());
129 assertTrue(testPendingTransactions.contains(transaction));
131 assertEquals(Collections.singletonMap(transaction, command), getInternalState(invoker, "transactionToCommand"));
135 public void testExtractCommands() throws InterruptedException {
136 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList());
138 final TransactionCommand command = mock(TransactionCommand.class);
139 invoker.invoke(command);
141 assertEquals(Collections.singletonList(command), invoker.extractCommands());
145 public void testExtractCommandsFromQueue() throws InterruptedException {
146 final TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, Collections.emptyList());
148 final TransactionCommand command = mock(TransactionCommand.class);
149 invoker.invoke(command);
151 assertEquals(Collections.singletonList(command), invoker.extractCommandsFromQueue());
155 public void testClose() throws InterruptedException {
156 final ExecutorService executor = mock(ExecutorService.class);
157 doNothing().when(executor).shutdown();
159 try (TransactionInvokerImpl invoker = new TransactionInvokerImpl(db, executor)) {
160 // No-op, but invokes close
163 verify(executor).shutdown();