using System; using System.Collections.Generic; using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using Renci.SshNet.Channels; using Renci.SshNet.Common; using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] public class ChannelSessionTest_Close_Closed { private Mock _sessionMock; private Mock _connectionInfoMock; private ChannelSession _channel; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteWindowSize; private uint _remotePacketSize; private uint _remoteChannelNumber; private SemaphoreLight _sessionSemaphore; private IList _channelClosedRegister; private List _channelExceptionRegister; [TestInitialize] public void Initialize() { Arrange(); Act(); } private void Arrange() { var random = new Random(); _localChannelNumber = (uint)random.Next(0, int.MaxValue); _localWindowSize = (uint)random.Next(2000, 3000); _localPacketSize = (uint)random.Next(1000, 2000); _remoteChannelNumber = (uint)random.Next(0, int.MaxValue); _remoteWindowSize = (uint)random.Next(0, int.MaxValue); _remotePacketSize = (uint)random.Next(100, 200); _sessionSemaphore = new SemaphoreLight(1); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _sessionMock = new Mock(MockBehavior.Strict); _connectionInfoMock = new Mock(MockBehavior.Strict); var sequence = new MockSequence(); _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(1); _sessionMock.Setup(p => p.SessionSemaphore).Returns(_sessionSemaphore); _sessionMock.InSequence(sequence) .Setup( p => p.SendMessage( It.Is( m => m.LocalChannelNumber == _localChannelNumber && m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize && m.Info is SessionChannelOpenInfo))); _sessionMock.InSequence(sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull())) .Callback( w => { _sessionMock.Raise( s => s.ChannelOpenConfirmationReceived += null, new MessageEventArgs( new ChannelOpenConfirmationMessage( _localChannelNumber, _remoteWindowSize, _remotePacketSize, _remoteChannelNumber))); w.WaitOne(); }); _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); _sessionMock.InSequence(sequence) .Setup(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber))).Returns(true); _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); _sessionMock.InSequence(sequence) .Setup(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber))).Returns(true); _sessionMock.InSequence(sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull())) .Callback( w => { _sessionMock.Raise( s => s.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); w.WaitOne(); }); _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); _channel.Close(); } protected virtual void Act() { _channel.Close(); } internal ChannelSession Channel { get { return _channel; } } [TestMethod] public void ChannelEofMessageShouldBeSentOnce() { _sessionMock.Verify(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } [TestMethod] public void ChannelCloseMessageShouldBeSentOnce() { _sessionMock.Verify(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } [TestMethod] public void ExceptionShouldNeverHaveFired() { Assert.AreEqual(0, _channelExceptionRegister.Count); } [TestMethod] public void ClosedEventShouldHaveFiredOnce() { Assert.AreEqual(1, _channelClosedRegister.Count); Assert.AreEqual(_localChannelNumber, _channelClosedRegister[0].ChannelNumber); } [TestMethod] public void IsOpenShouldReturnFalse() { Assert.IsFalse(_channel.IsOpen); } } }