OPNFLWPLUG-1032: Neon-MRI: Bump odlparent, yangtools, mdsal
[openflowplugin.git] / applications / topology-manager / src / test / java / org / opendaylight / openflowplugin / applications / topology / manager / TerminationPointChangeListenerImplTest.java
1 /*
2  * Copyright (c) 2015, 2017 Cisco Systems, Inc. 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.openflowplugin.applications.topology.manager;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.ArgumentMatchers.eq;
14 import static org.mockito.Mockito.doReturn;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.verify;
17 import static org.mockito.Mockito.when;
18 import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.DELETE;
19 import static org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType.WRITE;
20 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.assertDeletedIDs;
21 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newDestTp;
22 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newInvNodeConnKey;
23 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newInvNodeKey;
24 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newLink;
25 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newNodeConnID;
26 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newSourceTp;
27 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.setReadFutureAsync;
28 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.setupStubbedDeletes;
29 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.setupStubbedSubmit;
30 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.verifyMockTx;
31 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.waitForDeletes;
32 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.waitForSubmit;
33
34 import com.google.common.base.Optional;
35 import com.google.common.util.concurrent.Futures;
36 import com.google.common.util.concurrent.SettableFuture;
37 import java.util.Arrays;
38 import java.util.Collections;
39 import java.util.List;
40 import java.util.concurrent.CountDownLatch;
41 import org.junit.Test;
42 import org.mockito.ArgumentCaptor;
43 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
44 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
45 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
46 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnector;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60
61 public class TerminationPointChangeListenerImplTest extends DataTreeChangeListenerBase {
62     @SuppressWarnings("rawtypes")
63     @Test
64     public void testOnNodeConnectorRemoved() {
65
66         NodeKey topoNodeKey = new NodeKey(new NodeId("node1"));
67         TerminationPointKey terminationPointKey = new TerminationPointKey(new TpId("tp1"));
68
69         final InstanceIdentifier<Node> topoNodeII = topologyIID.child(Node.class, topoNodeKey);
70         Node topoNode = new NodeBuilder().withKey(topoNodeKey).build();
71
72         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes
73                 .NodeKey nodeKey = newInvNodeKey(topoNodeKey.getNodeId().getValue());
74
75         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
76                 newInvNodeConnKey(terminationPointKey.getTpId().getValue());
77
78         final InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
79
80         List<Link> linkList = Arrays.asList(
81                 newLink("link1", newSourceTp("tp1"), newDestTp("dest")),
82                 newLink("link2", newSourceTp("source"), newDestTp("tp1")),
83                 newLink("link3", newSourceTp("source2"), newDestTp("dest2")));
84         final Topology topology = new TopologyBuilder().setLink(linkList).build();
85
86         final InstanceIdentifier[] expDeletedIIDs = {
87                 topologyIID.child(Link.class, linkList.get(0).key()),
88                 topologyIID.child(Link.class, linkList.get(1).key()),
89                 topologyIID.child(Node.class, new NodeKey(new NodeId("node1")))
90                         .child(TerminationPoint.class, new TerminationPointKey(new TpId("tp1")))
91             };
92
93         final SettableFuture<Optional<Topology>> readFuture = SettableFuture.create();
94         readFuture.set(Optional.of(topology));
95         ReadWriteTransaction mockTx1 = mock(ReadWriteTransaction.class);
96         doReturn(Futures.makeChecked(readFuture, ReadFailedException.MAPPER)).when(mockTx1)
97                 .read(LogicalDatastoreType.OPERATIONAL, topologyIID);
98
99         SettableFuture<Optional<Node>> readFutureNode = SettableFuture.create();
100         readFutureNode.set(Optional.of(topoNode));
101         doReturn(Futures.makeChecked(readFutureNode, ReadFailedException.MAPPER)).when(mockTx1)
102                 .read(LogicalDatastoreType.OPERATIONAL, topoNodeII);
103
104         final CountDownLatch submitLatch1 = setupStubbedSubmit(mockTx1);
105
106         int expDeleteCalls = expDeletedIIDs.length;
107         CountDownLatch deleteLatch = new CountDownLatch(expDeleteCalls);
108         ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
109                 ArgumentCaptor.forClass(InstanceIdentifier.class);
110         setupStubbedDeletes(mockTx1, deletedLinkIDs, deleteLatch);
111
112         doReturn(mockTx1).when(mockTxChain).newReadWriteTransaction();
113
114         DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, invNodeConnID);
115         terminationPointListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
116
117         waitForSubmit(submitLatch1);
118
119         setReadFutureAsync(topology, readFuture);
120
121         waitForDeletes(expDeleteCalls, deleteLatch);
122
123         assertDeletedIDs(expDeletedIIDs, deletedLinkIDs);
124
125         verifyMockTx(mockTx1);
126     }
127
128     @SuppressWarnings("rawtypes")
129     @Test
130     public void testOnNodeConnectorRemovedWithNoTopology() {
131
132         NodeKey topoNodeKey = new NodeKey(new NodeId("node1"));
133         TerminationPointKey terminationPointKey = new TerminationPointKey(new TpId("tp1"));
134
135         InstanceIdentifier<Node> topoNodeII = topologyIID.child(Node.class, topoNodeKey);
136         Node topoNode = new NodeBuilder().withKey(topoNodeKey).build();
137
138         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
139                 nodeKey = newInvNodeKey(topoNodeKey.getNodeId().getValue());
140
141         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
142                 newInvNodeConnKey(terminationPointKey.getTpId().getValue());
143
144         final InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
145
146         final InstanceIdentifier[] expDeletedIIDs = {
147                 topologyIID.child(Node.class, new NodeKey(new NodeId("node1")))
148                         .child(TerminationPoint.class, new TerminationPointKey(new TpId("tp1")))
149             };
150
151         ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
152         doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockTx)
153                 .read(LogicalDatastoreType.OPERATIONAL, topologyIID);
154         final CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
155
156         SettableFuture<Optional<Node>> readFutureNode = SettableFuture.create();
157         readFutureNode.set(Optional.of(topoNode));
158         doReturn(Futures.makeChecked(readFutureNode, ReadFailedException.MAPPER)).when(mockTx)
159                 .read(LogicalDatastoreType.OPERATIONAL, topoNodeII);
160
161         CountDownLatch deleteLatch = new CountDownLatch(1);
162         ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
163                 ArgumentCaptor.forClass(InstanceIdentifier.class);
164         setupStubbedDeletes(mockTx, deletedLinkIDs, deleteLatch);
165
166         doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
167
168         DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, invNodeConnID);
169         terminationPointListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
170
171         waitForSubmit(submitLatch);
172
173         waitForDeletes(1, deleteLatch);
174
175         assertDeletedIDs(expDeletedIIDs, deletedLinkIDs);
176     }
177
178     @Test
179     public void testOnNodeConnectorUpdated() {
180
181         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
182                                                                  nodeKey = newInvNodeKey("node1");
183
184         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
185                 newInvNodeConnKey("tp1");
186
187         InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
188
189         ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
190         CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
191         doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
192
193         DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, invNodeConnID);
194         terminationPointListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
195
196         waitForSubmit(submitLatch);
197
198         ArgumentCaptor<TerminationPoint> mergedNode = ArgumentCaptor.forClass(TerminationPoint.class);
199         NodeId expNodeId = new NodeId("node1");
200         TpId expTpId = new TpId("tp1");
201         InstanceIdentifier<TerminationPoint> expTpPath = topologyIID.child(
202                 Node.class, new NodeKey(expNodeId)).child(TerminationPoint.class,
203                         new TerminationPointKey(expTpId));
204         verify(mockTx).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(expTpPath),
205                 mergedNode.capture(), eq(true));
206         assertEquals("getTpId", expTpId, mergedNode.getValue().getTpId());
207         InventoryNodeConnector augmentation = mergedNode.getValue().augmentation(
208                 InventoryNodeConnector.class);
209         assertNotNull("Missing augmentation", augmentation);
210         assertEquals("getInventoryNodeConnectorRef", new NodeConnectorRef(invNodeConnID),
211                 augmentation.getInventoryNodeConnectorRef());
212     }
213
214     @SuppressWarnings("rawtypes")
215     @Test
216     public void testOnNodeConnectorUpdatedWithLinkStateDown() {
217
218         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
219                                                                  nodeKey = newInvNodeKey("node1");
220
221         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
222                 newInvNodeConnKey("tp1");
223
224         final InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
225
226         List<Link> linkList = Arrays.asList(newLink("link1", newSourceTp("tp1"), newDestTp("dest")));
227         Topology topology = new TopologyBuilder().setLink(linkList).build();
228
229         ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
230         doReturn(Futures.immediateCheckedFuture(Optional.of(topology))).when(mockTx)
231                 .read(LogicalDatastoreType.OPERATIONAL, topologyIID);
232         setupStubbedSubmit(mockTx);
233
234         CountDownLatch deleteLatch = new CountDownLatch(1);
235         ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
236                 ArgumentCaptor.forClass(InstanceIdentifier.class);
237         setupStubbedDeletes(mockTx, deletedLinkIDs, deleteLatch);
238
239         doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
240
241         DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, invNodeConnID);
242         when(dataTreeModification.getRootNode().getDataAfter())
243                 .thenReturn(provideFlowCapableNodeConnector(true, false));
244         terminationPointListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
245
246         waitForDeletes(1, deleteLatch);
247
248         InstanceIdentifier<TerminationPoint> expTpPath = topologyIID.child(
249                 Node.class, new NodeKey(new NodeId("node1"))).child(TerminationPoint.class,
250                         new TerminationPointKey(new TpId("tp1")));
251
252         verify(mockTx).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(expTpPath),
253                 any(TerminationPoint.class), eq(true));
254
255         assertDeletedIDs(new InstanceIdentifier[]{topologyIID.child(Link.class,
256                 linkList.get(0).key())}, deletedLinkIDs);
257     }
258
259     @SuppressWarnings("rawtypes")
260     @Test
261     public void testOnNodeConnectorUpdatedWithPortDown() {
262
263         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
264                                                                  nodeKey = newInvNodeKey("node1");
265
266         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
267                 newInvNodeConnKey("tp1");
268
269         final InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
270
271         List<Link> linkList = Arrays.asList(newLink("link1", newSourceTp("tp1"), newDestTp("dest")));
272         Topology topology = new TopologyBuilder().setLink(linkList).build();
273
274         ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
275         doReturn(Futures.immediateCheckedFuture(Optional.of(topology))).when(mockTx)
276                 .read(LogicalDatastoreType.OPERATIONAL, topologyIID);
277         setupStubbedSubmit(mockTx);
278
279         CountDownLatch deleteLatch = new CountDownLatch(1);
280         ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
281                 ArgumentCaptor.forClass(InstanceIdentifier.class);
282         setupStubbedDeletes(mockTx, deletedLinkIDs, deleteLatch);
283
284         doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
285
286         DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, invNodeConnID);
287         when(dataTreeModification.getRootNode().getDataAfter())
288                 .thenReturn(provideFlowCapableNodeConnector(false, true));
289         terminationPointListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
290
291         waitForDeletes(1, deleteLatch);
292
293         InstanceIdentifier<TerminationPoint> expTpPath = topologyIID.child(
294                 Node.class, new NodeKey(new NodeId("node1"))).child(TerminationPoint.class,
295                         new TerminationPointKey(new TpId("tp1")));
296
297         verify(mockTx).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(expTpPath),
298                 any(TerminationPoint.class), eq(true));
299
300         assertDeletedIDs(new InstanceIdentifier[]{topologyIID.child(Link.class,
301                 linkList.get(0).key())}, deletedLinkIDs);
302     }
303 }