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