|
|
@@ -0,0 +1,157 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Threading;
|
|
|
+using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
|
+using Moq;
|
|
|
+using Renci.SshNet.Common;
|
|
|
+using Renci.SshNet.Messages.Connection;
|
|
|
+
|
|
|
+namespace Renci.SshNet.Tests.Classes.Channels
|
|
|
+{
|
|
|
+ [TestClass]
|
|
|
+ public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_OperationTimeoutExceptionWaitingForChannelCloseMessage
|
|
|
+ {
|
|
|
+ private Mock<ISession> _sessionMock;
|
|
|
+ private uint _localChannelNumber;
|
|
|
+ private uint _localWindowSize;
|
|
|
+ private uint _localPacketSize;
|
|
|
+ private uint _remoteChannelNumber;
|
|
|
+ private uint _remoteWindowSize;
|
|
|
+ private uint _remotePacketSize;
|
|
|
+ private ChannelStub _channel;
|
|
|
+ private List<ChannelEventArgs> _channelClosedRegister;
|
|
|
+ private List<ChannelEventArgs> _channelEndOfDataRegister;
|
|
|
+ private IList<ExceptionEventArgs> _channelExceptionRegister;
|
|
|
+ private SshOperationTimeoutException _operationTimeoutException;
|
|
|
+ private SshOperationTimeoutException _actualException;
|
|
|
+
|
|
|
+ private void SetupData()
|
|
|
+ {
|
|
|
+ var random = new Random();
|
|
|
+
|
|
|
+ _localChannelNumber = (uint)random.Next(0, int.MaxValue);
|
|
|
+ _localWindowSize = (uint)random.Next(0, int.MaxValue);
|
|
|
+ _localPacketSize = (uint)random.Next(0, int.MaxValue);
|
|
|
+ _remoteChannelNumber = (uint)random.Next(0, int.MaxValue);
|
|
|
+ _remoteWindowSize = (uint)random.Next(0, int.MaxValue);
|
|
|
+ _remotePacketSize = (uint)random.Next(0, int.MaxValue);
|
|
|
+ _channelClosedRegister = new List<ChannelEventArgs>();
|
|
|
+ _channelEndOfDataRegister = new List<ChannelEventArgs>();
|
|
|
+ _channelExceptionRegister = new List<ExceptionEventArgs>();
|
|
|
+ _operationTimeoutException = new SshOperationTimeoutException();
|
|
|
+ _actualException = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void CreateMocks()
|
|
|
+ {
|
|
|
+ _sessionMock = new Mock<ISession>(MockBehavior.Strict);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetupMocks()
|
|
|
+ {
|
|
|
+ var sequence = new MockSequence();
|
|
|
+
|
|
|
+ _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true);
|
|
|
+ _sessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is<ChannelCloseMessage>(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true);
|
|
|
+ _sessionMock.InSequence(sequence).Setup(p => p.WaitOnHandle(It.IsAny<EventWaitHandle>()))
|
|
|
+ .Callback<WaitHandle>(w =>
|
|
|
+ {
|
|
|
+ throw _operationTimeoutException;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ [TestInitialize]
|
|
|
+ public void Initialize()
|
|
|
+ {
|
|
|
+ Arrange();
|
|
|
+ Act();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Arrange()
|
|
|
+ {
|
|
|
+ SetupData();
|
|
|
+ CreateMocks();
|
|
|
+ SetupMocks();
|
|
|
+
|
|
|
+ _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
|
|
|
+ _channel.Closed += (sender, args) =>
|
|
|
+ {
|
|
|
+ _channelClosedRegister.Add(args);
|
|
|
+ };
|
|
|
+ _channel.EndOfData += (sender, args) => _channelEndOfDataRegister.Add(args);
|
|
|
+ _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args);
|
|
|
+ _channel.InitializeRemoteChannelInfo(_remoteChannelNumber, _remoteWindowSize, _remotePacketSize);
|
|
|
+ _channel.SetIsOpen(true);
|
|
|
+
|
|
|
+ _sessionMock.Raise(
|
|
|
+ s => s.ChannelEofReceived += null,
|
|
|
+ new MessageEventArgs<ChannelEofMessage>(new ChannelEofMessage(_localChannelNumber)));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Act()
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ _channel.Dispose();
|
|
|
+ }
|
|
|
+ catch (SshOperationTimeoutException ex)
|
|
|
+ {
|
|
|
+ _actualException = ex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [TestMethod]
|
|
|
+ public void IsOpenShouldReturnTrue()
|
|
|
+ {
|
|
|
+ Assert.IsTrue(_channel.IsOpen);
|
|
|
+ }
|
|
|
+
|
|
|
+ [TestMethod]
|
|
|
+ public void TrySendMessageOnSessionShouldBeInvokedOnceForChannelCloseMessage()
|
|
|
+ {
|
|
|
+ _sessionMock.Verify(
|
|
|
+ p => p.TrySendMessage(It.Is<ChannelCloseMessage>(c => c.LocalChannelNumber == _remoteChannelNumber)),
|
|
|
+ Times.Once);
|
|
|
+ }
|
|
|
+
|
|
|
+ [TestMethod]
|
|
|
+ public void TrySendMessageOnSessionShouldNeverBeInvokedForChannelEofMessage()
|
|
|
+ {
|
|
|
+ _sessionMock.Verify(
|
|
|
+ p => p.TrySendMessage(It.Is<ChannelEofMessage>(c => c.LocalChannelNumber == _remoteChannelNumber)),
|
|
|
+ Times.Never);
|
|
|
+ }
|
|
|
+
|
|
|
+ [TestMethod]
|
|
|
+ public void WaitOnHandleOnSessionShouldBeInvokedOnce()
|
|
|
+ {
|
|
|
+ _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny<EventWaitHandle>()), Times.Once);
|
|
|
+ }
|
|
|
+
|
|
|
+ [TestMethod]
|
|
|
+ public void ClosedEventShouldNotHaveFired()
|
|
|
+ {
|
|
|
+ Assert.AreEqual(0, _channelClosedRegister.Count);
|
|
|
+ }
|
|
|
+
|
|
|
+ [TestMethod]
|
|
|
+ public void EndOfDataEventShouldNotHaveFired()
|
|
|
+ {
|
|
|
+ Assert.AreEqual(1, _channelEndOfDataRegister.Count);
|
|
|
+ Assert.AreEqual(_localChannelNumber, _channelEndOfDataRegister[0].ChannelNumber);
|
|
|
+ }
|
|
|
+
|
|
|
+ [TestMethod]
|
|
|
+ public void ExceptionShouldNeverHaveFired()
|
|
|
+ {
|
|
|
+ Assert.AreEqual(0, _channelExceptionRegister.Count);
|
|
|
+ }
|
|
|
+
|
|
|
+ [TestMethod]
|
|
|
+ public void DisposeShouldHaveThrownOperationTimeoutException()
|
|
|
+ {
|
|
|
+ Assert.IsNotNull(_actualException);
|
|
|
+ Assert.AreSame(_operationTimeoutException, _actualException);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|