Prevent NPE for Credentials
[netconf.git] / apps / netconf-topology-impl / src / test / java / org / opendaylight / netconf / topology / impl / NetconfTopologyImplTest.java
index fef24764616fe4604a4fe81e960b0bdaa68c7f4f..036b7489396290b1f2c709247c09fbab10ee1fb1 100644 (file)
@@ -8,42 +8,40 @@
 package org.opendaylight.netconf.topology.impl;
 
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import com.google.common.util.concurrent.MoreExecutors;
-import io.netty.util.concurrent.EventExecutor;
-import java.util.Collection;
-import java.util.HashSet;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
 import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.junit.jupiter.MockitoExtension;
 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
-import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
-import org.opendaylight.controller.config.threadpool.ThreadPool;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.DataObjectModification;
+import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
 import org.opendaylight.mdsal.binding.api.RpcProviderService;
 import org.opendaylight.mdsal.binding.api.WriteTransaction;
 import org.opendaylight.mdsal.common.api.CommitInfo;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
-import org.opendaylight.netconf.client.NetconfClientDispatcher;
-import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
+import org.opendaylight.netconf.client.NetconfClientFactory;
+import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
-import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas;
+import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemaProvider;
+import org.opendaylight.netconf.common.NetconfTimer;
 import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
+import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPasswordBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev240611.credentials.credentials.LoginPwUnencryptedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev240611.credentials.credentials.login.pw.unencrypted.LoginPasswordUnencryptedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev240611.NetconfNodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
@@ -54,26 +52,21 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
-import org.opendaylight.yangtools.yang.parser.api.YangParserException;
 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
 
-@RunWith(MockitoJUnitRunner.StrictStubs.class)
-public class NetconfTopologyImplTest {
-    private static final NodeId NODE_ID = new NodeId("testing-node");
-    private static final String TOPOLOGY_ID = "testing-topology";
+@ExtendWith(MockitoExtension.class)
+class NetconfTopologyImplTest {
+    private static final TopologyKey TOPOLOGY_KEY = new TopologyKey(new TopologyId("testing-topology"));
+    private static final KeyedInstanceIdentifier<Topology, TopologyKey> TOPOLOGY_PATH =
+        InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, TOPOLOGY_KEY).build();
 
     @Mock
-    private NetconfClientDispatcher mockedClientDispatcher;
+    private NetconfClientFactory mockedClientFactory;
     @Mock
-    private EventExecutor mockedEventExecutor;
-    @Mock
-    private ScheduledThreadPool mockedKeepaliveExecutor;
-    @Mock
-    private ThreadPool mockedProcessingExecutor;
+    private NetconfTimer mockedTimer;
     @Mock
     private SchemaResourceManager mockedResourceManager;
     @Mock
@@ -88,92 +81,80 @@ public class NetconfTopologyImplTest {
     private NetconfClientConfigurationBuilderFactory builderFactory;
     @Mock
     private WriteTransaction wtx;
+    @Mock
+    private DataObjectModification<Node> objMod;
+    @Mock
+    private DataTreeModification<Node> treeMod;
 
-    private TestingNetconfTopologyImpl topology;
-    private TestingNetconfTopologyImpl spyTopology;
-
-    @Before
-    public void setUp() {
-        doReturn(MoreExecutors.newDirectExecutorService()).when(mockedProcessingExecutor).getExecutor();
+    @Test
+    void testOnDataTreeChange() throws Exception {
         doReturn(wtx).when(dataBroker).newWriteOnlyTransaction();
         doReturn(CommitInfo.emptyFluentFuture()).when(wtx).commit();
 
-        topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher, mockedEventExecutor,
-            mockedKeepaliveExecutor, mockedProcessingExecutor, mockedResourceManager, dataBroker, mountPointService,
-            encryptionService, builderFactory, rpcProviderService);
-        //verify initialization of topology
-        verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(NetworkTopology.class)
-                .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))).build(),
-                new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build());
+        try (var schemaAssembler = new NetconfTopologySchemaAssembler(1, 1, 0, TimeUnit.SECONDS)) {
+            final var topology = new TestingNetconfTopologyImpl(TOPOLOGY_KEY.getTopologyId().getValue(),
+                mockedClientFactory, mockedTimer, schemaAssembler, mockedResourceManager, dataBroker, mountPointService,
+                encryptionService, builderFactory, rpcProviderService,
+                new DefaultBaseNetconfSchemaProvider(new DefaultYangParserFactory()));
+            //verify initialization of topology
+            verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, TOPOLOGY_PATH,
+                new TopologyBuilder().withKey(TOPOLOGY_KEY).build());
 
