2 * Copyright (c) 2016 Brocade Communication Systems and others. All rights reserved.
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
8 package org.opendaylight.netconf.callhome.protocol;
10 import static org.junit.Assert.assertFalse;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.Mockito.doNothing;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.spy;
16 import static org.mockito.Mockito.times;
17 import static org.mockito.Mockito.verify;
19 import io.netty.channel.EventLoopGroup;
20 import io.netty.channel.nio.NioEventLoopGroup;
21 import java.io.IOException;
22 import java.net.InetSocketAddress;
23 import java.net.SocketAddress;
24 import java.security.PublicKey;
25 import java.util.HashMap;
27 import org.junit.AfterClass;
28 import org.junit.Before;
29 import org.junit.BeforeClass;
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.mockito.Mock;
33 import org.mockito.junit.MockitoJUnitRunner;
34 import org.opendaylight.netconf.shaded.sshd.client.SshClient;
35 import org.opendaylight.netconf.shaded.sshd.client.future.AuthFuture;
36 import org.opendaylight.netconf.shaded.sshd.client.session.ClientSession;
37 import org.opendaylight.netconf.shaded.sshd.client.session.ClientSessionImpl;
38 import org.opendaylight.netconf.shaded.sshd.common.future.SshFutureListener;
39 import org.opendaylight.netconf.shaded.sshd.common.io.IoAcceptor;
40 import org.opendaylight.netconf.shaded.sshd.common.io.IoHandler;
41 import org.opendaylight.netconf.shaded.sshd.common.io.IoServiceFactory;
42 import org.opendaylight.netconf.shaded.sshd.common.session.Session;
43 import org.opendaylight.netconf.shaded.sshd.common.session.SessionListener;
45 @RunWith(MockitoJUnitRunner.class)
46 public class NetconfCallHomeServerTest {
47 private static EventLoopGroup EVENT_LOOP_GROUP;
48 private static InetSocketAddress MOCK_ADDRESS;
50 private SshClient mockSshClient;
52 private CallHomeAuthorizationProvider mockCallHomeAuthProv;
54 private CallHomeAuthorization mockAuth;
56 private CallHomeSessionContext.Factory mockFactory;
58 private ClientSession mockSession;
60 private StatusRecorder mockStatusRecorder;
62 private NetconfCallHomeServer instance;
65 public static void beforeClass() {
66 EVENT_LOOP_GROUP = new NioEventLoopGroup();
67 MOCK_ADDRESS = InetSocketAddress.createUnresolved("127.0.0.1", 123);
71 public static void afterClass() {
72 EVENT_LOOP_GROUP.shutdownGracefully();
73 EVENT_LOOP_GROUP = null;
79 mockSshClient = spy(SshClient.setUpDefaultClient());
80 mockCallHomeAuthProv = mock(CallHomeAuthorizationProvider.class);
81 mockAuth = mock(CallHomeAuthorization.class);
82 mockFactory = mock(CallHomeSessionContext.Factory.class);
83 mockSession = mock(ClientSession.class);
84 mockStatusRecorder = mock(StatusRecorder.class);
86 Map<String, String> props = new HashMap<>();
87 props.put("nio-workers", "1");
88 doReturn(EVENT_LOOP_GROUP).when(mockFactory).getNettyGroup();
89 instance = new NetconfCallHomeServer(
90 mockSshClient, mockCallHomeAuthProv, mockFactory, MOCK_ADDRESS, mockStatusRecorder);
94 public void sessionListenerShouldHandleEventsOfKeyEstablishedAndAuthenticated() throws IOException {
95 // Weird - IJ was ok but command line compile failed using the usual array initializer syntax ????
96 SessionListener.Event[] evt = new SessionListener.Event[2];
97 evt[0] = SessionListener.Event.KeyEstablished;
98 evt[1] = SessionListener.Event.Authenticated;
100 int[] hitOpen = new int[2];
104 int[] hitAuth = new int[2];
108 for (int pass = 0; pass < evt.length; pass++) {
110 AuthFuture mockAuthFuture = mock(AuthFuture.class);
111 doReturn(null).when(mockAuthFuture).addListener(any(SshFutureListener.class));
112 CallHomeSessionContext mockContext = mock(CallHomeSessionContext.class);
113 doNothing().when(mockContext).openNetconfChannel();
114 doReturn(mockContext).when(mockSession).getAttribute(any(Session.AttributeKey.class));
116 final PublicKey serverKey = mock(PublicKey.class);
117 doReturn(serverKey).when(mockSession).getServerKey();
119 final SessionListener listener = instance.createSessionListener();
120 doReturn(mockAuthFuture).when(mockContext).authorize();
121 doReturn(false).when(mockSession).isAuthenticated();
123 listener.sessionEvent(mockSession, evt[pass]);
125 verify(mockContext, times(hitOpen[pass])).openNetconfChannel();
126 verify(mockContext, times(hitAuth[pass])).authorize();
131 public void verificationOfTheServerKeyShouldBeSuccessfulForServerIsAllowed() {
133 ClientSessionImpl mockClientSession = mock(ClientSessionImpl.class);
134 doReturn("test").when(mockClientSession).toString();
135 SocketAddress mockSocketAddr = mock(SocketAddress.class);
136 PublicKey mockPublicKey = mock(PublicKey.class);
138 doReturn(true).when(mockAuth).isServerAllowed();
139 doReturn("some-session-name").when(mockAuth).getSessionName();
140 doReturn(mockAuth).when(mockCallHomeAuthProv).provideAuth(mockSocketAddr, mockPublicKey);
141 doReturn(null).when(mockFactory).createIfNotExists(mockClientSession, mockAuth);
144 assertFalse(instance.verifyServerKey(mockClientSession, mockSocketAddr, mockPublicKey));
148 public void verificationOfTheServerKeyShouldFailIfTheServerIsNotAllowed() {
151 ClientSessionImpl mockClientSession = mock(ClientSessionImpl.class);
152 SocketAddress mockSocketAddr = mock(SocketAddress.class);
153 PublicKey mockPublicKey = mock(PublicKey.class);
155 doReturn(false).when(mockAuth).isServerAllowed();
156 doReturn(mockAuth).when(mockCallHomeAuthProv).provideAuth(mockSocketAddr, mockPublicKey);
157 doReturn("").when(mockClientSession).toString();
160 assertFalse(instance.verifyServerKey(mockClientSession, mockSocketAddr, mockPublicKey));
164 public void bindShouldStartTheClientAndBindTheAddress() throws IOException {
166 IoAcceptor mockAcceptor = mock(IoAcceptor.class);
167 IoServiceFactory mockMinaFactory = mock(IoServiceFactory.class);
169 doReturn(mockAcceptor).when(mockMinaFactory).createAcceptor(any(IoHandler.class));
170 doNothing().when(mockAcceptor).bind(any(SocketAddress.class));
171 instance = new NetconfCallHomeServer(
172 mockSshClient, mockCallHomeAuthProv, mockFactory, MOCK_ADDRESS, mockStatusRecorder, mockMinaFactory);
176 verify(mockSshClient, times(1)).start();
177 verify(mockAcceptor, times(1)).bind(MOCK_ADDRESS);