Hide Netty(Pipeline)AwareChannelSubsystem
[netconf.git] / netconf / callhome-protocol / src / test / java / org / opendaylight / netconf / callhome / protocol / CallHomeSessionContextTest.java
index 032679e94d5789d3cd4f2712843b080daa80c09c..a70471176020d450f17b7d1cdd6c3555582c7154 100644 (file)
  * 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.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyString;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
 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.Channel;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelPipeline;
+import io.netty.channel.DefaultChannelPipeline;
 import io.netty.channel.EventLoopGroup;
-import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.security.PublicKey;
-import org.apache.sshd.ClientChannel;
-import org.apache.sshd.ClientChannel.Streaming;
-import org.apache.sshd.ClientSession;
-import org.apache.sshd.client.channel.ChannelSubsystem;
-import org.apache.sshd.client.future.OpenFuture;
-import org.apache.sshd.client.session.ClientSessionImpl;
-import org.apache.sshd.common.KeyExchange;
-import org.apache.sshd.common.Session.AttributeKey;
-import org.apache.sshd.common.future.SshFutureListener;
-import org.apache.sshd.common.io.IoInputStream;
-import org.apache.sshd.common.io.IoOutputStream;
-import org.apache.sshd.common.io.IoReadFuture;
-import org.apache.sshd.common.io.IoSession;
-import org.apache.sshd.common.util.Buffer;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mockito;
+import org.opendaylight.netconf.callhome.protocol.CallHomeSessionContext.Factory;
 import org.opendaylight.netconf.client.NetconfClientSessionListener;
 import org.opendaylight.netconf.client.NetconfClientSessionNegotiatorFactory;
