2 * Copyright (c) 2015 Cisco Systems, 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
8 package org.opendaylight.openflowplugin.applications.topology.manager;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Matchers.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.opendaylight.openflowplugin.applications.topology.manager.TestUtils.*;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNodeConnector;
21 import org.opendaylight.yangtools.yang.binding.DataObject;
23 import com.google.common.base.Optional;
24 import com.google.common.util.concurrent.Futures;
25 import com.google.common.util.concurrent.SettableFuture;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.concurrent.CountDownLatch;
30 import org.junit.Test;
31 import org.mockito.ArgumentCaptor;
32 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
33 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
34 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
45 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 public class TerminationPointChangeListenerImplTest extends DataChangeListenerBase{
52 @SuppressWarnings("rawtypes")
54 public void testOnNodeConnectorRemoved() {
56 NodeKey topoNodeKey = new NodeKey(new NodeId("node1"));
57 TerminationPointKey terminationPointKey = new TerminationPointKey(new TpId("tp1"));
59 InstanceIdentifier<Node> topoNodeII = topologyIID.child(Node.class, topoNodeKey);
60 Node topoNode = new NodeBuilder().setKey(topoNodeKey).build();
62 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
63 nodeKey = newInvNodeKey(topoNodeKey.getNodeId().getValue());
65 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
66 newInvNodeConnKey(terminationPointKey.getTpId().getValue());
68 InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
70 List<Link> linkList = Arrays.asList(
71 newLink("link1", newSourceTp("tp1"), newDestTp("dest")),
72 newLink("link2", newSourceTp("source"), newDestTp("tp1")),
73 newLink("link3", newSourceTp("source2"), newDestTp("dest2")));
74 final Topology topology = new TopologyBuilder().setLink(linkList).build();
76 InstanceIdentifier[] expDeletedIIDs = {
77 topologyIID.child(Link.class, linkList.get(0).getKey()),
78 topologyIID.child(Link.class, linkList.get(1).getKey()),
79 topologyIID.child(Node.class, new NodeKey(new NodeId("node1")))
80 .child(TerminationPoint.class, new TerminationPointKey(new TpId("tp1")))
83 final SettableFuture<Optional<Topology>> readFuture = SettableFuture.create();
84 readFuture.set(Optional.of(topology));
85 ReadWriteTransaction mockTx1 = mock(ReadWriteTransaction.class);
86 doReturn(Futures.makeChecked(readFuture, ReadFailedException.MAPPER)).when(mockTx1)
87 .read(LogicalDatastoreType.OPERATIONAL, topologyIID);
89 SettableFuture<Optional<Node>> readFutureNode = SettableFuture.create();
90 readFutureNode.set(Optional.of(topoNode));
91 doReturn(Futures.makeChecked(readFutureNode, ReadFailedException.MAPPER)).when(mockTx1)
92 .read(LogicalDatastoreType.OPERATIONAL, topoNodeII);
94 CountDownLatch submitLatch1 = setupStubbedSubmit(mockTx1);
96 int expDeleteCalls = expDeletedIIDs.length;
97 CountDownLatch deleteLatch = new CountDownLatch(expDeleteCalls);
98 ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
99 ArgumentCaptor.forClass(InstanceIdentifier.class);
100 setupStubbedDeletes(mockTx1, deletedLinkIDs, deleteLatch);
102 doReturn(mockTx1).when(mockTxChain).newReadWriteTransaction();
104 mockDataChangeListener(null, null, Collections.singleton(invNodeConnID));
105 terminationPointListener.onDataChanged(mockedDataChangeListener);
107 waitForSubmit(submitLatch1);
109 setReadFutureAsync(topology, readFuture);
111 waitForDeletes(expDeleteCalls, deleteLatch);
113 assertDeletedIDs(expDeletedIIDs, deletedLinkIDs);
115 verifyMockTx(mockTx1);
118 @SuppressWarnings("rawtypes")
120 public void testOnNodeConnectorRemovedWithNoTopology() {
122 NodeKey topoNodeKey = new NodeKey(new NodeId("node1"));
123 TerminationPointKey terminationPointKey = new TerminationPointKey(new TpId("tp1"));
125 InstanceIdentifier<Node> topoNodeII = topologyIID.child(Node.class, topoNodeKey);
126 Node topoNode = new NodeBuilder().setKey(topoNodeKey).build();
128 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
129 nodeKey = newInvNodeKey(topoNodeKey.getNodeId().getValue());
131 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
132 newInvNodeConnKey(terminationPointKey.getTpId().getValue());
134 InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
136 InstanceIdentifier[] expDeletedIIDs = {
137 topologyIID.child(Node.class, new NodeKey(new NodeId("node1")))
138 .child(TerminationPoint.class, new TerminationPointKey(new TpId("tp1")))
141 ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
142 doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(mockTx)
143 .read(LogicalDatastoreType.OPERATIONAL, topologyIID);
144 CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
146 SettableFuture<Optional<Node>> readFutureNode = SettableFuture.create();
147 readFutureNode.set(Optional.of(topoNode));
148 doReturn(Futures.makeChecked(readFutureNode, ReadFailedException.MAPPER)).when(mockTx)
149 .read(LogicalDatastoreType.OPERATIONAL, topoNodeII);
151 CountDownLatch deleteLatch = new CountDownLatch(1);
152 ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
153 ArgumentCaptor.forClass(InstanceIdentifier.class);
154 setupStubbedDeletes(mockTx, deletedLinkIDs, deleteLatch);
156 doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
158 mockDataChangeListener(null, null, Collections.singleton(invNodeConnID));
159 terminationPointListener.onDataChanged(mockedDataChangeListener);
161 waitForSubmit(submitLatch);
163 waitForDeletes(1, deleteLatch);
165 assertDeletedIDs(expDeletedIIDs, deletedLinkIDs);
169 public void testOnNodeConnectorUpdated() {
171 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
172 nodeKey = newInvNodeKey("node1");
174 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
175 newInvNodeConnKey("tp1");
177 InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
179 ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
180 CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
181 doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
183 mockDataChangeListener(Collections.<InstanceIdentifier<?>, DataObject> singletonMap(
184 invNodeConnID, null), null, null);
185 terminationPointListener.onDataChanged(mockedDataChangeListener);
187 waitForSubmit(submitLatch);
189 ArgumentCaptor<TerminationPoint> mergedNode = ArgumentCaptor.forClass(TerminationPoint.class);
190 NodeId expNodeId = new NodeId("node1");
191 TpId expTpId = new TpId("tp1");
192 InstanceIdentifier<TerminationPoint> expTpPath = topologyIID.child(
193 Node.class, new NodeKey(expNodeId)).child(TerminationPoint.class,
194 new TerminationPointKey(expTpId));
195 verify(mockTx).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(expTpPath),
196 mergedNode.capture(), eq(true));
197 assertEquals("getTpId", expTpId, mergedNode.getValue().getTpId());
198 InventoryNodeConnector augmentation = mergedNode.getValue().getAugmentation(
199 InventoryNodeConnector.class);
200 assertNotNull("Missing augmentation", augmentation);
201 assertEquals("getInventoryNodeConnectorRef", new NodeConnectorRef(invNodeConnID),
202 augmentation.getInventoryNodeConnectorRef());
205 @SuppressWarnings("rawtypes")
207 public void testOnNodeConnectorUpdatedWithLinkStateDown() {
209 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
210 nodeKey = newInvNodeKey("node1");
212 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
213 newInvNodeConnKey("tp1");
215 InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
217 List<Link> linkList = Arrays.asList(newLink("link1", newSourceTp("tp1"), newDestTp("dest")));
218 Topology topology = new TopologyBuilder().setLink(linkList).build();
220 ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
221 doReturn(Futures.immediateCheckedFuture(Optional.of(topology))).when(mockTx)
222 .read(LogicalDatastoreType.OPERATIONAL, topologyIID);
223 setupStubbedSubmit(mockTx);
225 CountDownLatch deleteLatch = new CountDownLatch(1);
226 ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
227 ArgumentCaptor.forClass(InstanceIdentifier.class);
228 setupStubbedDeletes(mockTx, deletedLinkIDs, deleteLatch);
230 doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
232 mockDataChangeListener(Collections.<InstanceIdentifier<?>, DataObject> singletonMap(
233 invNodeConnID, provideFlowCapableNodeConnector(true, false)), null, null);
234 terminationPointListener.onDataChanged(mockedDataChangeListener);
236 waitForDeletes(1, deleteLatch);
238 InstanceIdentifier<TerminationPoint> expTpPath = topologyIID.child(
239 Node.class, new NodeKey(new NodeId("node1"))).child(TerminationPoint.class,
240 new TerminationPointKey(new TpId("tp1")));
242 verify(mockTx).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(expTpPath),
243 any(TerminationPoint.class), eq(true));
245 assertDeletedIDs(new InstanceIdentifier[]{topologyIID.child(Link.class,
246 linkList.get(0).getKey())}, deletedLinkIDs);
250 @SuppressWarnings("rawtypes")
252 public void testOnNodeConnectorUpdatedWithPortDown() {
254 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
255 nodeKey = newInvNodeKey("node1");
257 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnectorKey ncKey =
258 newInvNodeConnKey("tp1");
260 InstanceIdentifier<?> invNodeConnID = newNodeConnID(nodeKey, ncKey);
262 List<Link> linkList = Arrays.asList(newLink("link1", newSourceTp("tp1"), newDestTp("dest")));
263 Topology topology = new TopologyBuilder().setLink(linkList).build();
265 ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
266 doReturn(Futures.immediateCheckedFuture(Optional.of(topology))).when(mockTx)
267 .read(LogicalDatastoreType.OPERATIONAL, topologyIID);
268 setupStubbedSubmit(mockTx);
270 CountDownLatch deleteLatch = new CountDownLatch(1);
271 ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
272 ArgumentCaptor.forClass(InstanceIdentifier.class);
273 setupStubbedDeletes(mockTx, deletedLinkIDs, deleteLatch);
275 doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
277 mockDataChangeListener(Collections.<InstanceIdentifier<?>, DataObject> singletonMap(
278 invNodeConnID, provideFlowCapableNodeConnector(false, true)), null, null);
279 terminationPointListener.onDataChanged(mockedDataChangeListener);
281 waitForDeletes(1, deleteLatch);
283 InstanceIdentifier<TerminationPoint> expTpPath = topologyIID.child(
284 Node.class, new NodeKey(new NodeId("node1"))).child(TerminationPoint.class,
285 new TerminationPointKey(new TpId("tp1")));
287 verify(mockTx).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(expTpPath),
288 any(TerminationPoint.class), eq(true));
290 assertDeletedIDs(new InstanceIdentifier[]{topologyIID.child(Link.class,
291 linkList.get(0).getKey())}, deletedLinkIDs);