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