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