/* * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * 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.impl; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.verify; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.embedded.EmbeddedChannel; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.opendaylight.netconf.api.NetconfMessage; import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader; import org.opendaylight.netconf.api.xml.XmlUtil; import org.opendaylight.netconf.nettyutil.AbstractChannelInitializer; import org.opendaylight.netconf.nettyutil.handler.NetconfEXICodec; import org.opendaylight.netconf.nettyutil.handler.NetconfEXIToMessageDecoder; import org.opendaylight.netconf.nettyutil.handler.NetconfMessageToEXIEncoder; import org.opendaylight.netconf.nettyutil.handler.NetconfMessageToXMLEncoder; import org.opendaylight.netconf.nettyutil.handler.NetconfXMLToMessageDecoder; import org.opendaylight.netconf.nettyutil.handler.exi.EXIParameters; import org.opendaylight.netconf.notifications.NetconfNotification; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.NetconfTcp; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfSsh; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session; import org.w3c.dom.Document; public class NetconfServerSessionTest { private static final String HOST = "127.0.0.1"; private static final String PORT = "17830"; private static final String SSH_TRANSPORT = "ssh"; private static final String TCP_TRANSPORT = "tcp"; private static final String SESSION_ID = "1"; private static final String USER = "admin"; private NetconfServerSession session; private EmbeddedChannel channel; private NetconfMessage msg; @Mock private NetconfServerSessionListener listener; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); final NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader(USER, HOST, PORT, SSH_TRANSPORT, SESSION_ID); channel = new EmbeddedChannel(); session = new NetconfServerSession(listener, channel, 1L, header); doNothing().when(listener).onSessionUp(any()); msg = new NetconfMessage(XmlUtil.readXmlToDocument("")); } @Test public void testSessionUp() throws Exception { session.sessionUp(); verify(listener).onSessionUp(session); } @Test public void testDelayedClose() throws Exception { doNothing().when(listener).onSessionTerminated(eq(session), any()); session.delayedClose(); session.sendMessage(msg); channel.runPendingTasks(); final Object o = channel.readOutbound(); Assert.assertEquals(msg, o); verify(listener).onSessionTerminated(eq(session), any()); } @Test public void testSendMessage() throws Exception { session.sendMessage(msg); channel.runPendingTasks(); final Object o = channel.readOutbound(); Assert.assertEquals(msg, o); } @Test public void testSendNotification() throws Exception { doNothing().when(listener).onNotification(any(), any()); final Document msgDoc = XmlUtil.readXmlToDocument(""); final NetconfNotification notif = new NetconfNotification(msgDoc); session.sendMessage(notif); channel.runPendingTasks(); final Object o = channel.readOutbound(); Assert.assertEquals(notif, o); verify(listener).onNotification(session, notif); } @Test public void testOnIncommingRpcSuccess() throws Exception { session.sessionUp(); final Session managementSession = this.session.toManagementSession(); this.session.onIncommingRpcSuccess(); final Session afterRpcSuccess = this.session.toManagementSession(); Assert.assertEquals(managementSession.getInRpcs().getValue() + 1, afterRpcSuccess.getInRpcs().getValue().longValue()); } @Test public void testOnIncommingRpcFail() throws Exception { session.sessionUp(); final Session managementSession = this.session.toManagementSession(); this.session.onIncommingRpcFail(); final Session afterRpcSuccess = this.session.toManagementSession(); Assert.assertEquals(managementSession.getInBadRpcs().getValue() + 1, afterRpcSuccess.getInBadRpcs().getValue().longValue()); } @Test public void testOnOutgoingRpcError() throws Exception { session.sessionUp(); final Session managementSession = this.session.toManagementSession(); this.session.onOutgoingRpcError(); final Session afterRpcSuccess = this.session.toManagementSession(); Assert.assertEquals(managementSession.getOutRpcErrors().getValue() + 1, afterRpcSuccess.getOutRpcErrors().getValue().longValue()); } @Test public void testToManagementSession() throws Exception { final NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader(USER, HOST, PORT, TCP_TRANSPORT, SESSION_ID); final EmbeddedChannel ch = new EmbeddedChannel(); final NetconfServerSession tcpSession = new NetconfServerSession(listener, ch, 1L, header); tcpSession.sessionUp(); final Session managementSession = tcpSession.toManagementSession(); Assert.assertEquals(HOST, managementSession.getSourceHost().getIpAddress().getIpv4Address().getValue()); Assert.assertEquals(managementSession.getUsername(), USER); Assert.assertEquals(managementSession.getSessionId().toString(), SESSION_ID); Assert.assertEquals(managementSession.getTransport(), NetconfTcp.class); } @Test(expected = IllegalArgumentException.class) public void testToManagementSessionUnknownTransport() throws Exception { final NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader(USER, HOST, PORT, "http", SESSION_ID); final EmbeddedChannel ch = new EmbeddedChannel(); final NetconfServerSession tcpSession = new NetconfServerSession(listener, ch, 1L, header); tcpSession.sessionUp(); tcpSession.toManagementSession(); tcpSession.close(); } @Test public void testToManagementSessionIpv6() throws Exception { final NetconfHelloMessageAdditionalHeader header = new NetconfHelloMessageAdditionalHeader(USER, "::1", PORT, SSH_TRANSPORT, SESSION_ID); final EmbeddedChannel ch = new EmbeddedChannel(); final NetconfServerSession tcpSession = new NetconfServerSession(listener, ch, 1L, header); tcpSession.sessionUp(); final Session managementSession = tcpSession.toManagementSession(); Assert.assertEquals("::1", managementSession.getSourceHost().getIpAddress().getIpv6Address().getValue()); Assert.assertEquals(managementSession.getUsername(), USER); Assert.assertEquals(managementSession.getSessionId().toString(), SESSION_ID); Assert.assertEquals(managementSession.getTransport(), NetconfSsh.class); } @Test public void testThisInstance() throws Exception { Assert.assertEquals(session, session.thisInstance()); } @Test public void testAddExiHandlers() throws Exception { channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new NetconfXMLToMessageDecoder()); channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, new NetconfMessageToXMLEncoder()); final NetconfEXICodec codec = NetconfEXICodec.forParameters(EXIParameters.empty()); session.addExiHandlers(NetconfEXIToMessageDecoder.create(codec), NetconfMessageToEXIEncoder.create(codec)); } @Test public void testStopExiCommunication() throws Exception { channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER, new ChannelInboundHandlerAdapter()); channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER, new ChannelOutboundHandlerAdapter()); session.stopExiCommunication(); //handler is replaced only after next send message call final ChannelHandler exiEncoder = channel.pipeline().get(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER); Assert.assertTrue(ChannelOutboundHandlerAdapter.class.equals(exiEncoder.getClass())); session.sendMessage(msg); channel.runPendingTasks(); final ChannelHandler decoder = channel.pipeline().get(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER); Assert.assertTrue(NetconfXMLToMessageDecoder.class.equals(decoder.getClass())); final ChannelHandler encoder = channel.pipeline().get(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER); Assert.assertTrue(NetconfMessageToXMLEncoder.class.equals(encoder.getClass())); } }