Switch to MD-SAL APIs
[openflowplugin.git] / applications / topology-manager / src / test / java / org / opendaylight / openflowplugin / applications / topology / manager / NodeChangeListenerImplTest.java
1 /*
2  * Copyright (c) 2015 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.eq;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.verify;
16 import static org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType.DELETE;
17 import static org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType.WRITE;
18 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.assertDeletedIDs;
19 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newDestNode;
20 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newInvNodeKey;
21 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newLink;
22 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.newSourceNode;
23 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.setReadFutureAsync;
24 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.setupStubbedDeletes;
25 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.setupStubbedSubmit;
26 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.verifyMockTx;
27 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.waitForDeletes;
28 import static org.opendaylight.openflowplugin.applications.topology.manager.TestUtils.waitForSubmit;
29
30 import com.google.common.util.concurrent.SettableFuture;
31 import java.util.Arrays;
32 import java.util.Collections;
33 import java.util.List;
34 import java.util.Optional;
35 import java.util.concurrent.CountDownLatch;
36 import org.junit.Test;
37 import org.mockito.ArgumentCaptor;
38 import org.opendaylight.mdsal.binding.api.DataTreeModification;
39 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
40 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.topology.inventory.rev131030.InventoryNode;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
51 import org.opendaylight.yangtools.util.concurrent.FluentFutures;
52 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53
54 public class NodeChangeListenerImplTest extends DataTreeChangeListenerBase {
55     @SuppressWarnings({ "rawtypes" })
56     @Test
57     public void testOnNodeRemoved() {
58         NodeKey topoNodeKey = new NodeKey(new NodeId("node1"));
59         final InstanceIdentifier<Node> topoNodeII = topologyIID.child(Node.class, topoNodeKey);
60         Node topoNode = new NodeBuilder().withKey(topoNodeKey).build();
61
62         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819
63                 .nodes.NodeKey nodeKey = newInvNodeKey(topoNodeKey.getNodeId().getValue());
64         final InstanceIdentifier<?> invNodeID = InstanceIdentifier.create(Nodes.class).child(
65                 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
66                 nodeKey);
67
68         List<Link> linkList = Arrays.asList(
69                 newLink("link1", newSourceNode("node1"), newDestNode("dest")),
70                 newLink("link2", newSourceNode("source"), newDestNode("node1")),
71                 newLink("link2", newSourceNode("source2"), newDestNode("dest2")));
72         final Topology topology = new TopologyBuilder().setLink(linkList).build();
73
74         final InstanceIdentifier[] expDeletedIIDs = {
75                 topologyIID.child(Link.class, linkList.get(0).key()),
76                 topologyIID.child(Link.class, linkList.get(1).key()),
77                 topologyIID.child(Node.class, new NodeKey(new NodeId("node1")))
78             };
79
80         SettableFuture<Optional<Topology>> readFuture = SettableFuture.create();
81         readFuture.set(Optional.of(topology));
82         ReadWriteTransaction mockTx1 = mock(ReadWriteTransaction.class);
83         doReturn(readFuture).when(mockTx1).read(LogicalDatastoreType.OPERATIONAL, topologyIID);
84
85         SettableFuture<Optional<Node>> readFutureNode = SettableFuture.create();
86         readFutureNode.set(Optional.of(topoNode));
87         doReturn(readFutureNode).when(mockTx1).read(LogicalDatastoreType.OPERATIONAL, topoNodeII);
88
89         final CountDownLatch submitLatch1 = setupStubbedSubmit(mockTx1);
90
91         int expDeleteCalls = expDeletedIIDs.length;
92         CountDownLatch deleteLatch = new CountDownLatch(expDeleteCalls);
93         ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
94                 ArgumentCaptor.forClass(InstanceIdentifier.class);
95         setupStubbedDeletes(mockTx1, deletedLinkIDs, deleteLatch);
96
97         doReturn(mockTx1).when(mockTxChain).newReadWriteTransaction();
98
99         DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, invNodeID);
100         nodeChangeListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
101
102         waitForSubmit(submitLatch1);
103
104         setReadFutureAsync(topology, readFuture);
105
106         waitForDeletes(expDeleteCalls, deleteLatch);
107
108         assertDeletedIDs(expDeletedIIDs, deletedLinkIDs);
109
110         verifyMockTx(mockTx1);
111     }
112
113     @SuppressWarnings({ "rawtypes" })
114     @Test
115     public void testOnNodeRemovedWithNoTopology() {
116
117         NodeKey topoNodeKey = new NodeKey(new NodeId("node1"));
118         InstanceIdentifier<Node> topoNodeII = topologyIID.child(Node.class, topoNodeKey);
119         Node topoNode = new NodeBuilder().withKey(topoNodeKey).build();
120
121         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
122                 nodeKey = newInvNodeKey(topoNodeKey.getNodeId().getValue());
123         final InstanceIdentifier<?> invNodeID = InstanceIdentifier.create(Nodes.class).child(
124                 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
125                 nodeKey);
126
127         final InstanceIdentifier[] expDeletedIIDs = {
128                 topologyIID.child(Node.class, new NodeKey(new NodeId("node1")))
129             };
130
131         ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
132         doReturn(FluentFutures.immediateFluentFuture(Optional.empty())).when(mockTx)
133                 .read(LogicalDatastoreType.OPERATIONAL, topologyIID);
134         final CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
135
136         doReturn(FluentFutures.immediateFluentFuture(Optional.of(topoNode))).when(mockTx)
137             .read(LogicalDatastoreType.OPERATIONAL, topoNodeII);
138
139         CountDownLatch deleteLatch = new CountDownLatch(1);
140         ArgumentCaptor<InstanceIdentifier> deletedLinkIDs =
141                 ArgumentCaptor.forClass(InstanceIdentifier.class);
142         setupStubbedDeletes(mockTx, deletedLinkIDs, deleteLatch);
143
144         doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
145
146         DataTreeModification dataTreeModification = setupDataTreeChange(DELETE, invNodeID);
147         nodeChangeListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
148
149         waitForSubmit(submitLatch);
150
151         waitForDeletes(1, deleteLatch);
152
153         assertDeletedIDs(expDeletedIIDs, deletedLinkIDs);
154     }
155
156     @Test
157     public void testOnNodeAdded() {
158
159         org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey
160                                                             nodeKey = newInvNodeKey("node1");
161         InstanceIdentifier<?> invNodeID = InstanceIdentifier.create(Nodes.class).child(
162                 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class,
163                 nodeKey);
164
165         ReadWriteTransaction mockTx = mock(ReadWriteTransaction.class);
166         CountDownLatch submitLatch = setupStubbedSubmit(mockTx);
167         doReturn(mockTx).when(mockTxChain).newReadWriteTransaction();
168
169         DataTreeModification dataTreeModification = setupDataTreeChange(WRITE, invNodeID);
170         nodeChangeListener.onDataTreeChanged(Collections.singleton(dataTreeModification));
171
172         waitForSubmit(submitLatch);
173
174         ArgumentCaptor<Node> mergedNode = ArgumentCaptor.forClass(Node.class);
175         NodeId expNodeId = new NodeId("node1");
176         verify(mockTx).merge(eq(LogicalDatastoreType.OPERATIONAL), eq(topologyIID.child(Node.class,
177                 new NodeKey(expNodeId))), mergedNode.capture(), eq(true));
178         assertEquals("getNodeId", expNodeId, mergedNode.getValue().getNodeId());
179         InventoryNode augmentation = mergedNode.getValue().augmentation(InventoryNode.class);
180         assertNotNull("Missing augmentation", augmentation);
181         assertEquals("getInventoryNodeRef", new NodeRef(invNodeID), augmentation.getInventoryNodeRef());
182     }
183
184 }