fix for netconf model change
[groupbasedpolicy.git] / renderers / ios-xe / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ios_xe_provider / impl / manager / NodeManagerTest.java
1 /*
2  * Copyright (c) 2016 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.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.mockito.Matchers.any;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.when;
17 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connected;
18 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connecting;
19 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.UnableToConnect;
20
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.List;
25
26 import javax.annotation.Nonnull;
27
28 import org.junit.Before;
29 import org.junit.Test;
30 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
31 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
32 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
33 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
34 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
35 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
36 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
37 import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodes;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
60
61 import com.google.common.base.Optional;
62 import com.google.common.util.concurrent.CheckedFuture;
63
64
65 public class NodeManagerTest extends CustomDataBrokerTest {
66
67     private final NodeId NODE_NAME = new NodeId("testNode");
68     private final TopologyId TOPOLOGY_ID = new TopologyId("topology-netconf");
69     private final Ipv4Address IPv4_ADDRESS = new Ipv4Address("174.25.75.11");
70     private NodeManager nodeManager;
71     private DataBroker dataBroker;
72
73     @Nonnull
74     @Override
75     public Collection<java.lang.Class<?>> getClassesFromModules() {
76         return Arrays.asList(Renderers.class, NetworkTopology.class, NetconfNode.class);
77     }
78
79     @Before
80     public void init() {
81         dataBroker = getDataBroker();
82         BindingAwareBroker.ProviderContext context = mock(BindingAwareBroker.ProviderContext.class);
83         MountPointService mountPointService = mock(MountPointService.class);
84         when(context.getSALService(any())).thenReturn(mountPointService);
85         nodeManager = new NodeManager(dataBroker, context);
86     }
87
88     @Test
89     public void testRegisterNewNode_connectingCase() throws Exception {
90         Node testNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
91         nodeManager.syncNodes(testNode, null);
92         List<RendererNode> result = rendererNodesReader();
93         assertTrue(result.isEmpty());
94     }
95
96     // Create Cases
97
98     @Test
99     public void testRegisterNewNode_connectedCaseNoIpAddress() throws Exception {
100         Node testNode = createNode(Connected, null, NODE_NAME, Capabilities.None);
101         nodeManager.syncNodes(testNode, null);
102         List<RendererNode> result = rendererNodesReader();
103         assertTrue(result.isEmpty());
104     }
105
106     @Test
107     public void testRegisterNewNode_connectedCaseNullCapabilities() throws Exception {
108         Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.None);
109         nodeManager.syncNodes(testNode, null);
110         List<RendererNode> result = rendererNodesReader();
111         assertTrue(result.isEmpty());
112     }
113
114     @Test
115     public void testRegisterNewNode_connectedCasePartialCapabilities() throws Exception {
116         Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
117         nodeManager.syncNodes(testNode, null);
118         List<RendererNode> result = rendererNodesReader();
119         assertTrue(result.isEmpty());
120     }
121
122     @Test
123     public void testRegisterNewNode_connectedCaseFullCapabilities() throws Exception {
124         Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
125         nodeManager.syncNodes(testNode, null);
126         List<RendererNode> result = rendererNodesReader();
127         assertNotNull(result);
128         assertTrue(result.size() == 1);
129     }
130
131     @Test
132     public void testRegisterNewNode_unableToConnectCase() throws Exception {
133         Node testNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
134         nodeManager.syncNodes(testNode, null);
135         List<RendererNode> result = rendererNodesReader();
136         assertTrue(result.isEmpty());
137     }
138
139     @Test
140     public void testUpdateNode_fromConnectingToConnected() throws Exception {
141         Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
142         Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
143         nodeManager.syncNodes(oldNode, null);
144         List<RendererNode> result = rendererNodesReader();
145         assertTrue(result.isEmpty());
146         nodeManager.syncNodes(newNode, oldNode);
147         result = rendererNodesReader();
148         assertNotNull(result);
149         assertTrue(result.size() == 1);
150     }
151
152     // Update Cases
153
154     @Test
155     public void testUpdateNode_fromConnectingToUnableToConnect() throws Exception {
156         Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
157         Node newNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
158         nodeManager.syncNodes(oldNode, null);
159         List<RendererNode> result = rendererNodesReader();
160         assertTrue(result.isEmpty());
161         nodeManager.syncNodes(newNode, oldNode);
162         result = rendererNodesReader();
163         assertTrue(result.isEmpty());
164     }
165
166     @Test
167     public void testUpdateNode_fromConnectedToConnecting() throws Exception {
168         Node oldNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
169         Node newNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
170         nodeManager.syncNodes(oldNode, null);
171         List<RendererNode> result = rendererNodesReader();
172         assertNotNull(result);
173         assertTrue(result.size() == 1);
174         nodeManager.syncNodes(newNode, oldNode);
175         result = rendererNodesReader();
176         assertTrue(result.isEmpty());
177     }
178
179     @Test
180     public void testUpdateNode_fromConnectedToUnableToConnect() throws Exception {
181         Node oldNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
182         Node newNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
183         nodeManager.syncNodes(oldNode, null);
184         List<RendererNode> result = rendererNodesReader();
185         assertNotNull(result);
186         assertTrue(result.size() == 1);
187         nodeManager.syncNodes(newNode, oldNode);
188         result = rendererNodesReader();
189         assertTrue(result.isEmpty());
190     }
191
192     @Test
193     public void testUpdateNode_fromUnableToConnectToConnecting() throws Exception {
194         Node oldNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
195         Node newNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
196         nodeManager.syncNodes(oldNode, null);
197         List<RendererNode> result = rendererNodesReader();
198         assertTrue(result.isEmpty());
199         nodeManager.syncNodes(newNode, oldNode);
200         result = rendererNodesReader();
201         assertTrue(result.isEmpty());
202     }
203
204     @Test
205     public void testUpdateNode_fromUnableToConnectToConnected() throws Exception {
206         Node oldNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
207         Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
208         nodeManager.syncNodes(oldNode, null);
209         List<RendererNode> result = rendererNodesReader();
210         assertTrue(result.isEmpty());
211         nodeManager.syncNodes(newNode, oldNode);
212         result = rendererNodesReader();
213         assertNotNull(result);
214         assertTrue(result.size() == 1);
215     }
216
217     @Test
218     public void testUpdateNode_advancedCase() throws Exception {
219         Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
220         nodeManager.syncNodes(oldNode, null);
221         List<RendererNode> result = rendererNodesReader();
222         // One node is connecting, partial capabilities = empty list
223         assertTrue(result.isEmpty());
224         Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
225         nodeManager.syncNodes(newNode, oldNode);
226         result = rendererNodesReader();
227         // Update 1.: node is connected, still partial capabilities = empty list
228         assertTrue(result.isEmpty());
229         oldNode = newNode;
230         newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
231         nodeManager.syncNodes(newNode, oldNode);
232         result = rendererNodesReader();
233         // Update 2.: node is connected, full capabilities = 1 entry in list
234         assertNotNull(result);
235         assertTrue(result.size() == 1);
236         oldNode = newNode;
237         newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.None);
238         nodeManager.syncNodes(newNode, oldNode);
239         result = rendererNodesReader();
240         // Update 3.: node remains connected, but without capabilities = empty list
241         assertTrue(result.isEmpty());
242     }
243
244     // Advanced update Case
245
246     @Test
247     public void testRemoveNode() throws Exception {
248         Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
249         nodeManager.syncNodes(testNode, null);
250         List<RendererNode> result = rendererNodesReader();
251         assertNotNull(result);
252         assertTrue(result.size() == 1);
253         nodeManager.syncNodes(null, testNode);
254         result = rendererNodesReader();
255         assertTrue(result.isEmpty());
256     }
257
258     // Remove Case
259
260     @Test
261     public void getNodeManagementIpByMountPointIid_absentNode() {
262         NodeId testNodeId = new NodeId(NODE_NAME);
263         InstanceIdentifier mountpointIid = InstanceIdentifier.builder(NetworkTopology.class)
264                 .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
265                 .child(Node.class, new NodeKey(testNodeId)).build();
266         java.util.Optional<String> optionalIpAddress = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid);
267         assertFalse(optionalIpAddress.isPresent());
268     }
269
270     @Test
271     public void getNodeManagementIpByMountPointIid_ipV4Case() throws Exception {
272         // Put node
273         Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
274         InstanceIdentifier<Node> testNodeIid = InstanceIdentifier.builder(NetworkTopology.class)
275                 .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
276                 .child(Node.class, new NodeKey(testNode.getNodeId())).build();
277         WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
278         wTx.put(LogicalDatastoreType.CONFIGURATION, testNodeIid, testNode, true);
279         wTx.submit().checkedGet();
280
281         java.util.Optional<String> optionalResult = nodeManager.getNodeManagementIpByMountPointIid(testNodeIid);
282         assertTrue(optionalResult.isPresent());
283         assertEquals(IPv4_ADDRESS.getValue(), optionalResult.get());
284     }
285
286     private Node createNode(final NetconfNodeConnectionStatus.ConnectionStatus connectionStatus,
287                             final Ipv4Address ipAddress,
288                             final NodeId nodeName,
289                             final Capabilities choice) {
290         AvailableCapabilities capabilities = null;
291         switch (choice) {
292             case None: {
293                 capabilities = emptyCapabilities();
294                 break;
295             }
296             case Partial: {
297                 capabilities = partialCapabilities();
298                 break;
299             }
300             case Full: {
301                 capabilities = fullCapabilities();
302             }
303         }
304         // Netconf node
305         NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
306         netconfNodeBuilder.setConnectionStatus(connectionStatus)
307                 .setAvailableCapabilities(capabilities)
308                 .setHost(new Host(new IpAddress(ipAddress)));
309         // Node
310         NodeBuilder nodeBuilder = new NodeBuilder();
311         nodeBuilder.setNodeId(new NodeId(nodeName))
312                 .setKey(new NodeKey(new NodeId(nodeName)))
313                 .addAugmentation(NetconfNode.class, netconfNodeBuilder.build());
314         return nodeBuilder.build();
315     }
316
317     // Utility methods
318
319     private List<RendererNode> rendererNodesReader() throws Exception {
320         InstanceIdentifier<Renderers> renderersIid =
321                 InstanceIdentifier.builder(Renderers.class).build();
322         ReadWriteTransaction rwt = dataBroker.newReadWriteTransaction();
323         CheckedFuture<Optional<Renderers>, ReadFailedException> submitFuture =
324                 rwt.read(LogicalDatastoreType.OPERATIONAL, renderersIid);
325         Optional<Renderers> optionalRenderers = submitFuture.checkedGet();
326         if (optionalRenderers.isPresent()) {
327             Renderers renderers = optionalRenderers.get();
328             if (renderers != null && renderers.getRenderer() != null && !renderers.getRenderer().isEmpty()) {
329                 RendererNodes writtenNodes = renderers.getRenderer().get(0).getRendererNodes();
330                 if (writtenNodes != null) {
331                     return writtenNodes.getRendererNode();
332                 }
333             }
334         }
335         return Collections.emptyList();
336     }
337
338     private AvailableCapabilities emptyCapabilities() {
339         AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
340         return availableCapabilitiesBuilder.build();
341     }
342
343     private AvailableCapabilities partialCapabilities() {
344         final AvailableCapability c1 = new AvailableCapabilityBuilder()
345                 .setCapability("(urn:ios?revision=2016-03-08)ned")
346                 .build();
347         final AvailableCapability c2 = new AvailableCapabilityBuilder()
348                 .setCapability("(http://tail-f.com/yang/common?revision=2015-05-22)tailf-common")
349                 .build();
350         final AvailableCapability c3 = new AvailableCapabilityBuilder()
351                 .setCapability("(http://tail-f.com/yang/common?revision=2015-03-19)tailf-cli-extensions")
352                 .build();
353         AvailableCapability[] capabilityList = {c1, c2, c3};
354         AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
355         availableCapabilitiesBuilder.setAvailableCapability(Arrays.asList(capabilityList));
356         return availableCapabilitiesBuilder.build();
357     }
358
359     private AvailableCapabilities fullCapabilities() {
360         final AvailableCapability c1 = new AvailableCapabilityBuilder()
361                 .setCapability("(urn:ios?revision=2016-03-08)ned")
362                 .build();
363         final AvailableCapability c2 = new AvailableCapabilityBuilder()
364                 .setCapability("(http://tail-f.com/yang/common?revision=2015-05-22)tailf-common")
365                 .build();
366         final AvailableCapability c3 = new AvailableCapabilityBuilder()
367                 .setCapability("(http://tail-f.com/yang/common?revision=2015-03-19)tailf-cli-extensions")
368                 .build();
369         final AvailableCapability c4 = new AvailableCapabilityBuilder()
370                 .setCapability("(http://tail-f.com/yang/common?revision=2013-11-07)tailf-meta-extensions")
371                 .build();
372         final AvailableCapability c5 = new AvailableCapabilityBuilder()
373                 .setCapability("(urn:ietf:params:xml:ns:yang:ietf-yang-types?revision=2013-07-15)ietf-yang-types")
374                 .build();
375         final AvailableCapability c6 = new AvailableCapabilityBuilder()
376                 .setCapability("(urn:ietf:params:xml:ns:yang:ietf-inet-types?revision=2013-07-15)ietf-inet-types")
377                 .build();
378         AvailableCapability[] capabilityList = {c1, c2, c3, c4, c5, c6};
379         AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
380         availableCapabilitiesBuilder.setAvailableCapability(Arrays.asList(capabilityList));
381         return availableCapabilitiesBuilder.build();
382     }
383
384     private enum Capabilities {None, Partial, Full}
385 }