caff132e58dce945f7448e28e72fc2793264e7a3
[netconf.git] / netconf / netconf-topology / src / test / java / org / opendaylight / netconf / topology / impl / NetconfTopologyImplTest.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
9 package org.opendaylight.netconf.topology.impl;
10
11 import static org.mockito.Matchers.any;
12 import static org.mockito.Mockito.doNothing;
13 import static org.mockito.Mockito.mock;
14 import static org.mockito.Mockito.spy;
15 import static org.mockito.Mockito.times;
16 import static org.mockito.Mockito.verify;
17 import static org.mockito.Mockito.when;
18
19 import akka.actor.ActorContext;
20 import com.google.common.collect.Sets;
21 import com.google.common.util.concurrent.Futures;
22 import com.google.common.util.concurrent.ListenableFuture;
23 import com.google.common.util.concurrent.MoreExecutors;
24 import io.netty.util.concurrent.EventExecutor;
25 import io.netty.util.concurrent.Future;
26 import io.netty.util.concurrent.ImmediateEventExecutor;
27 import io.netty.util.concurrent.SucceededFuture;
28 import java.util.Collection;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.mockito.Mock;
32 import org.mockito.MockitoAnnotations;
33 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
34 import org.opendaylight.controller.config.threadpool.ThreadPool;
35 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
36 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
37 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
38 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
39 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
40 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
41 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
42 import org.opendaylight.controller.sal.core.api.Broker;
43 import org.opendaylight.netconf.client.NetconfClientDispatcher;
44 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
45 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
46 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
47 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
48 import org.opendaylight.netconf.topology.SchemaRepositoryProvider;
49 import org.opendaylight.netconf.topology.util.TopologyUtil;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
59 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
60 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
61 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
62 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
63 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
65 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
67 import org.opendaylight.yangtools.yang.binding.DataObject;
68 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
69 import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
70
71 public class NetconfTopologyImplTest {
72
73     private static final NodeId NODE_ID = new NodeId("testing-node");
74     private static final String TOPOLOGY_ID = "testing-topology";
75
76     @Mock
77     private Broker mockedDataBroker;
78
79     @Mock
80     private NetconfClientDispatcher mockedClientDispatcher;
81
82     @Mock
83     private BindingAwareBroker mockedBindingAwareBroker;
84
85     @Mock
86     private EventExecutor mockedEventExecutor;
87
88     @Mock
89     private ScheduledThreadPool mockedKeepaliveExecutor;
90
91     @Mock
92     private ThreadPool mockedProcessingExecutor;
93
94     @Mock
95     private SchemaRepositoryProvider mockedSchemaRepositoryProvider;
96
97
98     private TestingNetconfTopologyImpl topology;
99     private TestingNetconfTopologyImpl spyTopology;
100
101     @Before
102     public void setUp() {
103         MockitoAnnotations.initMocks(this);
104
105         when(mockedSchemaRepositoryProvider.getSharedSchemaRepository()).thenReturn(new SharedSchemaRepository("testingSharedSchemaRepo"));
106         when(mockedProcessingExecutor.getExecutor()).thenReturn(MoreExecutors.newDirectExecutorService());
107         Future future = new SucceededFuture(ImmediateEventExecutor.INSTANCE, new NetconfDeviceCapabilities());
108         when(mockedClientDispatcher.createReconnectingClient(any(NetconfReconnectingClientConfiguration.class))).thenReturn(future);
109
110         topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher, mockedBindingAwareBroker,
111                 mockedDataBroker, mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedSchemaRepositoryProvider);
112
113         spyTopology = spy(topology);
114     }
115
116     @Test(expected = UnsupportedOperationException.class)
117     public void testRegisterMountPointNotSupported() {
118         ActorContext context = mock(ActorContext.class);
119         topology.registerMountPoint(context, NODE_ID);
120     }
121
122     @Test(expected = UnsupportedOperationException.class)
123     public void testUnregisterMountPointNotSupported() {
124         topology.unregisterMountPoint(NODE_ID);
125     }
126
127     @Test(expected = UnsupportedOperationException.class)
128     public void testRegisterConnectionStatusListener() {
129         RemoteDeviceHandler<NetconfSessionPreferences> listener = mock(RemoteDeviceHandler.class);
130         topology.registerConnectionStatusListener(NODE_ID, listener);
131     }
132
133     @Test
134     public void testOnSessionInitiated() {
135         BindingAwareBroker.ProviderContext session = mock(BindingAwareBroker.ProviderContext.class);
136         DataBroker dataBroker = mock(DataBroker.class);
137         when(session.getSALService(DataBroker.class)).thenReturn(dataBroker);
138         WriteTransaction wtx = mock(WriteTransaction.class);
139         when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
140         doNothing().when(wtx).merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class));
141         when(wtx.submit()).thenReturn(Futures.<Void, TransactionCommitFailedException>immediateCheckedFuture(null));
142         topology.onSessionInitiated(session);
143
144         //verify initialization of topology
145         final InstanceIdentifier<NetworkTopology> networkTopologyId = InstanceIdentifier.builder(NetworkTopology.class).build();
146         final Topology topo = new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build();
147         final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
148         verify(wtx).merge(LogicalDatastoreType.CONFIGURATION, networkTopologyId, networkTopology);
149         verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, networkTopologyId, networkTopology);
150         verify(wtx).merge(LogicalDatastoreType.CONFIGURATION, networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
151         verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
152     }
153
154     @Test
155     public void testOnDataTreeChange() {
156
157         DataObjectModification<Node> newNode = mock(DataObjectModification.class);
158         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
159
160         InstanceIdentifier.PathArgument pa = null;
161
162         for (InstanceIdentifier.PathArgument p : TopologyUtil.createTopologyListPath(TOPOLOGY_ID).child(Node.class, new NodeKey(NODE_ID)).getPathArguments()) {
163             pa = p;
164         }
165
166         when(newNode.getIdentifier()).thenReturn(pa);
167
168
169         NetconfNode testingNode = new NetconfNodeBuilder()
170                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
171                 .setPort(new PortNumber(9999))
172                 .setReconnectOnChangedSchema(true)
173                 .setDefaultRequestTimeoutMillis(1000L)
174                 .setBetweenAttemptsTimeoutMillis(100)
175                 .setKeepaliveDelay(1000L)
176                 .setTcpOnly(true)
177                 .setCredentials(new LoginPasswordBuilder().setUsername("testuser").setPassword("testpassword").build())
178                 .build();
179
180         NodeBuilder nn = new NodeBuilder().addAugmentation(NetconfNode.class, testingNode);
181
182         when(newNode.getDataAfter()).thenReturn(nn.build());
183
184
185
186         Collection<DataTreeModification<Node>> changes = Sets.newHashSet();
187         DataTreeModification<Node> ch = mock(DataTreeModification.class);
188         when(ch.getRootNode()).thenReturn(newNode);
189         changes.add(ch);
190         spyTopology.onDataTreeChanged(changes);
191         verify(spyTopology).connectNode(TopologyUtil.getNodeId(pa), nn.build());
192
193         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
194         spyTopology.onDataTreeChanged(changes);
195         verify(spyTopology).disconnectNode(TopologyUtil.getNodeId(pa));
196
197         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
198         spyTopology.onDataTreeChanged(changes);
199
200         //one in previous creating and deleting node and one in updating
201         verify(spyTopology, times(2)).disconnectNode(TopologyUtil.getNodeId(pa));
202         verify(spyTopology, times(2)).connectNode(TopologyUtil.getNodeId(pa), nn.build());
203
204
205     }
206
207     public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
208
209         public TestingNetconfTopologyImpl(String topologyId, NetconfClientDispatcher clientDispatcher, BindingAwareBroker bindingAwareBroker, Broker domBroker, EventExecutor eventExecutor, ScheduledThreadPool keepaliveExecutor, ThreadPool processingExecutor, SchemaRepositoryProvider schemaRepositoryProvider) {
210             super(topologyId, clientDispatcher, bindingAwareBroker, domBroker, eventExecutor, keepaliveExecutor, processingExecutor, schemaRepositoryProvider);
211         }
212
213         @Override
214         public ListenableFuture<NetconfDeviceCapabilities> connectNode(NodeId nodeId, Node configNode) {
215             return Futures.immediateFuture(new NetconfDeviceCapabilities());
216         }
217
218         @Override
219         public ListenableFuture<Void> disconnectNode(NodeId nodeId) {
220             return Futures.immediateFuture(null);
221         }
222     }
223
224 }