Migrate netconf to MD-SAL APIs
[netconf.git] / netconf / sal-netconf-connector / src / test / java / org / opendaylight / netconf / sal / connect / netconf / sal / NetconfDeviceTopologyAdapterTest.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.netconf.sal.connect.netconf.sal;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.Mockito.doNothing;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.times;
15 import static org.mockito.Mockito.verify;
16 import static org.opendaylight.mdsal.common.api.CommitInfo.emptyFluentFuture;
17
18 import java.net.InetSocketAddress;
19 import java.util.Optional;
20 import java.util.concurrent.TimeUnit;
21 import org.awaitility.Awaitility;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.mockito.Mock;
25 import org.mockito.MockitoAnnotations;
26 import org.opendaylight.mdsal.binding.api.DataBroker;
27 import org.opendaylight.mdsal.binding.api.Transaction;
28 import org.opendaylight.mdsal.binding.api.TransactionChain;
29 import org.opendaylight.mdsal.binding.api.TransactionChainListener;
30 import org.opendaylight.mdsal.binding.api.WriteTransaction;
31 import org.opendaylight.mdsal.binding.dom.adapter.test.ConcurrentDataBrokerTestCustomizer;
32 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
33 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
34 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
35 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
36 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.opendaylight.yangtools.yang.common.QName;
44 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
45 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
46 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
47 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
48 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
49
50 public class NetconfDeviceTopologyAdapterTest {
51
52     private final RemoteDeviceId id = new RemoteDeviceId("test", new InetSocketAddress("localhost", 22));
53
54     @Mock
55     private WriteTransaction writeTx;
56     @Mock
57     private TransactionChain txChain;
58     @Mock
59     private NetconfNode data;
60
61     private final String txIdent = "test transaction";
62
63     private SchemaContext schemaContext = null;
64     private final String sessionIdForReporting = "netconf-test-session1";
65
66     private TransactionChain transactionChain;
67
68     private DataBroker dataBroker;
69
70     private DOMDataBroker domDataBroker;
71
72     @Before
73     public void setUp() throws Exception {
74         MockitoAnnotations.initMocks(this);
75         doReturn(writeTx).when(txChain).newWriteOnlyTransaction();
76         doNothing().when(writeTx)
77                 .put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(NetconfNode.class));
78         doNothing().when(writeTx)
79                 .merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(NetconfNode.class));
80
81         doReturn(txIdent).when(writeTx).getIdentifier();
82
83         this.schemaContext = YangParserTestUtils.parseYangResources(NetconfDeviceTopologyAdapterTest.class,
84             "/schemas/network-topology@2013-10-21.yang", "/schemas/ietf-inet-types@2013-07-15.yang",
85             "/schemas/yang-ext.yang", "/schemas/netconf-node-topology.yang",
86             "/schemas/network-topology-augment-test@2016-08-08.yang");
87         schemaContext.getModules();
88
89         ConcurrentDataBrokerTestCustomizer customizer = new ConcurrentDataBrokerTestCustomizer(true);
90         domDataBroker = customizer.getDOMDataBroker();
91         dataBroker = customizer.createDataBroker();
92         customizer.updateSchema(schemaContext);
93
94         transactionChain = dataBroker.createTransactionChain(new TransactionChainListener() {
95             @Override
96             public void onTransactionChainFailed(final TransactionChain chain, final Transaction transaction,
97                     final Throwable cause) {
98
99             }
100
101             @Override
102             public void onTransactionChainSuccessful(final TransactionChain chain) {
103
104             }
105         });
106
107     }
108
109     @Test
110     public void testFailedDevice() throws Exception {
111
112         doReturn(emptyFluentFuture()).when(writeTx).commit();
113         NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, txChain);
114         adapter.setDeviceAsFailed(null);
115
116         verify(txChain, times(2)).newWriteOnlyTransaction();
117         verify(writeTx, times(1))
118                 .put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
119         adapter.close();
120
121         adapter = new NetconfDeviceTopologyAdapter(id, transactionChain); //not a mock
122         adapter.setDeviceAsFailed(null);
123
124         Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> {
125             Optional<NetconfNode> netconfNode = dataBroker.newReadWriteTransaction()
126                     .read(LogicalDatastoreType.OPERATIONAL, id.getTopologyBindingPath().augmentation(NetconfNode.class))
127                     .get(5, TimeUnit.SECONDS);
128             return netconfNode.isPresent() && netconfNode.get().getConnectionStatus()
129                     == NetconfNodeConnectionStatus.ConnectionStatus.UnableToConnect;
130         });
131     }
132
133     @Test
134     public void testDeviceUpdate() throws Exception {
135         doReturn(emptyFluentFuture()).when(writeTx).commit();
136
137         NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, txChain);
138         adapter.updateDeviceData(true, new NetconfDeviceCapabilities());
139
140         verify(txChain, times(2)).newWriteOnlyTransaction();
141         verify(writeTx, times(1))
142                 .put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
143         verify(writeTx, times(1)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class));
144
145     }
146
147     @Test
148     public void testDeviceAugmentedNodePresence() throws Exception {
149
150         Integer dataTestId = 474747;
151
152         NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, transactionChain);
153
154         QName netconfTestLeafQname = QName.create(
155                 "urn:TBD:params:xml:ns:yang:network-topology-augment-test", "2016-08-08", "test-id").intern();
156
157         YangInstanceIdentifier pathToAugmentedLeaf = YangInstanceIdentifier.builder().node(NetworkTopology.QNAME)
158                 .node(Topology.QNAME)
159                 .nodeWithKey(Topology.QNAME, QName.create(Topology.QNAME, "topology-id"), "topology-netconf")
160                 .node(Node.QNAME)
161                 .nodeWithKey(Node.QNAME, QName.create(Node.QNAME, "node-id"), "test")
162                 .node(netconfTestLeafQname).build();
163
164         NormalizedNode<?, ?> augmentNode = ImmutableLeafNodeBuilder.create().withValue(dataTestId)
165                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(netconfTestLeafQname)).build();
166
167         DOMDataTreeWriteTransaction wtx =  domDataBroker.newWriteOnlyTransaction();
168         wtx.put(LogicalDatastoreType.OPERATIONAL, pathToAugmentedLeaf, augmentNode);
169         wtx.commit().get(5, TimeUnit.SECONDS);
170
171         adapter.updateDeviceData(true, new NetconfDeviceCapabilities());
172         Optional<NormalizedNode<?, ?>> testNode = domDataBroker.newReadOnlyTransaction()
173                 .read(LogicalDatastoreType.OPERATIONAL, pathToAugmentedLeaf).get(2, TimeUnit.SECONDS);
174
175         assertEquals("Augmented node data should be still present after device update.", true, testNode.isPresent());
176         assertEquals("Augmented data should be the same as before update node.", dataTestId, testNode.get().getValue());
177
178         adapter.setDeviceAsFailed(null);
179         testNode = domDataBroker.newReadOnlyTransaction()
180                 .read(LogicalDatastoreType.OPERATIONAL, pathToAugmentedLeaf).get(2, TimeUnit.SECONDS);
181
182         assertEquals("Augmented node data should be still present after device failed.", true, testNode.isPresent());
183         assertEquals("Augmented data should be the same as before failed device.",
184                 dataTestId, testNode.get().getValue());
185     }
186
187     @Test
188     public void testRemoveDeviceConfiguration() throws Exception {
189         doReturn(emptyFluentFuture()).when(writeTx).commit();
190
191         NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, txChain);
192         adapter.close();
193
194         verify(txChain, times(2)).newWriteOnlyTransaction();
195         verify(writeTx).delete(LogicalDatastoreType.OPERATIONAL, id.getTopologyBindingPath());
196         verify(writeTx, times(2)).commit();
197     }
198
199 }