2 * Copyright © 2017 Orange, Inc. 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
9 package org.opendaylight.transportpce.common.device;
11 import static org.junit.jupiter.api.Assertions.assertFalse;
12 import static org.junit.jupiter.api.Assertions.assertTrue;
13 import static org.junit.jupiter.api.Assertions.fail;
14 import static org.mockito.ArgumentMatchers.any;
15 import static org.mockito.Mockito.lenient;
16 import static org.mockito.Mockito.when;
18 import java.util.LinkedList;
19 import java.util.List;
20 import java.util.Optional;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.Future;
23 import java.util.concurrent.TimeUnit;
24 import java.util.concurrent.TimeoutException;
25 import org.junit.jupiter.api.AfterEach;
26 import org.junit.jupiter.api.BeforeEach;
27 import org.junit.jupiter.api.Test;
28 import org.junit.jupiter.api.extension.ExtendWith;
29 import org.mockito.Mock;
30 import org.mockito.Mockito;
31 import org.mockito.junit.jupiter.MockitoExtension;
32 import org.opendaylight.mdsal.binding.api.DataBroker;
33 import org.opendaylight.mdsal.binding.api.MountPoint;
34 import org.opendaylight.mdsal.binding.api.MountPointService;
35 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
36 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.NetworkId;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.Networks;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.Network;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.rev180226.networks.NetworkBuilder;
41 import org.opendaylight.yangtools.util.concurrent.FluentFutures;
42 import org.opendaylight.yangtools.yang.binding.DataObject;
43 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45 @ExtendWith(MockitoExtension.class)
46 public class DeviceTransactionManagerTest {
49 private MountPointService mountPointServiceMock;
51 private MountPoint mountPointMock;
53 private DataBroker dataBrokerMock;
55 private ReadWriteTransaction rwTransactionMock;
58 private DeviceTransactionManagerImpl transactionManager;
59 private String defaultDeviceId = "device-id";
60 private LogicalDatastoreType defaultDatastore = LogicalDatastoreType.OPERATIONAL;
61 private InstanceIdentifier<Network> defaultIid = InstanceIdentifier
62 .builder(Networks.class).child(Network.class).build();
63 private Network defaultData;
64 private long defaultTimeout = 1000;
65 private TimeUnit defaultTimeUnit = TimeUnit.MILLISECONDS;
69 when(mountPointServiceMock.getMountPoint(any())).thenReturn(Optional.of(mountPointMock));
70 when(mountPointMock.getService(any())).thenReturn(Optional.of(dataBrokerMock));
71 when(dataBrokerMock.newReadWriteTransaction()).thenReturn(rwTransactionMock);
72 lenient().when(rwTransactionMock.commit()).thenReturn(FluentFutures.immediateNullFluentFuture());
73 NetworkId networkId = new NetworkId("NETWORK1");
74 defaultData = new NetworkBuilder().setNetworkId(networkId).build();
75 this.transactionManager = new DeviceTransactionManagerImpl(mountPointServiceMock, 3000);
80 transactionManager.preDestroy();
84 void basicPositiveTransactionTest() {
86 putAndSubmit(transactionManager, defaultDeviceId, defaultDatastore, defaultIid, defaultData);
87 } catch (InterruptedException | ExecutionException e) {
88 fail("Exception catched! " + e);
92 Mockito.verify(rwTransactionMock, Mockito.times(1)).put(defaultDatastore, defaultIid, defaultData);
93 Mockito.verify(rwTransactionMock, Mockito.times(1)).commit();
97 void advancedPositiveTransactionTest() {
99 Future<java.util.Optional<DeviceTransaction>> firstDeviceTxFuture =
100 transactionManager.getDeviceTransaction(defaultDeviceId);
101 DeviceTransaction firstDeviceTx = firstDeviceTxFuture.get().orElseThrow();
103 Future<java.util.Optional<DeviceTransaction>> secondDeviceTxFuture =
104 transactionManager.getDeviceTransaction(defaultDeviceId);
105 assertFalse(secondDeviceTxFuture.isDone());
107 Future<java.util.Optional<DeviceTransaction>> thirdDeviceTxFuture =
108 transactionManager.getDeviceTransaction(defaultDeviceId);
109 assertFalse(thirdDeviceTxFuture.isDone());
111 firstDeviceTx.put(defaultDatastore, defaultIid, defaultData);
112 assertFalse(secondDeviceTxFuture.isDone());
113 assertFalse(thirdDeviceTxFuture.isDone());
115 assertFalse(secondDeviceTxFuture.isDone());
116 assertFalse(thirdDeviceTxFuture.isDone());
118 Future<java.util.Optional<DeviceTransaction>> anotherDeviceTxFuture =
119 transactionManager.getDeviceTransaction("another-id");
121 assertTrue(anotherDeviceTxFuture.isDone());
122 anotherDeviceTxFuture.get().orElseThrow().commit(defaultTimeout, defaultTimeUnit);
124 firstDeviceTx.commit(defaultTimeout, defaultTimeUnit);
126 assertTrue(secondDeviceTxFuture.isDone());
127 assertFalse(thirdDeviceTxFuture.isDone());
129 DeviceTransaction secondDeviceTx = secondDeviceTxFuture.get().orElseThrow();
130 secondDeviceTx.put(defaultDatastore, defaultIid, defaultData);
131 assertFalse(thirdDeviceTxFuture.isDone());
133 secondDeviceTx.commit(defaultTimeout, defaultTimeUnit);
135 assertTrue(thirdDeviceTxFuture.isDone());
137 DeviceTransaction thirdDeviceTx = thirdDeviceTxFuture.get().orElseThrow();
138 thirdDeviceTx.put(defaultDatastore, defaultIid, defaultData);
139 thirdDeviceTx.commit(defaultTimeout, defaultTimeUnit);
141 Mockito.verify(rwTransactionMock, Mockito.times(3)).put(defaultDatastore, defaultIid, defaultData);
142 Mockito.verify(rwTransactionMock, Mockito.times(4)).commit();
143 } catch (InterruptedException | ExecutionException e) {
144 fail("Exception catched! " + e);
149 void bigAmountOfTransactionsOnSameDeviceTest() {
150 int numberOfTxs = 100;
151 List<Future<java.util.Optional<DeviceTransaction>>> deviceTransactionFutures = new LinkedList<>();
152 List<DeviceTransaction> deviceTransactions = new LinkedList<>();
154 for (int i = 0; i < numberOfTxs; i++) {
155 deviceTransactionFutures.add(transactionManager.getDeviceTransaction(defaultDeviceId));
159 for (Future<java.util.Optional<DeviceTransaction>> futureTx : deviceTransactionFutures) {
160 DeviceTransaction deviceTx = futureTx.get().orElseThrow();
161 deviceTx.commit(defaultTimeout, defaultTimeUnit);
162 deviceTransactions.add(deviceTx);
164 } catch (InterruptedException | ExecutionException e) {
165 fail("Exception catched! " + e);
168 for (DeviceTransaction deviceTx : deviceTransactions) {
169 assertTrue(deviceTx.wasSubmittedOrCancelled().get());
174 void bigAmountOfTransactionsOnDifferentDevicesTest() {
175 int numberOfTxs = 1000;
176 List<DeviceTransaction> deviceTransactions = new LinkedList<>();
179 for (int i = 0; i < numberOfTxs; i++) {
180 deviceTransactions.add(transactionManager.getDeviceTransaction(defaultDeviceId + " " + i).get()
183 } catch (InterruptedException | ExecutionException e) {
184 fail("Exception catched! " + e);
187 deviceTransactions.parallelStream()
188 .forEach(deviceTransaction -> deviceTransaction.commit(defaultTimeout, defaultTimeUnit));
190 deviceTransactions.parallelStream()
191 .forEach(deviceTransaction -> assertTrue(deviceTransaction.wasSubmittedOrCancelled().get()));
195 void bigAmountOfTransactionsOnDifferentDevicesWithoutSubmitTest() {
196 int numberOfTxs = 1000;
197 List<DeviceTransaction> deviceTransactions = new LinkedList<>();
200 for (int i = 0; i < numberOfTxs; i++) {
201 deviceTransactions.add(transactionManager.getDeviceTransaction(defaultDeviceId + " " + i).get()
204 } catch (InterruptedException | ExecutionException e) {
205 fail("Exception catched! " + e);
209 Thread.sleep(transactionManager.getMaxDurationToSubmitTransaction() + 1000);
210 } catch (InterruptedException e) {
211 fail("Exception catched! " + e);
213 deviceTransactions.parallelStream()
214 .forEach(deviceTransaction -> assertTrue(deviceTransaction.wasSubmittedOrCancelled().get()));
218 void notSubmittedTransactionTest() {
219 Future<java.util.Optional<DeviceTransaction>> deviceTxFuture =
220 transactionManager.getDeviceTransaction(defaultDeviceId);
222 deviceTxFuture.get();
223 Thread.sleep(transactionManager.getMaxDurationToSubmitTransaction() + 1000);
224 } catch (InterruptedException | ExecutionException e) {
225 fail("Exception catched! " + e);
227 Mockito.verify(rwTransactionMock, Mockito.times(1)).cancel();
230 putAndSubmit(transactionManager, defaultDeviceId, defaultDatastore, defaultIid, defaultData);
231 } catch (InterruptedException | ExecutionException e) {
232 fail("Exception catched! " + e);
236 Mockito.verify(rwTransactionMock, Mockito.times(1)).cancel();
237 Mockito.verify(rwTransactionMock, Mockito.times(1)).put(defaultDatastore, defaultIid, defaultData);
238 Mockito.verify(rwTransactionMock, Mockito.times(1)).commit();
242 void dataBrokerTimeoutTransactionTest() {
243 Mockito.when(dataBrokerMock.newReadWriteTransaction()).then(invocation -> {
244 Thread.sleep(transactionManager.getMaxDurationToSubmitTransaction() + 1000);
245 return rwTransactionMock;
249 putAndSubmit(transactionManager, defaultDeviceId, defaultDatastore, defaultIid, defaultData);
250 } catch (InterruptedException | ExecutionException e) {
251 fail("Exception catched! " + e);
254 Mockito.verify(rwTransactionMock, Mockito.times(1)).commit();
256 Mockito.when(dataBrokerMock.newReadWriteTransaction()).thenReturn(rwTransactionMock); // remove sleep
259 putAndSubmit(transactionManager, defaultDeviceId, defaultDatastore, defaultIid, defaultData);
260 } catch (InterruptedException | ExecutionException e) {
261 fail("Exception catched! " + e);
265 Mockito.verify(rwTransactionMock, Mockito.times(2)).put(defaultDatastore, defaultIid, defaultData);
266 Mockito.verify(rwTransactionMock, Mockito.times(2)).commit();
270 void getFutureTimeoutTransactionTest() {
271 Mockito.when(dataBrokerMock.newReadWriteTransaction()).then(invocation -> {
273 return rwTransactionMock;
276 Exception throwedException = null;
278 Future<java.util.Optional<DeviceTransaction>> deviceTxFuture =
279 transactionManager.getDeviceTransaction(defaultDeviceId);
281 deviceTxFuture.get(1000, TimeUnit.MILLISECONDS);
282 } catch (InterruptedException | ExecutionException e) {
283 fail("Exception catched! " + e);
284 } catch (TimeoutException e) {
285 throwedException = e;
288 if (throwedException == null) {
289 fail("TimeoutException should be thrown!");
293 Mockito.when(dataBrokerMock.newReadWriteTransaction()).thenReturn(rwTransactionMock); // remove sleep
296 putAndSubmit(transactionManager, defaultDeviceId, defaultDatastore, defaultIid, defaultData);
297 } catch (InterruptedException | ExecutionException e) {
298 fail("Exception catched! " + e);
302 Mockito.verify(rwTransactionMock, Mockito.times(1)).put(defaultDatastore, defaultIid, defaultData);
303 Mockito.verify(rwTransactionMock, Mockito.times(1)).commit();
306 private <T extends DataObject> void putAndSubmit(DeviceTransactionManagerImpl deviceTxManager, String deviceId,
307 LogicalDatastoreType store, InstanceIdentifier<T> path, T data)
308 throws ExecutionException, InterruptedException {
309 Future<java.util.Optional<DeviceTransaction>> deviceTxFuture = deviceTxManager.getDeviceTransaction(deviceId);
310 DeviceTransaction deviceTx = deviceTxFuture.get().orElseThrow();
311 deviceTx.put(store, path, data);
312 deviceTx.commit(defaultTimeout, defaultTimeUnit);