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().get();
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().get().commit(defaultTimeout, defaultTimeUnit);
124 firstDeviceTx.commit(defaultTimeout, defaultTimeUnit);
126 assertTrue(secondDeviceTxFuture.isDone());
127 assertFalse(thirdDeviceTxFuture.isDone());
129 DeviceTransaction secondDeviceTx = secondDeviceTxFuture.get().get();
130 secondDeviceTx.put(defaultDatastore, defaultIid, defaultData);
131 assertFalse(thirdDeviceTxFuture.isDone());
133 secondDeviceTx.commit(defaultTimeout, defaultTimeUnit);
135 assertTrue(thirdDeviceTxFuture.isDone());
137 DeviceTransaction thirdDeviceTx = thirdDeviceTxFuture.get().get();
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().get();
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().get());
182 } catch (InterruptedException | ExecutionException e) {
183 fail("Exception catched! " + e);
186 deviceTransactions.parallelStream()
187 .forEach(deviceTransaction -> deviceTransaction.commit(defaultTimeout, defaultTimeUnit));
189 deviceTransactions.parallelStream()
190 .forEach(deviceTransaction -> assertTrue(deviceTransaction.wasSubmittedOrCancelled().get()));
194 void bigAmountOfTransactionsOnDifferentDevicesWithoutSubmitTest() {
195 int numberOfTxs = 1000;
196 List<DeviceTransaction> deviceTransactions = new LinkedList<>();
199 for (int i = 0; i < numberOfTxs; i++) {
200 deviceTransactions.add(transactionManager.getDeviceTransaction(defaultDeviceId + " " + i).get().get());
202 } catch (InterruptedException | ExecutionException e) {
203 fail("Exception catched! " + e);
207 Thread.sleep(transactionManager.getMaxDurationToSubmitTransaction() + 1000);
208 } catch (InterruptedException e) {
209 fail("Exception catched! " + e);
211 deviceTransactions.parallelStream()
212 .forEach(deviceTransaction -> assertTrue(deviceTransaction.wasSubmittedOrCancelled().get()));
216 void notSubmittedTransactionTest() {
217 Future<java.util.Optional<DeviceTransaction>> deviceTxFuture =
218 transactionManager.getDeviceTransaction(defaultDeviceId);
220 deviceTxFuture.get();
221 Thread.sleep(transactionManager.getMaxDurationToSubmitTransaction() + 1000);
222 } catch (InterruptedException | ExecutionException e) {
223 fail("Exception catched! " + e);
225 Mockito.verify(rwTransactionMock, Mockito.times(1)).cancel();
228 putAndSubmit(transactionManager, defaultDeviceId, defaultDatastore, defaultIid, defaultData);
229 } catch (InterruptedException | ExecutionException e) {
230 fail("Exception catched! " + e);
234 Mockito.verify(rwTransactionMock, Mockito.times(1)).cancel();
235 Mockito.verify(rwTransactionMock, Mockito.times(1)).put(defaultDatastore, defaultIid, defaultData);
236 Mockito.verify(rwTransactionMock, Mockito.times(1)).commit();
240 void dataBrokerTimeoutTransactionTest() {
241 Mockito.when(dataBrokerMock.newReadWriteTransaction()).then(invocation -> {
242 Thread.sleep(transactionManager.getMaxDurationToSubmitTransaction() + 1000);
243 return rwTransactionMock;
247 putAndSubmit(transactionManager, defaultDeviceId, defaultDatastore, defaultIid, defaultData);
248 } catch (InterruptedException | ExecutionException e) {
249 fail("Exception catched! " + e);
252 Mockito.verify(rwTransactionMock, Mockito.times(1)).commit();
254 Mockito.when(dataBrokerMock.newReadWriteTransaction()).thenReturn(rwTransactionMock); // remove sleep
257 putAndSubmit(transactionManager, defaultDeviceId, defaultDatastore, defaultIid, defaultData);
258 } catch (InterruptedException | ExecutionException e) {
259 fail("Exception catched! " + e);
263 Mockito.verify(rwTransactionMock, Mockito.times(2)).put(defaultDatastore, defaultIid, defaultData);
264 Mockito.verify(rwTransactionMock, Mockito.times(2)).commit();
268 void getFutureTimeoutTransactionTest() {
269 Mockito.when(dataBrokerMock.newReadWriteTransaction()).then(invocation -> {
271 return rwTransactionMock;
274 Exception throwedException = null;
276 Future<java.util.Optional<DeviceTransaction>> deviceTxFuture =
277 transactionManager.getDeviceTransaction(defaultDeviceId);
279 deviceTxFuture.get(1000, TimeUnit.MILLISECONDS);
280 } catch (InterruptedException | ExecutionException e) {
281 fail("Exception catched! " + e);
282 } catch (TimeoutException e) {
283 throwedException = e;
286 if (throwedException == null) {
287 fail("TimeoutException should be thrown!");
291 Mockito.when(dataBrokerMock.newReadWriteTransaction()).thenReturn(rwTransactionMock); // remove sleep
294 putAndSubmit(transactionManager, defaultDeviceId, defaultDatastore, defaultIid, defaultData);
295 } catch (InterruptedException | ExecutionException e) {
296 fail("Exception catched! " + e);
300 Mockito.verify(rwTransactionMock, Mockito.times(1)).put(defaultDatastore, defaultIid, defaultData);
301 Mockito.verify(rwTransactionMock, Mockito.times(1)).commit();
304 private <T extends DataObject> void putAndSubmit(DeviceTransactionManagerImpl deviceTxManager, String deviceId,
305 LogicalDatastoreType store, InstanceIdentifier<T> path, T data)
306 throws ExecutionException, InterruptedException {
307 Future<java.util.Optional<DeviceTransaction>> deviceTxFuture = deviceTxManager.getDeviceTransaction(deviceId);
308 DeviceTransaction deviceTx = deviceTxFuture.get().get();
309 deviceTx.put(store, path, data);
310 deviceTx.commit(defaultTimeout, defaultTimeUnit);