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