+import org.opendaylight.netconf.nettyutil.handler.ssh.client.NetconfClientSessionImpl;
+import org.opendaylight.netconf.shaded.sshd.client.channel.ChannelSubsystem;
+import org.opendaylight.netconf.shaded.sshd.client.channel.ClientChannel;
+import org.opendaylight.netconf.shaded.sshd.client.future.OpenFuture;
+import org.opendaylight.netconf.shaded.sshd.common.AttributeRepository.AttributeKey;
+import org.opendaylight.netconf.shaded.sshd.common.channel.StreamingChannel;
+import org.opendaylight.netconf.shaded.sshd.common.future.SshFutureListener;
+import org.opendaylight.netconf.shaded.sshd.common.io.IoInputStream;
+import org.opendaylight.netconf.shaded.sshd.common.io.IoOutputStream;
+import org.opendaylight.netconf.shaded.sshd.common.io.IoReadFuture;
+import org.opendaylight.netconf.shaded.sshd.common.io.IoSession;
+import org.opendaylight.netconf.shaded.sshd.common.kex.KeyExchange;
+import org.opendaylight.netconf.shaded.sshd.common.util.buffer.Buffer;
 
 public class CallHomeSessionContextTest {
-    private ClientSessionImpl mockSession;
+    private NetconfClientSessionImpl mockSession;
     private CallHomeAuthorization mockAuth;
     private ClientChannel mockChannel;
-    private InetSocketAddress address;
-
-    private ReverseSshChannelInitializer mockChannelInitializer;
-    private CallHomeNetconfSubsystemListener subListener;
     private EventLoopGroup mockNettyGroup;
-    private CallHomeSessionContext.Factory realFactory;
+    private Factory realFactory;
     private CallHomeSessionContext instance;
-    private NetconfClientSessionNegotiatorFactory mockNegotiatior;
 
     @Before
     public void setup() {
-        mockSession = mock(ClientSessionImpl.class);
+        mockSession = mock(NetconfClientSessionImpl.class);
         mockAuth = mock(CallHomeAuthorization.class);
         mockChannel = mock(ClientChannel.class);
-        address = mock(InetSocketAddress.class);
 
-        mockNegotiatior = mock(NetconfClientSessionNegotiatorFactory.class);
-        subListener = mock(CallHomeNetconfSubsystemListener.class);
+        final var mockNegotiatior = mock(NetconfClientSessionNegotiatorFactory.class);
+        final var subListener = mock(CallHomeNetconfSubsystemListener.class);
         mockNettyGroup = mock(EventLoopGroup.class);
-
-        realFactory = new CallHomeSessionContext.Factory(mockNettyGroup, mockNegotiatior, subListener);
-
-        KeyExchange kexMock = Mockito.mock(KeyExchange.class);
-        Mockito.doReturn(kexMock).when(mockSession).getKex();
-
-        PublicKey keyMock = Mockito.mock(PublicKey.class);
-        Mockito.doReturn(keyMock).when(kexMock).getServerKey();
-        IoReadFuture mockFuture = mock(IoReadFuture.class);
-        IoInputStream mockIn = mock(IoInputStream.class);
-        Mockito.doReturn(mockFuture).when(mockIn).read(any(Buffer.class));
-        IoOutputStream mockOut = mock(IoOutputStream.class);
-
-        Mockito.doReturn(mockIn).when(mockChannel).getAsyncOut();
-        Mockito.doReturn(mockOut).when(mockChannel).getAsyncIn();
-
-        Mockito.doReturn(true).when(mockAuth).isServerAllowed();
-
-        IoSession ioSession = mock(IoSession.class);
-        Mockito.doReturn(ioSession).when(mockSession).getIoSession();
-        Mockito.doReturn(address).when(ioSession).getRemoteAddress();
-        Mockito.doReturn(null).when(mockSession).setAttribute(any(AttributeKey.class), any());
-        Mockito.doReturn(null).when(mockSession).getAttribute(any(AttributeKey.class));
-        Mockito.doReturn("testSession").when(mockSession).toString();
-
+        realFactory = new Factory(mockNettyGroup, mockNegotiatior, subListener);
+
+        final var kexMock = mock(KeyExchange.class);
+        doReturn(kexMock).when(mockSession).getKex();
+        final var keyMock = mock(PublicKey.class);
+        doReturn(keyMock).when(mockSession).getServerKey();
+
+        final var mockFuture = mock(IoReadFuture.class);
+        final var mockIn = mock(IoInputStream.class);
+        doReturn(mockFuture).when(mockIn).read(any(Buffer.class));
+        final var mockOut = mock(IoOutputStream.class);
+        doReturn(mockIn).when(mockChannel).getAsyncOut();
+        doReturn(mockOut).when(mockChannel).getAsyncIn();
+
+        final var ioSession = mock(IoSession.class);
+        doReturn(ioSession).when(mockSession).getIoSession();
+        final var address = mock(InetSocketAddress.class);
+        doReturn(address).when(ioSession).getRemoteAddress();
+        doReturn(null).when(mockSession).setAttribute(any(AttributeKey.class), any());
+        doReturn(null).when(mockSession).getAttribute(any(AttributeKey.class));
+        doReturn("testSession").when(mockSession).toString();
+
+        doReturn(true).when(mockAuth).isServerAllowed();
         doNothing().when(mockAuth).applyTo(mockSession);
-        Mockito.doReturn("test").when(mockAuth).getSessionName();
+        doReturn("test").when(mockAuth).getSessionName();
     }
 
     @Test
     public void theContextShouldBeSettableAndRetrievableAsASessionAttribute() {
-        // redo instance below because previous constructor happened too early to capture behavior
-        instance = realFactory.createIfNotExists(mockSession, mockAuth, address);
         // when
-        CallHomeSessionContext.getFrom(mockSession);
+        instance = realFactory.createIfNotExists(mockSession, mockAuth);
         // then
+        assertNotNull(instance);
         verify(mockSession, times(1)).setAttribute(CallHomeSessionContext.SESSION_KEY, instance);
+        verify(mockSession, times(0)).getAttribute(any());
+
+        // when
+        CallHomeSessionContext.getFrom(mockSession);
+        // then
         verify(mockSession, times(1)).getAttribute(CallHomeSessionContext.SESSION_KEY);
     }
 
     @Test
-    public void anAuthorizeActionShouldApplyToTheBoundSession() throws IOException {
-        instance = realFactory.createIfNotExists(mockSession, mockAuth, address);
+    public void anAuthorizeActionShouldApplyToTheBoundSession() throws Exception {
+        instance = realFactory.createIfNotExists(mockSession, mockAuth);
         // when
-        Mockito.doReturn(null).when(mockSession).auth();
+        doReturn(null).when(mockSession).auth();
         instance.authorize();
         // then
         verify(mockAuth, times(1)).applyTo(mockSession);
     }
 
     @Test
-    public void creatingAChannelSuccessfullyShouldResultInAnAttachedListener() throws IOException {
+    public void creatingAChannelSuccessfullyShouldResultInAnAttachedListener() throws Exception {
         // given
-        OpenFuture mockFuture = mock(OpenFuture.class);
-        ChannelSubsystem mockChannel = mock(ChannelSubsystem.class);
-        Mockito.doReturn(mockFuture).when(mockChannel).open();
-        Mockito.doReturn(mockChannel).when(mockSession).createSubsystemChannel(anyString());
-
-        Mockito.doReturn(null).when(mockFuture).addListener(any(SshFutureListener.class));
-        doNothing().when(mockChannel).setStreaming(any(Streaming.class));
-        instance = realFactory.createIfNotExists(mockSession, mockAuth, address);
+        final var mockFuture = mock(OpenFuture.class);
+        final var mockChannelSubsystem = mock(ChannelSubsystem.class);
+        doReturn(mockFuture).when(mockChannelSubsystem).open();
+        doReturn(mockChannelSubsystem).when(mockSession).createSubsystemChannel(anyString(),
+            any(DefaultChannelPipeline.class));
+
+        doReturn(null).when(mockFuture).addListener(any(SshFutureListener.class));
+        doNothing().when(mockChannelSubsystem).setStreaming(any(StreamingChannel.Streaming.class));
+        instance = realFactory.createIfNotExists(mockSession, mockAuth);
         // when
         instance.openNetconfChannel();
         // then
         verify(mockFuture, times(1)).addListener(any(SshFutureListener.class));
     }
 
-    static class TestableContext extends CallHomeSessionContext {
-        MinaSshNettyChannel minaMock;
-
-        TestableContext(ClientSession sshSession, CallHomeAuthorization authorization,
-                        InetSocketAddress address, CallHomeSessionContext.Factory factory,
-                        MinaSshNettyChannel minaMock) {
-            super(sshSession, authorization, address, factory);
-            this.minaMock = minaMock;
-        }
-
-        @Override
-        protected MinaSshNettyChannel newMinaSshNettyChannel(ClientChannel netconfChannel) {
-            return minaMock;
-        }
-    }
-
     @Test
     public void openingTheChannelSuccessfullyNotifyTheChannelListener() {
         // given
-        MinaSshNettyChannel mockMinaChannel = mock(MinaSshNettyChannel.class);
-        CallHomeSessionContext.Factory mockFactory = mock(CallHomeSessionContext.Factory.class);
-
-        CallHomeNetconfSubsystemListener mockListener = mock(CallHomeNetconfSubsystemListener.class);
+        final var mockListener = mock(CallHomeNetconfSubsystemListener.class);
         doNothing().when(mockListener).onNetconfSubsystemOpened(any(CallHomeProtocolSessionContext.class),
-                any(CallHomeChannelActivator.class));
+            any(CallHomeChannelActivator.class));
 
-        ChannelFuture mockChanFuture = mock(ChannelFuture.class);
-        Mockito.doReturn(mockChanFuture).when(mockNettyGroup).register(any(Channel.class));
+        final var mockChanFuture = mock(ChannelFuture.class);
+        doReturn(mockChanFuture).when(mockNettyGroup).register(any(Channel.class));
 
-        Mockito.doReturn(mockNettyGroup).when(mockFactory).getNettyGroup();
-        Mockito.doReturn(mockChannelInitializer).when(mockFactory)
-                .getChannelInitializer(any(NetconfClientSessionListener.class));
-        Mockito.doReturn(mockListener).when(mockFactory).getChannelOpenListener();
+        final var mockFactory = mock(Factory.class);
+        doReturn(mockNettyGroup).when(mockFactory).getNettyGroup();
+        final var mockChannelInitializer = mock(ReverseSshChannelInitializer.class);
+        doReturn(mockChannelInitializer).when(mockFactory)
+            .getChannelInitializer(any(NetconfClientSessionListener.class));
+        doReturn(mockListener).when(mockFactory).getChannelOpenListener();
 
-        ChannelPipeline mockPipeline = mock(ChannelPipeline.class);
-        Mockito.doReturn(mockPipeline).when(mockMinaChannel).pipeline();
+        final var mockPipeline = mock(ChannelPipeline.class);
+        final var mockMinaChannel = mock(MinaSshNettyChannel.class);
+        doReturn(mockPipeline).when(mockMinaChannel).pipeline();
 
-        OpenFuture mockFuture = mock(OpenFuture.class);
-        Mockito.doReturn(true).when(mockFuture).isOpened();
+        final var mockFuture = mock(OpenFuture.class);
+        doReturn(true).when(mockFuture).isOpened();
+
+        instance = spy(new CallHomeSessionContext(mockSession, mockAuth, mockFactory));
+        doReturn(mockMinaChannel).when(instance).newMinaSshNettyChannel();
+        final var listener = instance.newSshFutureListener(mockChannel, mockMinaChannel);
 
-        instance = new TestableContext(mockSession, mockAuth, address, mockFactory, mockMinaChannel);
-        SshFutureListener<OpenFuture> listener = instance.newSshFutureListener(mockChannel);
         // when
         listener.operationComplete(mockFuture);
         // then
         verify(mockListener, times(1)).onNetconfSubsystemOpened(any(CallHomeProtocolSessionContext.class),
-                any(CallHomeChannelActivator.class));
+            any(CallHomeChannelActivator.class));
     }
 
     @Test
     public void failureToOpenTheChannelShouldCauseTheSessionToClose() {
         // given
-        instance = realFactory.createIfNotExists(mockSession, mockAuth, address);
-
-        OpenFuture mockFuture = mock(OpenFuture.class);
-        Mockito.doReturn(false).when(mockFuture).isOpened();
-        Mockito.doReturn(new RuntimeException("test")).when(mockFuture).getException();
-
+        instance = realFactory.createIfNotExists(mockSession, mockAuth);
+        final var mockFuture = mock(OpenFuture.class);
+        doReturn(false).when(mockFuture).isOpened();
+        doReturn(new RuntimeException("test")).when(mockFuture).getException();
         doReturn(null).when(mockSession).close(anyBoolean());
 
         // when
-        SshFutureListener<OpenFuture> listener = instance.newSshFutureListener(mockChannel);
+        final var listener = instance.newSshFutureListener(mockChannel, null);
         listener.operationComplete(mockFuture);
         // then
         // You'll see an error message logged to the console - it is expected.
         verify(mockSession, times(1)).close(anyBoolean());
     }
+
+    @Test
+    public void theContextConstructorShouldNotModifySession() {
+        instance = new CallHomeSessionContext(mockSession, mockAuth, realFactory);
+        verify(mockSession, times(0)).setAttribute(any(), any());
+        assertNull(CallHomeSessionContext.getFrom(mockSession));
+    }
 }