Fix periodic NETCONF Call Home connection dropping
[netconf.git] / netconf / callhome-protocol / src / test / java / org / opendaylight / netconf / callhome / protocol / NetconfCallHomeServerTest.java
index 25302177529b2f478a92a185b78279ee53b89b00..250ab80bfa464e0adefeab8f15585ac67a11b527 100644 (file)
@@ -5,67 +5,94 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-
 package org.opendaylight.netconf.callhome.protocol;
 
 import static org.junit.Assert.assertFalse;
-import static org.mockito.Matchers.any;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+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 io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.security.PublicKey;
 import java.util.HashMap;
 import java.util.Map;
-import org.apache.sshd.ClientSession;
-import org.apache.sshd.SshClient;
-import org.apache.sshd.client.future.AuthFuture;
-import org.apache.sshd.client.session.ClientSessionImpl;
-import org.apache.sshd.common.Session;
-import org.apache.sshd.common.SessionListener;
-import org.apache.sshd.common.future.SshFutureListener;
-import org.apache.sshd.common.io.IoAcceptor;
-import org.apache.sshd.common.io.IoHandler;
-import org.apache.sshd.common.io.IoServiceFactory;
+import org.junit.AfterClass;
 import org.junit.Before;
-import org.junit.Ignore;
+import org.junit.BeforeClass;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opendaylight.netconf.shaded.sshd.client.SshClient;
+import org.opendaylight.netconf.shaded.sshd.client.future.AuthFuture;
+import org.opendaylight.netconf.shaded.sshd.client.session.ClientSession;
+import org.opendaylight.netconf.shaded.sshd.client.session.ClientSessionImpl;
+import org.opendaylight.netconf.shaded.sshd.common.future.SshFutureListener;
+import org.opendaylight.netconf.shaded.sshd.common.io.IoAcceptor;
+import org.opendaylight.netconf.shaded.sshd.common.io.IoHandler;
+import org.opendaylight.netconf.shaded.sshd.common.io.IoServiceFactory;
+import org.opendaylight.netconf.shaded.sshd.common.session.Session;
+import org.opendaylight.netconf.shaded.sshd.common.session.SessionListener;
+
+@RunWith(MockitoJUnitRunner.class)
 public class NetconfCallHomeServerTest {
+    private static EventLoopGroup EVENT_LOOP_GROUP;
+    private static InetSocketAddress MOCK_ADDRESS;
+
+    private SshClient mockSshClient;
+    @Mock
+    private CallHomeAuthorizationProvider mockCallHomeAuthProv;
+    @Mock
+    private CallHomeAuthorization mockAuth;
+    @Mock
+    private CallHomeSessionContext.Factory mockFactory;
+    @Mock
+    private ClientSession mockSession;
+    @Mock
+    private StatusRecorder mockStatusRecorder;
+
+    private NetconfCallHomeServer instance;
+
+    @BeforeClass
+    public static void beforeClass() {
+        EVENT_LOOP_GROUP = new NioEventLoopGroup();
+        MOCK_ADDRESS = InetSocketAddress.createUnresolved("127.0.0.1", 123);
+    }
 
-    SshClient mockSshClient;
-    CallHomeAuthorizationProvider mockCallHomeAuthProv;
-    CallHomeAuthorization mockAuth;
-    CallHomeSessionContext.Factory mockFactory;
-    InetSocketAddress mockAddress;
-    ClientSession mockSession;
-
-    NetconfCallHomeServer instance;
+    @AfterClass
+    public static void afterClass() {
+        EVENT_LOOP_GROUP.shutdownGracefully();
+        EVENT_LOOP_GROUP = null;
+        MOCK_ADDRESS = null;
+    }
 
     @Before
     public void setup() {
-        mockSshClient = Mockito.spy(SshClient.setUpDefaultClient());
+        mockSshClient = spy(SshClient.setUpDefaultClient());
         mockCallHomeAuthProv = mock(CallHomeAuthorizationProvider.class);
         mockAuth = mock(CallHomeAuthorization.class);
         mockFactory = mock(CallHomeSessionContext.Factory.class);
-        mockAddress = InetSocketAddress.createUnresolved("1.2.3.4", 123);
         mockSession = mock(ClientSession.class);
+        mockStatusRecorder = mock(StatusRecorder.class);
 
-        Map<String,String> props = new HashMap<>();
+        Map<String, String> props = new HashMap<>();
         props.put("nio-workers", "1");
-        Mockito.doReturn(props).when(mockSshClient).getProperties();
-        Mockito.doReturn("test").when(mockSession).toString();
-        instance = new NetconfCallHomeServer(mockSshClient, mockCallHomeAuthProv, mockFactory, mockAddress);
+        doReturn(EVENT_LOOP_GROUP).when(mockFactory).getNettyGroup();
+        instance = new NetconfCallHomeServer(
+            mockSshClient, mockCallHomeAuthProv, mockFactory, MOCK_ADDRESS, mockStatusRecorder);
     }
 
     @Test
-    public void sessionListenerShouldHandleEventsOfKeyEstablishedAndAuthenticated () throws IOException {
+    public void sessionListenerShouldHandleEventsOfKeyEstablishedAndAuthenticated() throws IOException {
         // Weird - IJ was ok but command line compile failed using the usual array initializer syntax ????
         SessionListener.Event[] evt = new SessionListener.Event[2];
         evt[0] = SessionListener.Event.KeyEstablished;
@@ -79,16 +106,20 @@ public class NetconfCallHomeServerTest {
         hitAuth[0] = 1;
         hitAuth[1] = 0;
 
-        for (int pass = 0; pass < evt.length; pass++)
-        {
+        for (int pass = 0; pass < evt.length; pass++) {
             // given
             AuthFuture mockAuthFuture = mock(AuthFuture.class);
-            Mockito.doReturn(null).when(mockAuthFuture).addListener(any(SshFutureListener.class));
+            doReturn(null).when(mockAuthFuture).addListener(any(SshFutureListener.class));
             CallHomeSessionContext mockContext = mock(CallHomeSessionContext.class);
-            Mockito.doNothing().when(mockContext).openNetconfChannel();
-            Mockito.doReturn(mockContext).when(mockSession).getAttribute(any(Session.AttributeKey.class));
-            SessionListener listener = instance.createSessionListener();
-            Mockito.doReturn(mockAuthFuture).when(mockContext).authorize();
+            doNothing().when(mockContext).openNetconfChannel();
+            doReturn(mockContext).when(mockSession).getAttribute(any(Session.AttributeKey.class));
+
+            final PublicKey serverKey = mock(PublicKey.class);
+            doReturn(serverKey).when(mockSession).getServerKey();
+
+            final SessionListener listener = instance.createSessionListener();
+            doReturn(mockAuthFuture).when(mockContext).authorize();
+            doReturn(false).when(mockSession).isAuthenticated();
             // when
             listener.sessionEvent(mockSession, evt[pass]);
             // then
@@ -98,30 +129,24 @@ public class NetconfCallHomeServerTest {
     }
 
     @Test
-    public void verificationOfTheServerKeyShouldBeSuccessfulForServerIsAllowed () {
+    public void verificationOfTheServerKeyShouldBeSuccessfulForServerIsAllowed() {
         // given
-
         ClientSessionImpl mockClientSession = mock(ClientSessionImpl.class);
         Mockito.doReturn("test").when(mockClientSession).toString();
         SocketAddress mockSocketAddr = mock(SocketAddress.class);
-        Mockito.doReturn("testAddr").when(mockSocketAddr).toString();
         PublicKey mockPublicKey = mock(PublicKey.class);
 
-        CallHomeAuthorization mockAuth = mock(CallHomeAuthorization.class);
-        Mockito.doReturn("test").when(mockAuth).toString();
         Mockito.doReturn(true).when(mockAuth).isServerAllowed();
         Mockito.doReturn("some-session-name").when(mockAuth).getSessionName();
-
-        Mockito.doReturn(mockAuth).when(mockCallHomeAuthProv).provideAuth(mockSocketAddr,mockPublicKey);
-
+        Mockito.doReturn(mockAuth).when(mockCallHomeAuthProv).provideAuth(mockSocketAddr, mockPublicKey);
         Mockito.doReturn(null).when(mockFactory).createIfNotExists(mockClientSession, mockAuth, mockSocketAddr);
 
         // expect
-        instance.verifyServerKey(mockClientSession, mockSocketAddr, mockPublicKey);
+        assertFalse(instance.verifyServerKey(mockClientSession, mockSocketAddr, mockPublicKey));
     }
 
     @Test
-    public void verificationOfTheServerKeyShouldFailIfTheServerIsNotAllowed () {
+    public void verificationOfTheServerKeyShouldFailIfTheServerIsNotAllowed() {
         // given
 
         ClientSessionImpl mockClientSession = mock(ClientSessionImpl.class);
@@ -136,46 +161,20 @@ public class NetconfCallHomeServerTest {
         assertFalse(instance.verifyServerKey(mockClientSession, mockSocketAddr, mockPublicKey));
     }
 
-    static class TestableCallHomeServer extends NetconfCallHomeServer
-    {
-        static IoServiceFactory minaServiceFactory;
-        static SshClient factoryHook (SshClient client, IoServiceFactory minaFactory)
-        {
-            minaServiceFactory = minaFactory;
-            return client;
-        }
-
-        SshClient client;
-
-        TestableCallHomeServer(SshClient sshClient, CallHomeAuthorizationProvider authProvider,
-                                   CallHomeSessionContext.Factory factory, InetSocketAddress socketAddress,
-                                   IoServiceFactory minaFactory) {
-            super(factoryHook(sshClient, minaFactory), authProvider, factory, socketAddress);
-            client = sshClient;
-        }
-
-        @Override
-        protected IoServiceFactory createMinaServiceFactory(SshClient sshClient)
-        {
-            return minaServiceFactory;
-        }
-    }
-
     @Test
-    public void bindShouldStartTheClientAndBindTheAddress () throws IOException {
+    public void bindShouldStartTheClientAndBindTheAddress() throws IOException {
         // given
         IoAcceptor mockAcceptor = mock(IoAcceptor.class);
         IoServiceFactory mockMinaFactory = mock(IoServiceFactory.class);
 
         Mockito.doReturn(mockAcceptor).when(mockMinaFactory).createAcceptor(any(IoHandler.class));
-        Mockito.doReturn(mockAcceptor).when(mockMinaFactory).createAcceptor(any(IoHandler.class));
-        Mockito.doNothing().when(mockAcceptor).bind(mockAddress);
-        instance = new TestableCallHomeServer(mockSshClient, mockCallHomeAuthProv, mockFactory, mockAddress, mockMinaFactory);
+        Mockito.doNothing().when(mockAcceptor).bind(any(SocketAddress.class));
+        instance = new NetconfCallHomeServer(
+                mockSshClient, mockCallHomeAuthProv, mockFactory, MOCK_ADDRESS, mockStatusRecorder, mockMinaFactory);
         // when
         instance.bind();
         // then
         verify(mockSshClient, times(1)).start();
-        verify(mockAcceptor, times(1)).bind(mockAddress);
+        verify(mockAcceptor, times(1)).bind(MOCK_ADDRESS);
     }
-
 }