6616968d03bf36335741b36e08971160dd8afe5f
[netconf.git] / apps / netconf-topology-impl / 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 package org.opendaylight.netconf.topology.impl;
9
10 import static org.mockito.Mockito.doReturn;
11 import static org.mockito.Mockito.spy;
12 import static org.mockito.Mockito.times;
13 import static org.mockito.Mockito.verify;
14
15 import com.google.common.util.concurrent.MoreExecutors;
16 import io.netty.util.concurrent.EventExecutor;
17 import java.util.List;
18 import org.junit.jupiter.api.Test;
19 import org.junit.jupiter.api.extension.ExtendWith;
20 import org.mockito.Mock;
21 import org.mockito.junit.jupiter.MockitoExtension;
22 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
23 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
24 import org.opendaylight.controller.config.threadpool.ThreadPool;
25 import org.opendaylight.mdsal.binding.api.DataBroker;
26 import org.opendaylight.mdsal.binding.api.DataObjectModification;
27 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
28 import org.opendaylight.mdsal.binding.api.DataTreeModification;
29 import org.opendaylight.mdsal.binding.api.RpcProviderService;
30 import org.opendaylight.mdsal.binding.api.WriteTransaction;
31 import org.opendaylight.mdsal.common.api.CommitInfo;
32 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
33 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
34 import org.opendaylight.netconf.client.NetconfClientDispatcher;
35 import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
36 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
37 import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas;
38 import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPasswordBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNodeBuilder;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
54 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
55 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
56 import org.opendaylight.yangtools.yang.common.Uint16;
57 import org.opendaylight.yangtools.yang.common.Uint32;
58 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
59
60 @ExtendWith(MockitoExtension.class)
61 class NetconfTopologyImplTest {
62     private static final TopologyKey TOPOLOGY_KEY = new TopologyKey(new TopologyId("testing-topology"));
63     private static final KeyedInstanceIdentifier<Topology, TopologyKey> TOPOLOGY_PATH =
64         InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, TOPOLOGY_KEY).build();
65
66     @Mock
67     private NetconfClientDispatcher mockedClientDispatcher;
68     @Mock
69     private EventExecutor mockedEventExecutor;
70     @Mock
71     private ScheduledThreadPool mockedKeepaliveExecutor;
72     @Mock
73     private ThreadPool mockedProcessingExecutor;
74     @Mock
75     private SchemaResourceManager mockedResourceManager;
76     @Mock
77     private DataBroker dataBroker;
78     @Mock
79     private DOMMountPointService mountPointService;
80     @Mock
81     private AAAEncryptionService encryptionService;
82     @Mock
83     private RpcProviderService rpcProviderService;
84     @Mock
85     private NetconfClientConfigurationBuilderFactory builderFactory;
86     @Mock
87     private WriteTransaction wtx;
88     @Mock
89     private DataObjectModification<Node> objMod;
90     @Mock
91     private DataTreeModification<Node> treeMod;
92
93     private TestingNetconfTopologyImpl topology;
94     private TestingNetconfTopologyImpl spyTopology;
95
96     @Test
97     void testOnDataTreeChange() throws Exception {
98         doReturn(MoreExecutors.newDirectExecutorService()).when(mockedProcessingExecutor).getExecutor();
99         doReturn(wtx).when(dataBroker).newWriteOnlyTransaction();
100         doReturn(CommitInfo.emptyFluentFuture()).when(wtx).commit();
101
102         topology = new TestingNetconfTopologyImpl(TOPOLOGY_KEY.getTopologyId().getValue(), mockedClientDispatcher,
103             mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedResourceManager, dataBroker,
104             mountPointService, encryptionService, builderFactory, rpcProviderService,
105             new DefaultBaseNetconfSchemas(new DefaultYangParserFactory()));
106         //verify initialization of topology
107         verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, TOPOLOGY_PATH,
108             new TopologyBuilder().withKey(TOPOLOGY_KEY).build());
109
110         spyTopology = spy(topology);
111
112         final var key = new NodeKey(new NodeId("testing-node"));
113         final var node = new NodeBuilder()
114             .withKey(key)
115             .addAugmentation(new NetconfNodeBuilder()
116                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
117                 .setPort(new PortNumber(Uint16.valueOf(9999)))
118                 .setReconnectOnChangedSchema(true)
119                 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
120                 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
121                 .setKeepaliveDelay(Uint32.valueOf(1000))
122                 .setTcpOnly(true)
123                 .setCredentials(new LoginPasswordBuilder()
124                     .setUsername("testuser")
125                     .setPassword("testpassword")
126                     .build())
127                 .build())
128             .build();
129
130         doReturn(DataObjectModification.ModificationType.WRITE).when(objMod).getModificationType();
131         doReturn(node).when(objMod).getDataAfter();
132
133         doReturn(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, TOPOLOGY_PATH.child(Node.class, key)))
134             .when(treeMod).getRootPath();
135         final var changes = List.of(treeMod);
136
137         doReturn(objMod).when(treeMod).getRootNode();
138         spyTopology.onDataTreeChanged(changes);
139         verify(spyTopology).ensureNode(node);
140
141         doReturn(DataObjectModification.ModificationType.DELETE).when(objMod).getModificationType();
142         spyTopology.onDataTreeChanged(changes);
143         verify(spyTopology).deleteNode(key.getNodeId());
144
145         doReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED).when(objMod).getModificationType();
146         spyTopology.onDataTreeChanged(changes);
147
148         // one in previous creating and deleting node and one in updating
149         verify(spyTopology, times(2)).ensureNode(node);
150     }
151
152     private static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
153         TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
154                 final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
155                 final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
156                 final DataBroker dataBroker, final DOMMountPointService mountPointService,
157                 final AAAEncryptionService encryptionService,
158                 final NetconfClientConfigurationBuilderFactory builderFactory,
159                 final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas) {
160             super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
161                 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, builderFactory,
162                 rpcProviderService, baseSchemas);
163         }
164
165         @Override
166         public void ensureNode(final Node configNode) {
167             // No-op
168         }
169
170         @Override
171         public void deleteNode(final NodeId nodeId) {
172             // No-op
173         }
174     }
175 }