-        spyTopology = spy(topology);
-    }
-
-    @Test
-    public void testOnDataTreeChange() {
-        final DataObjectModification<Node> newNode = mock(DataObjectModification.class);
-        doReturn(DataObjectModification.ModificationType.WRITE).when(newNode).getModificationType();
+            final var spyTopology = spy(topology);
 
-        NodeKey key = new NodeKey(NODE_ID);
-        PathArgument pa = IdentifiableItem.of(Node.class, key);
-        doReturn(pa).when(newNode).getIdentifier();
-
-        final NodeBuilder nn = new NodeBuilder()
+            final var key = new NodeKey(new NodeId("testing-node"));
+            final var node = new NodeBuilder()
                 .withKey(key)
                 .addAugmentation(new NetconfNodeBuilder()
+                    .setLockDatastore(true)
                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
                     .setPort(new PortNumber(Uint16.valueOf(9999)))
                     .setReconnectOnChangedSchema(true)
                     .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
-                    .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
+                    .setMinBackoffMillis(Uint16.valueOf(100))
                     .setKeepaliveDelay(Uint32.valueOf(1000))
                     .setTcpOnly(true)
-                    .setCredentials(new LoginPasswordBuilder()
-                        .setUsername("testuser")
-                        .setPassword("testpassword")
+                    .setCredentials(new LoginPwUnencryptedBuilder()
+                        .setLoginPasswordUnencrypted(new LoginPasswordUnencryptedBuilder()
+                            .setUsername("testuser")
+                            .setPassword("testpassword")
+                            .build())
                         .build())
-                    .build());
-        doReturn(nn.build()).when(newNode).getDataAfter();
+                    .build())
+                .build();
 
-        final Collection<DataTreeModification<Node>> changes = new HashSet<>();
-        final DataTreeModification<Node> ch = mock(DataTreeModification.class);
-        doReturn(newNode).when(ch).getRootNode();
-        changes.add(ch);
-        spyTopology.onDataTreeChanged(changes);
-        verify(spyTopology).ensureNode(nn.build());
+            doReturn(DataObjectModification.ModificationType.WRITE).when(objMod).modificationType();
+            doReturn(node).when(objMod).dataAfter();
 
-        doReturn(DataObjectModification.ModificationType.DELETE).when(newNode).getModificationType();
-        spyTopology.onDataTreeChanged(changes);
-        verify(spyTopology).deleteNode(NetconfTopologyImpl.getNodeId(pa));
+            doReturn(DataTreeIdentifier.of(LogicalDatastoreType.CONFIGURATION,
+                TOPOLOGY_PATH.child(Node.class, key))).when(treeMod).getRootPath();
+            final var changes = List.of(treeMod);
 
-        doReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED).when(newNode).getModificationType();
-        spyTopology.onDataTreeChanged(changes);
+            doReturn(objMod).when(treeMod).getRootNode();
+            spyTopology.onDataTreeChanged(changes);
+            verify(spyTopology).ensureNode(node);
 
-        // one in previous creating and deleting node and one in updating
-        verify(spyTopology, times(2)).ensureNode(nn.build());
-    }
+            doReturn(DataObjectModification.ModificationType.DELETE).when(objMod).modificationType();
+            spyTopology.onDataTreeChanged(changes);
+            verify(spyTopology).deleteNode(key.getNodeId());
 
-    public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
-        private static final BaseNetconfSchemas BASE_SCHEMAS;
+            doReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED).when(objMod).modificationType();
+            spyTopology.onDataTreeChanged(changes);
 
-        static {
-            try {
-                BASE_SCHEMAS = new DefaultBaseNetconfSchemas(new DefaultYangParserFactory());
-            } catch (YangParserException e) {
-                throw new ExceptionInInitializerError(e);
-            }
+            // one in previous creating and deleting node and one in updating
+            verify(spyTopology, times(2)).ensureNode(node);
         }
+    }
 
-        public TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
-                final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
-                final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
-                final DataBroker dataBroker, final DOMMountPointService mountPointService,
-                final AAAEncryptionService encryptionService,
+    private static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
+        TestingNetconfTopologyImpl(final String topologyId, final NetconfClientFactory clientFactory,
+                final NetconfTimer timer, final NetconfTopologySchemaAssembler schemaAssembler,
+                final SchemaResourceManager schemaRepositoryProvider, final DataBroker dataBroker,
+                final DOMMountPointService mountPointService, final AAAEncryptionService encryptionService,
                 final NetconfClientConfigurationBuilderFactory builderFactory,
-                final RpcProviderService rpcProviderService) {
-            super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
-                schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, builderFactory,
-                rpcProviderService, BASE_SCHEMAS);
+                final RpcProviderService rpcProviderService, final BaseNetconfSchemaProvider baseSchemaProvider) {
+            super(topologyId, clientFactory, timer, schemaAssembler, schemaRepositoryProvider, dataBroker,
+                mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemaProvider);
         }
 
         @Override