using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Renci.SshNet.Channels; using Renci.SshNet.Common; using Renci.SshNet.Tests.Common; namespace Renci.SshNet.Tests.Classes { [TestClass] public class ForwardedPortDynamicTest_Started_SocketVersionNotSupported { private Mock _sessionMock; private Mock _channelMock; private Mock _connectionInfoMock; private ForwardedPortDynamic _forwardedPort; private Socket _client; private IList _closingRegister; private IList _exceptionRegister; private ManualResetEvent _exceptionFired; private TimeSpan _connectionTimeout; [TestInitialize] public void Initialize() { Arrange(); Act(); } [TestCleanup] public void Cleanup() { if (_forwardedPort != null && _forwardedPort.IsStarted) { _sessionMock.Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); _connectionInfoMock.Setup(p => p.Timeout).Returns(TimeSpan.FromSeconds(5)); _forwardedPort.Stop(); } if (_client != null) { _client.Close(); _client = null; } if (_exceptionFired != null) { _exceptionFired.Dispose(); _exceptionFired = null; } } private void SetupData() { _closingRegister = new List(); _exceptionRegister = new List(); _exceptionFired = new ManualResetEvent(false); _connectionTimeout = TimeSpan.FromSeconds(5); } private void CreateMocks() { _sessionMock = new Mock(MockBehavior.Strict); _channelMock = new Mock(MockBehavior.Strict); _connectionInfoMock = new Mock(MockBehavior.Strict); } private void SetupMocks() { var seq = new MockSequence(); _sessionMock.InSequence(seq).Setup(p => p.IsConnected).Returns(true); _sessionMock.InSequence(seq).Setup(p => p.CreateChannelDirectTcpip()).Returns(_channelMock.Object); _sessionMock.InSequence(seq).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); _connectionInfoMock.InSequence(seq).Setup(p => p.Timeout).Returns(_connectionTimeout); _channelMock.InSequence(seq).Setup(p => p.Dispose()); } private void Arrange() { SetupData(); CreateMocks(); SetupMocks(); _forwardedPort = new ForwardedPortDynamic(8122); _forwardedPort.Closing += (sender, args) => _closingRegister.Add(args); _forwardedPort.Exception += (sender, args) => { _exceptionRegister.Add(args); _exceptionFired.Set(); }; _forwardedPort.Session = _sessionMock.Object; _forwardedPort.Start(); var endPoint = new IPEndPoint(IPAddress.Loopback, 8122); _client = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _client.Connect(endPoint); } private void Act() { var buffer = new byte[] { 0x07 }; _client.Send(buffer, 0, buffer.Length, SocketFlags.None); // wait for Exception event to be fired as a way to ensure that SOCKS // request has been handled completely _exceptionFired.WaitOne(TimeSpan.FromMilliseconds(200)); } [TestMethod] public void SocketShouldBeConnected() { Assert.IsTrue(_client.Connected); } [TestMethod] public void ForwardedPortShouldShutdownSendOnSocket() { var buffer = new byte[1]; var bytesReceived = _client.Receive(buffer, 0, buffer.Length, SocketFlags.None); Assert.AreEqual(0, bytesReceived); } [TestMethod] public void ClosingShouldNotHaveFired() { Assert.AreEqual(0, _closingRegister.Count); } [TestMethod] public void ExceptionShouldHaveFiredOnce() { Assert.AreEqual(1, _exceptionRegister.Count, _exceptionRegister.AsString()); var exception = _exceptionRegister[0].Exception; Assert.IsNotNull(exception); var notSupportedException = exception as NotSupportedException; Assert.IsNotNull(notSupportedException, exception.ToString()); Assert.AreEqual("SOCKS version 7 is not supported.", notSupportedException.Message); } [TestMethod] public void CreateChannelDirectTcpipOnSessionShouldBeInvokedOnce() { _sessionMock.Verify(p => p.CreateChannelDirectTcpip(), Times.Once); } [TestMethod] public void DisposeOnChannelShouldBeInvokedOnce() { _channelMock.Verify(p => p.Dispose(), Times.Once); } } }