diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest.cs index 804e477a..1dce239e 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest.cs @@ -27,6 +27,7 @@ namespace Renci.SshNet.Tests.Classes.Channels private uint _remoteWindowSize; private uint _remotePacketSize; private uint _remoteChannelNumber; + private TimeSpan _channelCloseTimeout; protected override void OnInit() { @@ -40,8 +41,9 @@ namespace Renci.SshNet.Tests.Classes.Channels _port = (uint) random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort); _localChannelNumber = (uint) random.Next(0, int.MaxValue); _remoteWindowSize = (uint) random.Next(0, int.MaxValue); - _remotePacketSize = (uint)random.Next(100, 200); - _remoteChannelNumber = (uint)random.Next(0, int.MaxValue); + _remotePacketSize = (uint) random.Next(100, 200); + _remoteChannelNumber = (uint) random.Next(0, int.MaxValue); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _sessionMock = new Mock(MockBehavior.Strict); _forwardedPortMock = new Mock(MockBehavior.Strict); @@ -53,11 +55,14 @@ namespace Renci.SshNet.Tests.Classes.Channels { _sessionMock.Setup(p => p.IsConnected).Returns(true); _sessionMock.Setup(p => p.SendMessage(It.IsAny())) - .Callback(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null, - new MessageEventArgs( - new ChannelOpenConfirmationMessage(((ChannelOpenMessage)m).LocalChannelNumber, _remoteWindowSize, _remotePacketSize, _remoteChannelNumber)))); + .Callback(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null, + new MessageEventArgs( + new ChannelOpenConfirmationMessage(((ChannelOpenMessage) m).LocalChannelNumber, + _remoteWindowSize, + _remotePacketSize, + _remoteChannelNumber)))); _sessionMock.Setup(p => p.WaitOnHandle(It.IsAny())) - .Callback(p => p.WaitOne(Session.Infinite)); + .Callback(p => p.WaitOne(Session.Infinite)); var localPortEndPoint = new IPEndPoint(IPAddress.Loopback, 8122); using (var localPortListener = new AsyncSocketListener(localPortEndPoint)) @@ -65,25 +70,27 @@ namespace Renci.SshNet.Tests.Classes.Channels localPortListener.Start(); localPortListener.Connected += socket => - { - var channel = new ChannelDirectTcpip(_sessionMock.Object, _localChannelNumber, _localWindowSize, - _localPacketSize); - channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket); + { + var channel = new ChannelDirectTcpip(_sessionMock.Object, + _localChannelNumber, + _localWindowSize, + _localPacketSize); + channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket); - var closeForwardedPortThread = - new Thread(() => - { - // sleep for a short period to allow channel to actually start receiving from socket - Thread.Sleep(100); - // raise Closing event on forwarded port - _forwardedPortMock.Raise(p => p.Closing += null, EventArgs.Empty); - }); - closeForwardedPortThread.Start(); + var closeForwardedPortThread = + new Thread(() => + { + // sleep for a short period to allow channel to actually start receiving from socket + Thread.Sleep(100); + // raise Closing event on forwarded port + _forwardedPortMock.Raise(p => p.Closing += null, EventArgs.Empty); + }); + closeForwardedPortThread.Start(); - channel.Bind(); + channel.Bind(); - closeForwardedPortThread.Join(); - }; + closeForwardedPortThread.Join(); + }; var client = new Socket(localPortEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.Connect(localPortEndPoint); @@ -103,11 +110,14 @@ namespace Renci.SshNet.Tests.Classes.Channels { _sessionMock.Setup(p => p.IsConnected).Returns(true); _sessionMock.Setup(p => p.SendMessage(It.IsAny())) - .Callback(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null, - new MessageEventArgs( - new ChannelOpenConfirmationMessage(((ChannelOpenMessage)m).LocalChannelNumber, _remoteWindowSize, _remotePacketSize, _remoteChannelNumber)))); + .Callback(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null, + new MessageEventArgs( + new ChannelOpenConfirmationMessage(((ChannelOpenMessage) m).LocalChannelNumber, + _remoteWindowSize, + _remotePacketSize, + _remoteChannelNumber)))); _sessionMock.Setup(p => p.WaitOnHandle(It.IsAny())) - .Callback(p => p.WaitOne(Session.Infinite)); + .Callback(p => p.WaitOne(Session.Infinite)); var localPortEndPoint = new IPEndPoint(IPAddress.Loopback, 8122); using (var localPortListener = new AsyncSocketListener(localPortEndPoint)) @@ -116,19 +126,21 @@ namespace Renci.SshNet.Tests.Classes.Channels localPortListener.Connected += socket => { - var channel = new ChannelDirectTcpip(_sessionMock.Object, _localChannelNumber, _localWindowSize, - _localPacketSize); + var channel = new ChannelDirectTcpip(_sessionMock.Object, + _localChannelNumber, + _localWindowSize, + _localPacketSize); channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket); var signalSessionErrorOccurredThread = new Thread(() => - { - // sleep for a short period to allow channel to actually start receiving from socket - Thread.Sleep(100); - // raise ErrorOccured event on session - _sessionMock.Raise(s => s.ErrorOccured += null, - new ExceptionEventArgs(new SystemException())); - }); + { + // sleep for a short period to allow channel to actually start receiving from socket + Thread.Sleep(100); + // raise ErrorOccured event on session + _sessionMock.Raise(s => s.ErrorOccured += null, + new ExceptionEventArgs(new SystemException())); + }); signalSessionErrorOccurredThread.Start(); channel.Bind(); @@ -152,34 +164,49 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void SocketShouldBeClosedAndEofShouldBeSentToServerWhenClientShutsDownSocket() { - _sessionMock.Setup(p => p.IsConnected).Returns(true); - _sessionMock.Setup(p => p.SendMessage(It.IsAny())) - .Callback(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null, - new MessageEventArgs( - new ChannelOpenConfirmationMessage(((ChannelOpenMessage) m).LocalChannelNumber, - _remoteWindowSize, _remotePacketSize, _remoteChannelNumber)))); - _sessionMock.Setup(p => p.WaitOnHandle(It.IsAny())) - .Callback(p => p.WaitOne(Session.Infinite)); - _sessionMock.Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); - _connectionInfoMock.Setup(p => p.Timeout).Returns(TimeSpan.FromSeconds(60)); - _sessionMock.Setup(p => p.TrySendMessage(It.IsAny())) - .Returns(true) - .Callback( - m => new Thread(() => - { - Thread.Sleep(50); - _sessionMock.Raise(s => s.ChannelEofReceived += null, - new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); - }).Start()); - _sessionMock.Setup(p => p.TrySendMessage(It.IsAny())) - .Returns(true) - .Callback( - m => new Thread(() => - { - Thread.Sleep(50); - _sessionMock.Raise(s => s.ChannelCloseReceived += null, - new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); - }).Start()); + var sequence = new MockSequence(); + + _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + _sessionMock.InSequence(sequence) + .Setup(p => p.SendMessage(It.IsAny())) + .Callback(m => _sessionMock.Raise(p => p.ChannelOpenConfirmationReceived += null, + new MessageEventArgs( + new ChannelOpenConfirmationMessage(((ChannelOpenMessage) m).LocalChannelNumber, + _remoteWindowSize, + _remotePacketSize, + _remoteChannelNumber)))); + _sessionMock.InSequence(sequence) + .Setup(p => p.WaitOnHandle(It.IsAny())) + .Callback(p => p.WaitOne(Session.Infinite)); + _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + _sessionMock.InSequence(sequence) + .Setup(p => p.TrySendMessage(It.IsAny())) + .Returns(true) + .Callback( + m => new Thread(() => + { + Thread.Sleep(50); + _sessionMock.Raise(s => s.ChannelEofReceived += null, + new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); + }).Start()); + _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + _sessionMock.InSequence(sequence) + .Setup(p => p.TrySendMessage(It.IsAny())) + .Returns(true) + .Callback( + m => new Thread(() => + { + Thread.Sleep(50); + _sessionMock.Raise(s => s.ChannelCloseReceived += null, + new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); + }).Start()); + _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); + _connectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + _sessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsAny(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => waitHandle.WaitOne()) + .Returns(WaitResult.Success); + var channelBindFinishedWaitHandle = new ManualResetEvent(false); Socket handler = null; ChannelDirectTcpip channel = null; @@ -190,17 +217,19 @@ namespace Renci.SshNet.Tests.Classes.Channels localPortListener.Start(); localPortListener.Connected += socket => - { - channel = new ChannelDirectTcpip(_sessionMock.Object, _localChannelNumber, _localWindowSize, - _localPacketSize); - channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket); - channel.Bind(); - channel.Dispose(); + { + channel = new ChannelDirectTcpip(_sessionMock.Object, + _localChannelNumber, + _localWindowSize, + _localPacketSize); + channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket); + channel.Bind(); + channel.Dispose(); - handler = socket; + handler = socket; - channelBindFinishedWaitHandle.Set(); - }; + channelBindFinishedWaitHandle.Set(); + }; var client = new Socket(localPortEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); client.Connect(localPortEndPoint); diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs index a99adce1..a75d407d 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs @@ -18,6 +18,7 @@ namespace Renci.SshNet.Tests.Classes.Channels public class ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen { private Mock _sessionMock; + private Mock _connectionInfoMock; private Mock _forwardedPortMock; private ChannelDirectTcpip _channel; private uint _localChannelNumber; @@ -26,6 +27,7 @@ namespace Renci.SshNet.Tests.Classes.Channels private uint _remoteWindowSize; private uint _remotePacketSize; private uint _remoteChannelNumber; + private TimeSpan _channelCloseTimeout; private string _remoteHost; private uint _port; private AsyncSocketListener _listener; @@ -60,9 +62,11 @@ namespace Renci.SshNet.Tests.Classes.Channels 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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _remoteHost = random.Next().ToString(CultureInfo.InvariantCulture); _port = (uint) random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort); _channelBindFinishedWaitHandle = new ManualResetEvent(false); @@ -74,6 +78,7 @@ namespace Renci.SshNet.Tests.Classes.Channels _remotePacketSize = (uint)random.Next(100, 200); _sessionMock = new Mock(MockBehavior.Strict); + _connectionInfoMock = new Mock(MockBehavior.Strict); _forwardedPortMock = new Mock(MockBehavior.Strict); var sequence = new MockSequence(); @@ -102,19 +107,20 @@ namespace Renci.SshNet.Tests.Classes.Channels .Returns(true); _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); _sessionMock.InSequence(sequence) - .Setup( - p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber))) + .Setup(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber))) .Returns(true); + _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); + _connectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); _sessionMock.InSequence(sequence) - .Setup(p => p.WaitOnHandle(It.IsNotNull())) - .Callback( - w => - { - _sessionMock.Raise( - s => s.ChannelCloseReceived += null, - new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); - w.WaitOne(); - }); + .Setup(p => p.TryWait(It.IsAny(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => + { + _sessionMock.Raise( + s => s.ChannelCloseReceived += null, + new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); + waitHandle.WaitOne(); + }) + .Returns(WaitResult.Success); var localEndpoint = new IPEndPoint(IPAddress.Loopback, 8122); _listener = new AsyncSocketListener(localEndpoint); @@ -122,11 +128,10 @@ namespace Renci.SshNet.Tests.Classes.Channels { try { - _channel = new ChannelDirectTcpip( - _sessionMock.Object, - _localChannelNumber, - _localWindowSize, - _localPacketSize); + _channel = new ChannelDirectTcpip(_sessionMock.Object, + _localChannelNumber, + _localWindowSize, + _localPacketSize); _channel.Open(_remoteHost, _port, _forwardedPortMock.Object, socket); _channel.Bind(); } diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs index 2ec4c9c9..bbbff6d3 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs @@ -25,6 +25,7 @@ namespace Renci.SshNet.Tests.Classes.Channels private uint _remoteWindowSize; private uint _remotePacketSize; private uint _remoteChannelNumber; + private TimeSpan _channelCloseTimeout; private IPEndPoint _remoteEndpoint; private AsyncSocketListener _remoteListener; private EventWaitHandle _channelBindFinishedWaitHandle; @@ -72,6 +73,7 @@ namespace Renci.SshNet.Tests.Classes.Channels _remoteChannelNumber = (uint) random.Next(0, int.MaxValue); _remoteWindowSize = (uint) random.Next(0, int.MaxValue); _remotePacketSize = (uint) random.Next(100, 200); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _channelBindFinishedWaitHandle = new ManualResetEvent(false); _channelException = null; _connectedRegister = new List(); @@ -109,16 +111,18 @@ namespace Renci.SshNet.Tests.Classes.Channels .Setup( p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber))) .Returns(true); + _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); + _connectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); _sessionMock.InSequence(sequence) - .Setup(p => p.WaitOnHandle(It.IsNotNull())) - .Callback( - w => + .Setup(p => p.TryWait(It.IsAny(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => { _sessionMock.Raise( s => s.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); - w.WaitOne(); - }); + waitHandle.WaitOne(); + }) + .Returns(WaitResult.Success); _remoteListener = new AsyncSocketListener(_remoteEndpoint); _remoteListener.Connected += socket => _connectedRegister.Add(socket); diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTestBase.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTestBase.cs new file mode 100644 index 00000000..52dfabb9 --- /dev/null +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTestBase.cs @@ -0,0 +1,37 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace Renci.SshNet.Tests.Classes.Channels +{ + public abstract class ChannelSessionTestBase + { + internal Mock SessionMock { get; private set; } + internal Mock ConnectionInfoMock { get; private set; } + + [TestInitialize] + public void Initialize() + { + Arrange(); + Act(); + } + + protected abstract void SetupData(); + + protected void CreateMocks() + { + SessionMock = new Mock(MockBehavior.Strict); + ConnectionInfoMock = new Mock(MockBehavior.Strict); + } + + protected abstract void SetupMocks(); + + protected virtual void Arrange() + { + SetupData(); + CreateMocks(); + SetupMocks(); + } + + protected abstract void Act(); + } +} diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs index 75461290..379f7e18 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_Disposed.cs @@ -10,10 +10,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_Disposed + public class ChannelSessionTest_Dispose_Disposed : ChannelSessionTestBase { - private Mock _sessionMock; - private Mock _connectionInfoMock; private ChannelSession _channel; private uint _localChannelNumber; private uint _localWindowSize; @@ -21,38 +19,35 @@ namespace Renci.SshNet.Tests.Classes.Channels private uint _remoteWindowSize; private uint _remotePacketSize; private uint _remoteChannelNumber; + private TimeSpan _channelCloseTimeout; private SemaphoreLight _sessionSemaphore; private IList _channelClosedRegister; private List _channelExceptionRegister; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { 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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _sessionSemaphore = new SemaphoreLight(1); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { 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) + + 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( @@ -61,12 +56,12 @@ namespace Renci.SshNet.Tests.Classes.Channels m.LocalChannelNumber == _localChannelNumber && m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize && m.Info is SessionChannelOpenInfo))); - _sessionMock.InSequence(sequence) + SessionMock.InSequence(sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull())) .Callback( w => { - _sessionMock.Raise( + SessionMock.Raise( s => s.ChannelOpenConfirmationReceived += null, new MessageEventArgs( new ChannelOpenConfirmationMessage( @@ -76,31 +71,39 @@ namespace Renci.SshNet.Tests.Classes.Channels _remoteChannelNumber))); w.WaitOne(); }); - _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(sequence) + 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) + 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(); - }); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsNotNull(), _channelCloseTimeout)) + .Callback( + (waitHandle, channelCloseTimeout) => + { + SessionMock.Raise( + s => s.ChannelCloseReceived += null, + new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); + waitHandle.WaitOne(); + }) + .Returns(WaitResult.Success); + } - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _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.Dispose(); } - protected virtual void Act() + protected override void Act() { _channel.Dispose(); } @@ -113,13 +116,13 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void ChannelEofMessageShouldBeSentOnce() { - _sessionMock.Verify(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber)), Times.Once); + 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); + SessionMock.Verify(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } [TestMethod] diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler.cs index 35e70ac3..be4fdc30 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler.cs @@ -11,52 +11,47 @@ using Renci.SshNet.Tests.Common; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler + public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_DisposeInEventHandler : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { _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) + + 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( @@ -65,12 +60,12 @@ namespace Renci.SshNet.Tests.Classes.Channels m.LocalChannelNumber == _localChannelNumber && m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize && m.Info is SessionChannelOpenInfo))); - _sessionMock.InSequence(_sequence) + SessionMock.InSequence(_sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull())) .Callback( w => { - _sessionMock.Raise( + SessionMock.Raise( s => s.ChannelOpenConfirmationReceived += null, new MessageEventArgs( new ChannelOpenConfirmationMessage( @@ -80,15 +75,23 @@ namespace Renci.SshNet.Tests.Classes.Channels _remoteChannelNumber))); w.WaitOne(); }); - _sessionMock.InSequence(_sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(_sequence) + SessionMock.InSequence(_sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(_sequence) .Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) .Returns(true); - _sessionMock.InSequence(_sequence) - .Setup(s => s.WaitOnHandle(It.IsNotNull())) - .Callback(w => w.WaitOne()); + SessionMock.InSequence(_sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(_sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(_sequence) + .Setup(p => p.TryWait(It.IsNotNull(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => waitHandle.WaitOne()) + .Returns(WaitResult.Success); + } - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => { _channelClosedRegister.Add(args); @@ -97,13 +100,13 @@ namespace Renci.SshNet.Tests.Classes.Channels _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); - _sessionMock.Raise(p => p.ChannelEofReceived += null, + SessionMock.Raise(p => p.ChannelEofReceived += null, new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); - _sessionMock.Raise(p => p.ChannelCloseReceived += null, + SessionMock.Raise(p => p.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -133,4 +136,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.IsFalse(_channel.IsOpen); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs index 4f5590f4..aac5c837 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure.cs @@ -10,9 +10,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure + public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageFailure : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; @@ -22,83 +21,82 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { _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.Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(_sequence) - .Setup( - p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) - .Returns(false); - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + 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.Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(_sequence) + .Setup( + p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) + .Returns(false); + } + + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelEofReceived += null, new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -128,4 +126,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.IsFalse(_channel.IsOpen); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs index 8f007fb3..dd17c5ab 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess.cs @@ -11,98 +11,100 @@ using Renci.SshNet.Tests.Common; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess + public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived_SendChannelCloseMessageSuccess : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; - private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + var sequence = new MockSequence(); - _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(c => c.LocalChannelNumber == _remoteChannelNumber))) - .Returns(true); - _sessionMock.InSequence(_sequence) - .Setup(s => s.WaitOnHandle(It.IsNotNull())) - .Callback(w => w.WaitOne()); + 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(c => c.LocalChannelNumber == _remoteChannelNumber))) + .Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsNotNull(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => waitHandle.WaitOne()) + .Returns(WaitResult.Success); + } - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelEofReceived += null, new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -132,4 +134,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.IsFalse(_channel.IsOpen); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs index 049d90f1..251adf5d 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure.cs @@ -10,9 +10,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure + public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageFailure : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; @@ -22,80 +21,79 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { _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.Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(_sequence) - .Setup( - p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) - .Returns(false); - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + 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.Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(_sequence) + .Setup( + p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) + .Returns(false); + } + + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -125,4 +123,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.IsFalse(_channel.IsOpen); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs index dcb0a8fb..37dff92f 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess.cs @@ -11,52 +11,46 @@ using Renci.SshNet.Tests.Common; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess + public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelCloseReceived_SendChannelCloseMessageSuccess : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; - private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + var sequence = new MockSequence(); - _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) + 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( @@ -65,12 +59,12 @@ namespace Renci.SshNet.Tests.Classes.Channels m.LocalChannelNumber == _localChannelNumber && m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize && m.Info is SessionChannelOpenInfo))); - _sessionMock.InSequence(_sequence) + SessionMock.InSequence(sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull())) .Callback( w => { - _sessionMock.Raise( + SessionMock.Raise( s => s.ChannelOpenConfirmationReceived += null, new MessageEventArgs( new ChannelOpenConfirmationMessage( @@ -80,26 +74,34 @@ namespace Renci.SshNet.Tests.Classes.Channels _remoteChannelNumber))); w.WaitOne(); }); - _sessionMock.InSequence(_sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(_sequence) + SessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence) .Setup( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) .Returns(true); - _sessionMock.InSequence(_sequence) - .Setup(s => s.WaitOnHandle(It.IsNotNull())) - .Callback(w => w.WaitOne()); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsNotNull(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => waitHandle.WaitOne()) + .Returns(WaitResult.Success); + } - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs index 3173232f..83b40b32 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure.cs @@ -10,9 +10,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure + public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageFailure : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; @@ -22,80 +21,78 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { _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.Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(_sequence) - .Setup( - p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) - .Returns(false); + 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.Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(_sequence) + .Setup( + p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) + .Returns(false); + } - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelEofReceived += null, new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -124,4 +121,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.IsFalse(_channel.IsOpen); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs index f0b7bd01..5ab59626 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess.cs @@ -10,52 +10,46 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess + public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_ChannelEofReceived_SendChannelCloseMessageSuccess : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; - private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + var sequence = new MockSequence(); - _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) + 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( @@ -64,12 +58,12 @@ namespace Renci.SshNet.Tests.Classes.Channels m.LocalChannelNumber == _localChannelNumber && m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize && m.Info is SessionChannelOpenInfo))); - _sessionMock.InSequence(_sequence) + SessionMock.InSequence(sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull())) .Callback( w => { - _sessionMock.Raise( + SessionMock.Raise( s => s.ChannelOpenConfirmationReceived += null, new MessageEventArgs( new ChannelOpenConfirmationMessage( @@ -79,33 +73,41 @@ namespace Renci.SshNet.Tests.Classes.Channels _remoteChannelNumber))); w.WaitOne(); }); - _sessionMock.Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(_sequence) + SessionMock.Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence) .Setup( p => p.TrySendMessage(It.Is(c => c.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(); - }); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsNotNull(), _channelCloseTimeout)) + .Callback( + (waitHandle, channelCloseTimeout) => + { + SessionMock.Raise( + s => s.ChannelCloseReceived += null, + new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); + waitHandle.WaitOne(); + }) + .Returns(WaitResult.Success); + } - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelEofReceived += null, new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs index fdd0e469..47c84903 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs @@ -10,10 +10,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived + public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived : ChannelSessionTestBase { - private Mock _sessionMock; - private Mock _connectionInfoMock; private ChannelSession _channel; private uint _localChannelNumber; private uint _localWindowSize; @@ -21,89 +19,94 @@ namespace Renci.SshNet.Tests.Classes.Channels private uint _remoteWindowSize; private uint _remotePacketSize; private uint _remoteChannelNumber; + private TimeSpan _channelCloseTimeout; private SemaphoreLight _sessionSemaphore; private IList _channelClosedRegister; private List _channelExceptionRegister; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { 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); + + _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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _sessionSemaphore = new SemaphoreLight(1); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { 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); + 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.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsNotNull(), _channelCloseTimeout)) + .Callback( + (waitHandle, channelCloseTimeout) => + { + SessionMock.Raise( + s => s.ChannelCloseReceived += null, + new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); + waitHandle.WaitOne(); + }) + .Returns(WaitResult.Success); + } + + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -111,13 +114,13 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void ChannelEofMessageShouldBeSentOnce() { - _sessionMock.Verify(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber)), Times.Once); + 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); + SessionMock.Verify(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } [TestMethod] diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs index 084d5b1d..ce733bbc 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure.cs @@ -10,10 +10,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure + public class ChannelSessionTest_Dispose_SessionIsConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived_SendChannelEofMessageFailure : ChannelSessionTestBase { - private Mock _sessionMock; - private Mock _connectionInfoMock; private ChannelSession _channel; private uint _localChannelNumber; private uint _localWindowSize; @@ -21,89 +19,93 @@ namespace Renci.SshNet.Tests.Classes.Channels private uint _remoteWindowSize; private uint _remotePacketSize; private uint _remoteChannelNumber; + private TimeSpan _channelCloseTimeout; private SemaphoreLight _sessionSemaphore; private IList _channelClosedRegister; private List _channelExceptionRegister; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { 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); + + _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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _sessionSemaphore = new SemaphoreLight(1); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { 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(false); - _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); + 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(false); + 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.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsNotNull(), _channelCloseTimeout)) + .Callback( + (waitHandle, channelCloseTimeout) => + { + SessionMock.Raise(s => s.ChannelCloseReceived += null, + new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); + waitHandle.WaitOne(); + }) + .Returns(WaitResult.Success); + } + + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -111,13 +113,13 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void ChannelEofMessageShouldBeSentOnce() { - _sessionMock.Verify(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber)), Times.Once); + 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); + SessionMock.Verify(p => p.TrySendMessage(It.Is(m => m.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } [TestMethod] diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs index b0407c3f..d44f4e0a 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived.cs @@ -10,9 +10,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived + public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseAndChannelEofReceived : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; @@ -22,79 +21,78 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { _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.Setup(p => p.IsConnected).Returns(false); - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + 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.Setup(p => p.IsConnected).Returns(false); + } + + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelEofReceived += null, new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -124,4 +122,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.IsFalse(_channel.IsOpen); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs index 7a16c21d..fedd4cd6 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived.cs @@ -10,9 +10,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived + public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_ChannelCloseReceived : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; @@ -22,76 +21,75 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { _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.Setup(p => p.IsConnected).Returns(false); - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + 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.Setup(p => p.IsConnected).Returns(false); + } + + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -121,4 +119,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.IsFalse(_channel.IsOpen); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs index ad14e13a..ce8fa16c 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived.cs @@ -10,9 +10,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived + public class ChannelSessionTest_Dispose_SessionIsNotConnectedAndChannelIsOpen_NoChannelCloseOrChannelEofReceived : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; @@ -22,72 +21,70 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { _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.Setup(p => p.IsConnected).Returns(false); + 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.Setup(p => p.IsConnected).Returns(false); + } - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -116,4 +113,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.IsFalse(_channel.IsOpen); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs index 130797cd..584c4e94 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen.cs @@ -11,52 +11,47 @@ using Renci.SshNet.Tests.Common; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen + public class ChannelSessionTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen : ChannelSessionTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private IList _channelClosedRegister; private List _channelExceptionRegister; private ChannelSession _channel; - private Mock _connectionInfoMock; private MockSequence _sequence; private SemaphoreLight _sessionSemaphore; private int _initialSessionSemaphoreCount; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { _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) + + 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( @@ -65,12 +60,12 @@ namespace Renci.SshNet.Tests.Classes.Channels m.LocalChannelNumber == _localChannelNumber && m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize && m.Info is SessionChannelOpenInfo))); - _sessionMock.InSequence(_sequence) + SessionMock.InSequence(_sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull())) .Callback( w => { - _sessionMock.Raise( + SessionMock.Raise( s => s.ChannelOpenConfirmationReceived += null, new MessageEventArgs( new ChannelOpenConfirmationMessage( @@ -80,24 +75,32 @@ namespace Renci.SshNet.Tests.Classes.Channels _remoteChannelNumber))); w.WaitOne(); }); - _sessionMock.InSequence(_sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(_sequence) + SessionMock.InSequence(_sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(_sequence) .Setup( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) .Returns(true); - _sessionMock.InSequence(_sequence) - .Setup(s => s.WaitOnHandle(It.IsNotNull())) - .Callback(w => w.WaitOne()); + SessionMock.InSequence(_sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(_sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(_sequence) + .Setup(p => p.TryWait(It.IsNotNull(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => waitHandle.WaitOne()) + .Returns(WaitResult.Success); + } - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.Open(); } - private void Act() + protected override void Act() { - _sessionMock.Raise( + SessionMock.Raise( p => p.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs index 54733501..fbb27e38 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation.cs @@ -10,10 +10,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation + public class ChannelSessionTest_Open_ExceptionWaitingOnOpenConfirmation : ChannelSessionTestBase { - private Mock _sessionMock; - private Mock _connectionInfoMock; private ChannelSession _channel; private uint _localChannelNumber; private uint _localWindowSize; @@ -25,51 +23,51 @@ namespace Renci.SshNet.Tests.Classes.Channels private Exception _waitOnConfirmationException; private SystemException _actualException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localChannelNumber = (uint)random.Next(0, int.MaxValue); - _localWindowSize = (uint)random.Next(2000, 3000); - _localPacketSize = (uint)random.Next(1000, 2000); + + _localChannelNumber = (uint) random.Next(0, int.MaxValue); + _localWindowSize = (uint) random.Next(2000, 3000); + _localPacketSize = (uint) random.Next(1000, 2000); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _waitOnConfirmationException = new SystemException(); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { var sequence = new MockSequence(); - _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); - _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(2); - _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())) - .Throws(_waitOnConfirmationException); - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(2); + 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())) + .Throws(_waitOnConfirmationException); + } + + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); } - private void Act() + protected override void Act() { try { @@ -84,7 +82,8 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void OpenShouldHaveRethrownExceptionThrownByWaitOnHandle() { - + Assert.IsNotNull(_actualException); + Assert.AreSame(_waitOnConfirmationException, _actualException); } [TestMethod] diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs index 870d8caa..ab4ba4f6 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable.cs @@ -11,10 +11,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable + public class ChannelSessionTest_Open_OnOpenFailureReceived_NoRetriesAvailable : ChannelSessionTestBase { - private Mock _sessionMock; - private Mock _connectionInfoMock; private ChannelSession _channel; private uint _localChannelNumber; private uint _localWindowSize; @@ -28,16 +26,10 @@ namespace Renci.SshNet.Tests.Classes.Channels private string _failureLanguage; private SshException _actualException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); + _localChannelNumber = (uint) random.Next(0, int.MaxValue); _localWindowSize = (uint) random.Next(2000, 3000); _localPacketSize = (uint) random.Next(1000, 2000); @@ -50,15 +42,16 @@ namespace Renci.SshNet.Tests.Classes.Channels _failureReasonCode = (uint)random.Next(0, int.MaxValue); _failureDescription = random.Next().ToString(CultureInfo.InvariantCulture); _failureLanguage = random.Next().ToString(CultureInfo.InvariantCulture); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { 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) + + 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( @@ -67,12 +60,12 @@ namespace Renci.SshNet.Tests.Classes.Channels m.LocalChannelNumber == _localChannelNumber && m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize && m.Info is SessionChannelOpenInfo))); - _sessionMock.InSequence(sequence) + SessionMock.InSequence(sequence) .Setup(p => p.WaitOnHandle(It.IsNotNull())) .Callback( w => { - _sessionMock.Raise( + SessionMock.Raise( s => s.ChannelOpenFailureReceived += null, new MessageEventArgs( new ChannelOpenFailureMessage( @@ -83,15 +76,20 @@ namespace Renci.SshNet.Tests.Classes.Channels ))); w.WaitOne(); }); - _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); - _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(1); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(1); + } - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); } - private void Act() + protected override void Act() { try { diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs index 4b1edc1d..e6caeb22 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable.cs @@ -11,10 +11,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable + public class ChannelSessionTest_Open_OnOpenFailureReceived_RetriesAvalable : ChannelSessionTestBase { - private Mock _sessionMock; - private Mock _connectionInfoMock; private ChannelSession _channel; private uint _localChannelNumber; private uint _localWindowSize; @@ -30,97 +28,97 @@ namespace Renci.SshNet.Tests.Classes.Channels private string _failureDescription; private string _failureLanguage; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { 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(0, int.MaxValue); + + _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(0, int.MaxValue); _initialSessionSemaphoreCount = random.Next(10, 20); _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); - _failureReasonCode = (uint)random.Next(0, int.MaxValue); + _failureReasonCode = (uint) random.Next(0, int.MaxValue); _failureDescription = random.Next().ToString(CultureInfo.InvariantCulture); _failureLanguage = random.Next().ToString(CultureInfo.InvariantCulture); + } - _sessionMock = new Mock(MockBehavior.Strict); - _connectionInfoMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { var sequence = new MockSequence(); - _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); - _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(2); - _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.ChannelOpenFailureReceived += null, - new MessageEventArgs( - new ChannelOpenFailureMessage( - _localChannelNumber, - _failureDescription, - _failureReasonCode, - _failureLanguage - ))); - w.WaitOne(); - }); - _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object); - _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(2); - _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(); - }); - _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(2); + 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.ChannelOpenFailureReceived += null, + new MessageEventArgs( + new ChannelOpenFailureMessage( + _localChannelNumber, + _failureDescription, + _failureReasonCode, + _failureLanguage + ))); + w.WaitOne(); + }); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(2); + 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(); + }); + } + + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelSession(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); } - private void Act() + protected override void Act() { _channel.Open(); } diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTestBase.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTestBase.cs new file mode 100644 index 00000000..f92810cc --- /dev/null +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTestBase.cs @@ -0,0 +1,37 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace Renci.SshNet.Tests.Classes.Channels +{ + public abstract class ChannelTestBase + { + internal Mock SessionMock { get; private set; } + internal Mock ConnectionInfoMock { get; private set; } + + [TestInitialize] + public void Initialize() + { + Arrange(); + Act(); + } + + protected abstract void SetupData(); + + protected void CreateMocks() + { + SessionMock = new Mock(MockBehavior.Strict); + ConnectionInfoMock = new Mock(MockBehavior.Strict); + } + + protected abstract void SetupMocks(); + + protected virtual void Arrange() + { + SetupData(); + CreateMocks(); + SetupMocks(); + } + + protected abstract void Act(); + } +} diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsNotOpen.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsNotOpen.cs index 67903d6e..8847ff7a 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsNotOpen.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsNotOpen.cs @@ -9,9 +9,8 @@ using Renci.SshNet.Messages; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsNotOpen + public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsNotOpen : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -19,32 +18,32 @@ namespace Renci.SshNet.Tests.Classes.Channels private List _channelClosedRegister; private IList _channelExceptionRegister; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _localChannelNumber = (uint) random.Next(0, int.MaxValue); + _localWindowSize = (uint) random.Next(0, int.MaxValue); + _localPacketSize = (uint) random.Next(0, int.MaxValue); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + SessionMock.Setup(p => p.IsConnected).Returns(true); + } - _sessionMock.Setup(p => p.IsConnected).Returns(true); + protected override void Arrange() + { + base.Arrange(); - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -58,7 +57,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void SendMessageOnSessionShouldNeverBeInvoked() { - _sessionMock.Verify(p => p.SendMessage(It.IsAny()), Times.Never); + SessionMock.Verify(p => p.SendMessage(It.IsAny()), Times.Never); } [TestMethod] @@ -73,4 +72,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreEqual(0, _channelExceptionRegister.Count); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs index d30f7f54..679e1b8a 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs @@ -10,85 +10,91 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived + public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private ChannelStub _channel; private Stopwatch _closeTimer; private ManualResetEvent _channelClosedEventHandlerCompleted; private List _channelClosedRegister; private IList _channelExceptionRegister; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _closeTimer = new Stopwatch(); _channelClosedRegister = new List(); _channelClosedEventHandlerCompleted = new ManualResetEvent(false); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { var sequence = new MockSequence(); - _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.WaitOnHandle(It.IsAny())) - .Callback(w => - { - new Thread(() => - { - Thread.Sleep(100); - // raise ChannelCloseReceived event to set waithandle for receiving - // SSH_MSG_CHANNEL_CLOSE message from server which is waited on after - // sending the SSH_MSG_CHANNEL_CLOSE message to the server - _sessionMock.Raise(s => s.ChannelCloseReceived += null, - new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); - }).Start(); - _closeTimer.Start(); - try - { - w.WaitOne(); - } - finally - { - _closeTimer.Stop(); - } - }); - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + SessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsAny(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => + { + new Thread(() => + { + Thread.Sleep(100); + // raise ChannelCloseReceived event to set waithandle for receiving + // SSH_MSG_CHANNEL_CLOSE message from server which is waited on after + // sending the SSH_MSG_CHANNEL_CLOSE message to the server + SessionMock.Raise(s => s.ChannelCloseReceived += null, + new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); + }).Start(); + _closeTimer.Start(); + try + { + waitHandle.WaitOne(); + } + finally + { + _closeTimer.Stop(); + } + }) + .Returns(WaitResult.Success); + } + + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => - { - _channelClosedRegister.Add(args); - Thread.Sleep(50); - _channelClosedEventHandlerCompleted.Set(); - }; + { + _channelClosedRegister.Add(args); + Thread.Sleep(50); + _channelClosedEventHandlerCompleted.Set(); + }; _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.InitializeRemoteChannelInfo(_remoteChannelNumber, _remoteWindowSize, _remotePacketSize); _channel.SetIsOpen(true); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -102,7 +108,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldBeInvokedOnceForChannelCloseMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } @@ -110,15 +116,15 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldBeInvokedOnceForChannelEofMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } [TestMethod] - public void WaitOnHandleOnSessionShouldBeInvokedOnce() + public void TryWaitOnSessionShouldBeInvokedOnce() { - _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny()), Times.Once); + SessionMock.Verify(p => p.TryWait(It.IsAny(), _channelCloseTimeout), Times.Once); } [TestMethod] @@ -146,4 +152,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreEqual(0, _channelExceptionRegister.Count); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs index 17af2e84..e59e95df 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs @@ -11,9 +11,8 @@ namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] [Ignore] - public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked + public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; @@ -26,13 +25,6 @@ namespace Renci.SshNet.Tests.Classes.Channels private List _channelClosedRegister; private IList _channelExceptionRegister; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - [TestCleanup] public void TearDown() { @@ -43,64 +35,72 @@ namespace Renci.SshNet.Tests.Classes.Channels } } - private void Arrange() + protected override 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); + + _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); _closeTimer = new Stopwatch(); _channelClosedEventHandlerCompleted = new ManualResetEvent(false); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { var sequence = new MockSequence(); - _sessionMock.InSequence(sequence).Setup(p => p.SendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))); - _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.WaitOnHandle(It.IsAny())) - .Callback(w => - { - new Thread(() => - { - Thread.Sleep(100); - // raise ChannelCloseReceived event to set waithandle for receiving - // SSH_MSG_CHANNEL_CLOSE message from server which is waited on after - // sending the SSH_MSG_CHANNEL_CLOSE message to the server - _sessionMock.Raise(s => s.ChannelCloseReceived += null, - new MessageEventArgs( - new ChannelCloseMessage(_localChannelNumber))); - }).Start(); - _closeTimer.Start(); - try - { - w.WaitOne(); - } - finally - { - _closeTimer.Stop(); - } - }); - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + SessionMock.InSequence(sequence).Setup(p => p.SendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))); + SessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.WaitOnHandle(It.IsAny())) + .Callback(w => + { + new Thread(() => + { + Thread.Sleep(100); + // raise ChannelCloseReceived event to set waithandle for receiving + // SSH_MSG_CHANNEL_CLOSE message from server which is waited on after + // sending the SSH_MSG_CHANNEL_CLOSE message to the server + SessionMock.Raise(s => s.ChannelCloseReceived += null, + new MessageEventArgs( + new ChannelCloseMessage(_localChannelNumber))); + }).Start(); + _closeTimer.Start(); + try + { + w.WaitOne(); + } + finally + { + _closeTimer.Stop(); + } + }); + } + + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => - { - _channelClosedRegister.Add(args); - Thread.Sleep(50); - _channelClosedEventHandlerCompleted.Set(); - }; + { + _channelClosedRegister.Add(args); + Thread.Sleep(50); + _channelClosedEventHandlerCompleted.Set(); + }; _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.InitializeRemoteChannelInfo(_remoteChannelNumber, _remoteWindowSize, _remotePacketSize); _channel.SetIsOpen(true); //_channel.SendEof(); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -114,7 +114,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldBeInvokedOnceForChannelCloseMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } @@ -122,7 +122,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void SendMessageOnSessionShouldBeInvokedOnceForChannelEofMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.SendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } @@ -130,7 +130,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void WaitOnHandleOnSessionShouldBeInvokedOnce() { - _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny()), Times.Once); + SessionMock.Verify(p => p.WaitOnHandle(It.IsAny()), Times.Once); } [TestMethod] @@ -158,4 +158,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreEqual(0, _channelExceptionRegister.Count); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs index 97f6a0ba..0bb9e862 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived.cs @@ -9,15 +9,15 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived + public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private ChannelStub _channel; private List _channelClosedRegister; private List _channelEndOfDataRegister; @@ -26,7 +26,7 @@ namespace Renci.SshNet.Tests.Classes.Channels private ManualResetEvent _channelClosedEventHandlerCompleted; private Thread _raiseChannelCloseReceivedThread; - private void SetupData() + protected override void SetupData() { var random = new Random(); @@ -36,6 +36,7 @@ namespace Renci.SshNet.Tests.Classes.Channels _remoteChannelNumber = (uint) random.Next(0, int.MaxValue); _remoteWindowSize = (uint) random.Next(0, int.MaxValue); _remotePacketSize = (uint) random.Next(0, int.MaxValue); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _channelClosedRegister = new List(); _channelEndOfDataRegister = new List(); _channelExceptionRegister = new List(); @@ -44,52 +45,44 @@ namespace Renci.SshNet.Tests.Classes.Channels _raiseChannelCloseReceivedThread = null; } - private void CreateMocks() - { - _sessionMock = new Mock(MockBehavior.Strict); - } - - private void SetupMocks() + protected override void SetupMocks() { var sequence = new MockSequence(); - _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.WaitOnHandle(It.IsAny())) - .Callback(w => - { - _raiseChannelCloseReceivedThread = new Thread(() => - { - Thread.Sleep(100); + SessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsAny(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => + { + _raiseChannelCloseReceivedThread = new Thread(() => + { + Thread.Sleep(100); - // signal that the ChannelCloseMessage was received; we use this to verify whether we've actually - // waited on the EventWaitHandle to be set; this needs to be set before we raise the ChannelCloseReceived - // to make sure the waithandle is signaled when the Dispose method completes (or else the assert that - // checks whether the handle has been signaled, will sometimes fail) - _channelClosedReceived.Set(); + // signal that the ChannelCloseMessage was received; we use this to verify whether we've actually + // waited on the EventWaitHandle to be set; this needs to be set before we raise the ChannelCloseReceived + // to make sure the waithandle is signaled when the Dispose method completes (or else the assert that + // checks whether the handle has been signaled, will sometimes fail) + _channelClosedReceived.Set(); - // raise ChannelCloseReceived event to set waithandle for receiving SSH_MSG_CHANNEL_CLOSE message - // from server which is waited on after sending the SSH_MSG_CHANNEL_CLOSE message to the server - // - // this will cause a new invocation of Close() that will block until the Close() that was invoked - // as part of Dispose() has released the lock; as such, this thread cannot be joined until that - // lock is released - // - // we're mocking the wait on the ChannelCloseMessage, but we still want - // to get the channel in the state that it would have after actually receiving - // the ChannelCloseMessage - _sessionMock.Raise(s => s.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); - }); - _raiseChannelCloseReceivedThread.Start(); - w.WaitOne(); - }); - } - - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); + // raise ChannelCloseReceived event to set waithandle for receiving SSH_MSG_CHANNEL_CLOSE message + // from server which is waited on after sending the SSH_MSG_CHANNEL_CLOSE message to the server + // + // this will cause a new invocation of Close() that will block until the Close() that was invoked + // as part of Dispose() has released the lock; as such, this thread cannot be joined until that + // lock is released + // + // we're mocking the wait on the ChannelCloseMessage, but we still want + // to get the channel in the state that it would have after actually receiving + // the ChannelCloseMessage + SessionMock.Raise(s => s.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); + }); + _raiseChannelCloseReceivedThread.Start(); + waitHandle.WaitOne(); + }) + .Returns(WaitResult.Success); } [TestCleanup] @@ -116,13 +109,11 @@ namespace Renci.SshNet.Tests.Classes.Channels } } - private void Arrange() + protected override void Arrange() { - SetupData(); - CreateMocks(); - SetupMocks(); + base.Arrange(); - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => { _channelClosedRegister.Add(args); @@ -134,12 +125,12 @@ namespace Renci.SshNet.Tests.Classes.Channels _channel.InitializeRemoteChannelInfo(_remoteChannelNumber, _remoteWindowSize, _remotePacketSize); _channel.SetIsOpen(true); - _sessionMock.Raise( + SessionMock.Raise( s => s.ChannelEofReceived += null, new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -153,7 +144,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldBeInvokedOnceForChannelCloseMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } @@ -161,15 +152,15 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldNeverBeInvokedForChannelEofMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Never); } [TestMethod] - public void WaitOnHandleOnSessionShouldBeInvokedOnce() + public void TryWaitOnSessionShouldBeInvokedOnce() { - _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny()), Times.Once); + SessionMock.Verify(p => p.TryWait(It.IsAny(), _channelCloseTimeout), Times.Once); } [TestMethod] diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_ConnectionExceptionWaitingForChannelCloseMessage.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_DisconnectWaitingForChannelCloseMessage.cs similarity index 59% rename from src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_ConnectionExceptionWaitingForChannelCloseMessage.cs rename to src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_DisconnectWaitingForChannelCloseMessage.cs index afe1f75a..7519c5db 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_ConnectionExceptionWaitingForChannelCloseMessage.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_DisconnectWaitingForChannelCloseMessage.cs @@ -9,84 +9,64 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_ConnectionExceptionWaitingForChannelCloseMessage + public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_DisconnectWaitingForChannelCloseMessage : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private ChannelStub _channel; private List _channelClosedRegister; private List _channelEndOfDataRegister; private IList _channelExceptionRegister; - private SshConnectionException _connectionException; - private void SetupData() + protected override 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); + _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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _channelClosedRegister = new List(); _channelEndOfDataRegister = new List(); _channelExceptionRegister = new List(); - _connectionException = new SshConnectionException(); } - private void CreateMocks() - { - _sessionMock = new Mock(MockBehavior.Strict); - } - - private void SetupMocks() + protected override void SetupMocks() { var sequence = new MockSequence(); - _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.WaitOnHandle(It.IsAny())) - .Callback(w => - { - throw _connectionException; - }); + SessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence).Setup(p => p.TryWait(It.IsAny(), _channelCloseTimeout)).Returns(WaitResult.Disconnected); } - [TestInitialize] - public void Initialize() + protected override void Arrange() { - Arrange(); - Act(); - } + base.Arrange(); - private void Arrange() - { - SetupData(); - CreateMocks(); - SetupMocks(); - - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); - _channel.Closed += (sender, args) => - { - _channelClosedRegister.Add(args); - }; + _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( + SessionMock.Raise( s => s.ChannelEofReceived += null, new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -100,7 +80,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldBeInvokedOnceForChannelCloseMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } @@ -108,15 +88,15 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldNeverBeInvokedForChannelEofMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Never); } [TestMethod] - public void WaitOnHandleOnSessionShouldBeInvokedOnce() + public void TryWaitOnSessionShouldBeInvokedOnce() { - _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny()), Times.Once); + SessionMock.Verify(p => p.TryWait(It.IsAny(), _channelCloseTimeout), Times.Once); } [TestMethod] @@ -138,4 +118,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreEqual(0, _channelExceptionRegister.Count); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_OperationTimeoutExceptionWaitingForChannelCloseMessage.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_TimeoutWaitingForChannelCloseMessage.cs similarity index 51% rename from src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_OperationTimeoutExceptionWaitingForChannelCloseMessage.cs rename to src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_TimeoutWaitingForChannelCloseMessage.cs index 116776d5..a5131338 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_OperationTimeoutExceptionWaitingForChannelCloseMessage.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_TimeoutWaitingForChannelCloseMessage.cs @@ -9,107 +9,78 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_OperationTimeoutExceptionWaitingForChannelCloseMessage + public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived_TimeoutWaitingForChannelCloseMessage : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private ChannelStub _channel; private List _channelClosedRegister; private List _channelEndOfDataRegister; private IList _channelExceptionRegister; - private SshOperationTimeoutException _operationTimeoutException; - private SshOperationTimeoutException _actualException; - private void SetupData() + protected override 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); + _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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next()); _channelClosedRegister = new List(); _channelEndOfDataRegister = new List(); _channelExceptionRegister = new List(); - _operationTimeoutException = new SshOperationTimeoutException(); - _actualException = null; } - private void CreateMocks() - { - _sessionMock = new Mock(MockBehavior.Strict); - } - - private void SetupMocks() + protected override void SetupMocks() { var sequence = new MockSequence(); - _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.WaitOnHandle(It.IsAny())) - .Callback(w => - { - throw _operationTimeoutException; - }); + SessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence).Setup(p => p.TryWait(It.IsAny(), _channelCloseTimeout)).Returns(WaitResult.TimedOut); } - [TestInitialize] - public void Initialize() + protected override void Arrange() { - Arrange(); - Act(); - } + base.Arrange(); - private void Arrange() - { - SetupData(); - CreateMocks(); - SetupMocks(); - - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); - _channel.Closed += (sender, args) => - { - _channelClosedRegister.Add(args); - }; + _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( + SessionMock.Raise( s => s.ChannelEofReceived += null, new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { - try - { - _channel.Dispose(); - } - catch (SshOperationTimeoutException ex) - { - _actualException = ex; - } + _channel.Dispose(); } [TestMethod] - public void IsOpenShouldReturnTrue() + public void IsOpenShouldReturnFalse() { - Assert.IsTrue(_channel.IsOpen); + Assert.IsFalse(_channel.IsOpen); } [TestMethod] public void TrySendMessageOnSessionShouldBeInvokedOnceForChannelCloseMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } @@ -117,15 +88,15 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldNeverBeInvokedForChannelEofMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Never); } [TestMethod] - public void WaitOnHandleOnSessionShouldBeInvokedOnce() + public void TryWaitOnSessionShouldBeInvokedOnce() { - _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny()), Times.Once); + SessionMock.Verify(p => p.TryWait(It.IsAny(), _channelCloseTimeout), Times.Once); } [TestMethod] @@ -146,12 +117,5 @@ namespace Renci.SshNet.Tests.Classes.Channels { Assert.AreEqual(0, _channelExceptionRegister.Count); } - - [TestMethod] - public void DisposeShouldHaveThrownOperationTimeoutException() - { - Assert.IsNotNull(_actualException); - Assert.AreSame(_operationTimeoutException, _actualException); - } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsNotOpen.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsNotOpen.cs index 3ef388d9..d7709464 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsNotOpen.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsNotOpen.cs @@ -9,9 +9,8 @@ using Renci.SshNet.Messages; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsNotOpen + public class ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsNotOpen : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -19,32 +18,32 @@ namespace Renci.SshNet.Tests.Classes.Channels private List _channelClosedRegister; private IList _channelExceptionRegister; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localChannelNumber = (uint)random.Next(0, int.MaxValue); + + _localChannelNumber = (uint) random.Next(0, int.MaxValue); _localWindowSize = (uint) random.Next(0, int.MaxValue); _localPacketSize = (uint) random.Next(0, int.MaxValue); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + SessionMock.Setup(p => p.IsConnected).Returns(false); + } - _sessionMock.Setup(p => p.IsConnected).Returns(false); + protected override void Arrange() + { + base.Arrange(); - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -58,7 +57,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void SendMessageOnSessionShouldNeverBeInvoked() { - _sessionMock.Verify(p => p.SendMessage(It.IsAny()), Times.Never); + SessionMock.Verify(p => p.SendMessage(It.IsAny()), Times.Never); } [TestMethod] @@ -73,4 +72,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreEqual(0, _channelExceptionRegister.Count); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsOpen.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsOpen.cs index 76fbaa65..d837c734 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsOpen.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsOpen.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsOpen + public class ChannelTest_Dispose_SessionIsNotConnectedAndChannelIsOpen : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -18,33 +17,33 @@ namespace Renci.SshNet.Tests.Classes.Channels private List _channelClosedRegister; private IList _channelExceptionRegister; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _localChannelNumber = (uint) random.Next(0, int.MaxValue); + _localWindowSize = (uint) random.Next(0, int.MaxValue); + _localPacketSize = (uint) random.Next(0, int.MaxValue); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + SessionMock.Setup(p => p.IsConnected).Returns(false); + } - _sessionMock.Setup(p => p.IsConnected).Returns(false); + protected override void Arrange() + { + base.Arrange(); - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.SetIsOpen(true); } - private void Act() + protected override void Act() { _channel.Dispose(); } @@ -58,7 +57,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void SendMessageOnSessionShouldNeverBeInvoked() { - _sessionMock.Verify(p => p.SendMessage(It.IsAny()), Times.Never); + SessionMock.Verify(p => p.SendMessage(It.IsAny()), Times.Never); } [TestMethod] @@ -73,4 +72,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreEqual(0, _channelExceptionRegister.Count); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_OnClose_Exception.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_OnClose_Exception.cs index 1933afb7..102a5769 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_OnClose_Exception.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_OnClose_Exception.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelCloseReceived_OnClose_Exception + public class ChannelTest_OnSessionChannelCloseReceived_OnClose_Exception : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -18,32 +17,33 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelExceptionRegister; private Exception _onCloseException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); + _localWindowSize = (uint) random.Next(1000, int.MaxValue); _localPacketSize = _localWindowSize - 1; _localChannelNumber = (uint) random.Next(0, int.MaxValue); _onCloseException = new SystemException(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.OnCloseException = _onCloseException; } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.ChannelCloseReceived += null, + SessionMock.Raise(s => s.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_DisposeChannelInClosedEventHandler.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_DisposeChannelInClosedEventHandler.cs index 44d745d0..e8aa9752 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_DisposeChannelInClosedEventHandler.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_DisposeChannelInClosedEventHandler.cs @@ -9,22 +9,23 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_DisposeChannelInClosedEventHandler + public class ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_DisposeChannelInClosedEventHandler : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private ChannelStub _channel; private List _channelClosedRegister; private List _channelEndOfDataRegister; private IList _channelExceptionRegister; private ManualResetEvent _channelClosedEventHandlerCompleted; + private bool _channelClosedWaitHandleSignaled; - private void SetupData() + protected override void SetupData() { var random = new Random(); @@ -34,44 +35,33 @@ namespace Renci.SshNet.Tests.Classes.Channels _remoteChannelNumber = (uint) random.Next(0, int.MaxValue); _remoteWindowSize = (uint) random.Next(0, int.MaxValue); _remotePacketSize = (uint) random.Next(0, int.MaxValue); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); + _channelClosedWaitHandleSignaled = false; _channelClosedRegister = new List(); _channelEndOfDataRegister = new List(); _channelExceptionRegister = new List(); _channelClosedEventHandlerCompleted = new ManualResetEvent(false); } - private void CreateMocks() - { - _sessionMock = new Mock(MockBehavior.Strict); - } - - private void SetupMocks() + protected override void SetupMocks() { var sequence = new MockSequence(); - _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(sequence) - .Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) - .Returns(true); - _sessionMock.InSequence(sequence) - .Setup(p => p.WaitOnHandle(It.IsAny())) - .Callback(w => w.WaitOne()); + SessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsAny(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => _channelClosedWaitHandleSignaled = waitHandle.WaitOne(0)) + .Returns(WaitResult.Success); } - [TestInitialize] - public void Initialize() + protected override void Arrange() { - Arrange(); - Act(); - } + base.Arrange(); - private void Arrange() - { - SetupData(); - CreateMocks(); - SetupMocks(); - - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => { _channelClosedRegister.Add(args); @@ -84,9 +74,9 @@ namespace Renci.SshNet.Tests.Classes.Channels _channel.SetIsOpen(true); } - private void Act() + protected override void Act() { - _sessionMock.Raise( + SessionMock.Raise( s => s.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } @@ -100,7 +90,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldBeInvokedOnceForChannelCloseMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } @@ -108,15 +98,21 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldNeverBeInvokedForChannelEofMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Never); } [TestMethod] - public void WaitOnHandleOnSessionShouldBeInvokedOnce() + public void TryWaitOnSessionShouldBeInvokedOnce() { - _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny()), Times.Once); + SessionMock.Verify(p => p.TryWait(It.IsAny(), _channelCloseTimeout), Times.Once); + } + + [TestMethod] + public void ChannelCloseWaitHandleShouldHaveBeenSignaledImmediately() + { + Assert.IsTrue(_channelClosedWaitHandleSignaled); } [TestMethod] diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs index 9a2a6078..b1d633b5 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs @@ -10,51 +10,55 @@ using Renci.SshNet.Tests.Common; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofNotReceived + public class ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofNotReceived : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private IList _channelClosedRegister; private IList _channelExceptionRegister; private ManualResetEvent _channelClosedEventHandlerCompleted; private ChannelStub _channel; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _channelClosedEventHandlerCompleted = new ManualResetEvent(false); + } - _sessionMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { var sequence = new MockSequence(); - _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); - _sessionMock.InSequence(sequence) - .Setup(s => s.WaitOnHandle(It.IsNotNull())) - .Callback(w => w.WaitOne()); + SessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsAny(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => waitHandle.WaitOne()) + .Returns(WaitResult.Success); + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => { _channelClosedRegister.Add(args); @@ -66,9 +70,9 @@ namespace Renci.SshNet.Tests.Classes.Channels _channel.SetIsOpen(true); } - private void Act() + protected override void Act() { - _sessionMock.Raise(p => p.ChannelCloseReceived += null, + SessionMock.Raise(p => p.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } @@ -81,7 +85,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldBeInvokedOnceForChannelCloseMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } @@ -89,15 +93,15 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldNeverBeInvokedForChannelEofMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Never); } [TestMethod] - public void WaitOnHandleOnSessionShouldBeInvokedOnce() + public void TryWaitOnSessionShouldBeInvokedOnce() { - _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny()), Times.Once); + SessionMock.Verify(p => p.TryWait(It.IsAny(), _channelCloseTimeout), Times.Once); } [TestMethod] diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofReceived.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofReceived.cs index 97be46bd..9f37a40a 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofReceived.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofReceived.cs @@ -10,71 +10,73 @@ using Renci.SshNet.Tests.Common; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofReceived + public class ChannelTest_OnSessionChannelCloseReceived_SessionIsConnectedAndChannelIsOpen_EofReceived : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; private uint _remoteChannelNumber; private uint _remoteWindowSize; private uint _remotePacketSize; + private TimeSpan _channelCloseTimeout; private IList _channelClosedRegister; private IList _channelExceptionRegister; private ManualResetEvent _channelClosedEventHandlerCompleted; private ChannelStub _channel; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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); + _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _channelClosedEventHandlerCompleted = new ManualResetEvent(false); + } - _sessionMock = new Mock(MockBehavior.Strict); - + protected override void SetupMocks() + { var sequence = new MockSequence(); - _sessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); - _sessionMock.InSequence(sequence).Setup( - p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))) - .Returns(true); - _sessionMock.InSequence(sequence) - .Setup(s => s.WaitOnHandle(It.IsNotNull())) - .Callback(w => w.WaitOne()); + SessionMock.InSequence(sequence).Setup(p => p.IsConnected).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber))).Returns(true); + SessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(ConnectionInfoMock.Object); + ConnectionInfoMock.InSequence(sequence).Setup(p => p.ChannelCloseTimeout).Returns(_channelCloseTimeout); + SessionMock.InSequence(sequence) + .Setup(p => p.TryWait(It.IsAny(), _channelCloseTimeout)) + .Callback((waitHandle, channelCloseTimeout) => waitHandle.WaitOne()) + .Returns(WaitResult.Success); + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => - { - _channelClosedRegister.Add(args); - Thread.Sleep(100); - _channelClosedEventHandlerCompleted.Set(); - }; + { + _channelClosedRegister.Add(args); + Thread.Sleep(100); + _channelClosedEventHandlerCompleted.Set(); + }; _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.InitializeRemoteChannelInfo(_remoteChannelNumber, _remoteWindowSize, _remotePacketSize); _channel.SetIsOpen(true); - _sessionMock.Raise(p => p.ChannelEofReceived += null, - new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); + SessionMock.Raise(p => p.ChannelEofReceived += null, + new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); } - private void Act() + protected override void Act() { - _sessionMock.Raise(p => p.ChannelCloseReceived += null, - new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); + SessionMock.Raise(p => p.ChannelCloseReceived += null, + new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); } [TestMethod] @@ -86,7 +88,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void TrySendMessageOnSessionShouldBeInvokedOnceForChannelCloseMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } @@ -94,15 +96,15 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void SendMessageOnSessionShouldNeverBeInvokedForChannelEofMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.TrySendMessage(It.Is(c => c.LocalChannelNumber == _remoteChannelNumber)), Times.Never); } [TestMethod] - public void WaitOnHandleOnSessionShouldBeInvokedOnce() + public void TryWaitOnSessionShouldBeInvokedOnce() { - _sessionMock.Verify(p => p.WaitOnHandle(It.IsAny()), Times.Once); + SessionMock.Verify(p => p.TryWait(It.IsAny(), _channelCloseTimeout), Times.Once); } [TestMethod] @@ -124,4 +126,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.IsTrue(_channelClosedEventHandlerCompleted.WaitOne(0)); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelDataReceived_OnData_Exception.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelDataReceived_OnData_Exception.cs index 6e1b4479..3c2884f2 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelDataReceived_OnData_Exception.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelDataReceived_OnData_Exception.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelDataReceived_OnData_Exception + public class ChannelTest_OnSessionChannelDataReceived_OnData_Exception : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -18,33 +17,34 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelExceptionRegister; private Exception _onDataException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localWindowSize = (uint)random.Next(1000, int.MaxValue); + + _localWindowSize = (uint) random.Next(1000, int.MaxValue); _localPacketSize = _localWindowSize - 1; - _localChannelNumber = (uint)random.Next(0, int.MaxValue); + _localChannelNumber = (uint) random.Next(0, int.MaxValue); _onDataException = new SystemException(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.OnDataException = _onDataException; } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.ChannelDataReceived += null, - new MessageEventArgs(new ChannelDataMessage(_localChannelNumber, new byte[0]))); + SessionMock.Raise(s => s.ChannelDataReceived += null, + new MessageEventArgs(new ChannelDataMessage(_localChannelNumber, new byte[0]))); } [TestMethod] @@ -61,4 +61,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreSame(_onDataException, _channel.OnErrorOccurredInvocations[0]); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelEofReceived_OnEof_Exception.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelEofReceived_OnEof_Exception.cs index ea2ff46e..ff4a38bb 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelEofReceived_OnEof_Exception.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelEofReceived_OnEof_Exception.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelEofReceived_Exception + public class ChannelTest_OnSessionChannelEofReceived_Exception : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -21,38 +20,39 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelExceptionRegister; private Exception _onEofException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localWindowSize = (uint)random.Next(0, 1000); - _localPacketSize = (uint)random.Next(1001, int.MaxValue); - _localChannelNumber = (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); + + _localWindowSize = (uint) random.Next(0, 1000); + _localPacketSize = (uint) random.Next(1001, int.MaxValue); + _localChannelNumber = (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); _onEofException = new SystemException(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.InitializeRemoteChannelInfo(_remoteChannelNumber, _remoteWindowSize, _remotePacketSize); _channel.SetIsOpen(true); _channel.OnEofException = _onEofException; } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.ChannelEofReceived += null, - new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); + SessionMock.Raise(s => s.ChannelEofReceived += null, + new MessageEventArgs(new ChannelEofMessage(_localChannelNumber))); } [TestMethod] @@ -69,4 +69,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreSame(_onEofException, _channel.OnErrorOccurredInvocations[0]); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelExtendedDataReceived_OnExtendedData_Exception.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelExtendedDataReceived_OnExtendedData_Exception.cs index fccb0081..9f582933 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelExtendedDataReceived_OnExtendedData_Exception.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelExtendedDataReceived_OnExtendedData_Exception.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelExtendedDataReceived_OnExtendedData_Exception + public class ChannelTest_OnSessionChannelExtendedDataReceived_OnExtendedData_Exception : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -18,33 +17,34 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelExceptionRegister; private Exception _onExtendedDataException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localWindowSize = (uint)random.Next(1000, int.MaxValue); + + _localWindowSize = (uint) random.Next(1000, int.MaxValue); _localPacketSize = _localWindowSize - 1; - _localChannelNumber = (uint)random.Next(0, int.MaxValue); + _localChannelNumber = (uint) random.Next(0, int.MaxValue); _onExtendedDataException = new SystemException(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.OnExtendedDataException = _onExtendedDataException; } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.ChannelExtendedDataReceived += null, - new MessageEventArgs(new ChannelExtendedDataMessage(_localChannelNumber, 5, new byte[0]))); + SessionMock.Raise(s => s.ChannelExtendedDataReceived += null, + new MessageEventArgs(new ChannelExtendedDataMessage(_localChannelNumber, 5, new byte[0]))); } [TestMethod] @@ -61,4 +61,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreSame(_onExtendedDataException, _channel.OnErrorOccurredInvocations[0]); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelFailureReceived_OnFailure_Exception.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelFailureReceived_OnFailure_Exception.cs index 76a9c8ad..935048a2 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelFailureReceived_OnFailure_Exception.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelFailureReceived_OnFailure_Exception.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelFailureReceived_OnFailure_Exception + public class ChannelTest_OnSessionChannelFailureReceived_OnFailure_Exception : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -18,33 +17,34 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelExceptionRegister; private Exception _onFailureException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localWindowSize = (uint)random.Next(0, 1000); - _localPacketSize = (uint)random.Next(1001, int.MaxValue); - _localChannelNumber = (uint)random.Next(0, int.MaxValue); + + _localWindowSize = (uint) random.Next(0, 1000); + _localPacketSize = (uint) random.Next(1001, int.MaxValue); + _localChannelNumber = (uint) random.Next(0, int.MaxValue); _onFailureException = new SystemException(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.OnFailureException = _onFailureException; } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.ChannelFailureReceived += null, - new MessageEventArgs(new ChannelFailureMessage(_localChannelNumber))); + SessionMock.Raise(s => s.ChannelFailureReceived += null, + new MessageEventArgs(new ChannelFailureMessage(_localChannelNumber))); } [TestMethod] @@ -61,4 +61,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreSame(_onFailureException, _channel.OnErrorOccurredInvocations[0]); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelRequestReceived_OnRequest_Exception.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelRequestReceived_OnRequest_Exception.cs index bcb59532..d5c82801 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelRequestReceived_OnRequest_Exception.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelRequestReceived_OnRequest_Exception.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelRequestReceived_OnRequest_Exception + public class ChannelTest_OnSessionChannelRequestReceived_OnRequest_Exception : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -19,36 +18,37 @@ namespace Renci.SshNet.Tests.Classes.Channels private Exception _onRequestException; private SignalRequestInfo _requestInfo; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localWindowSize = (uint)random.Next(1000, int.MaxValue); + + _localWindowSize = (uint) random.Next(1000, int.MaxValue); _localPacketSize = _localWindowSize - 1; - _localChannelNumber = (uint)random.Next(0, int.MaxValue); + _localChannelNumber = (uint) random.Next(0, int.MaxValue); _onRequestException = new SystemException(); _channelExceptionRegister = new List(); _requestInfo = new SignalRequestInfo("ABC"); + } - _sessionMock = new Mock(MockBehavior.Strict); - _sessionMock.Setup(p => p.ConnectionInfo) - .Returns(new ConnectionInfo("host", "user", new PasswordAuthenticationMethod("user", "password"))); + protected override void SetupMocks() + { + SessionMock.Setup(p => p.ConnectionInfo) + .Returns(new ConnectionInfo("host", "user", new PasswordAuthenticationMethod("user", "password"))); + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.OnRequestException = _onRequestException; } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.ChannelRequestReceived += null, - new MessageEventArgs(new ChannelRequestMessage(_localChannelNumber, _requestInfo))); + SessionMock.Raise(s => s.ChannelRequestReceived += null, + new MessageEventArgs(new ChannelRequestMessage(_localChannelNumber, _requestInfo))); } [TestMethod] @@ -65,4 +65,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreSame(_onRequestException, _channel.OnErrorOccurredInvocations[0]); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelSuccessReceived_OnSuccess_Exception.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelSuccessReceived_OnSuccess_Exception.cs index 4bc8e849..2caa91f1 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelSuccessReceived_OnSuccess_Exception.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelSuccessReceived_OnSuccess_Exception.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelSuccessReceived_OnSuccess_Exception + public class ChannelTest_OnSessionChannelSuccessReceived_OnSuccess_Exception : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -18,33 +17,34 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelExceptionRegister; private Exception _onSuccessException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localChannelNumber = (uint)random.Next(0, int.MaxValue); - _localWindowSize = (uint)random.Next(0, 1000); - _localPacketSize = (uint)random.Next(1001, int.MaxValue); + + _localChannelNumber = (uint) random.Next(0, int.MaxValue); + _localWindowSize = (uint) random.Next(0, 1000); + _localPacketSize = (uint) random.Next(1001, int.MaxValue); _onSuccessException = new SystemException(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.OnSuccessException = _onSuccessException; } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.ChannelSuccessReceived += null, - new MessageEventArgs(new ChannelSuccessMessage(_localChannelNumber))); + SessionMock.Raise(s => s.ChannelSuccessReceived += null, + new MessageEventArgs(new ChannelSuccessMessage(_localChannelNumber))); } [TestMethod] @@ -61,4 +61,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreSame(_onSuccessException, _channel.OnErrorOccurredInvocations[0]); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelWindowAdjustReceived_OnWindowAdjust_Exception.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelWindowAdjustReceived_OnWindowAdjust_Exception.cs index e4e0b863..ba223ad9 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelWindowAdjustReceived_OnWindowAdjust_Exception.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionChannelWindowAdjustReceived_OnWindowAdjust_Exception.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionChannelWindowAdjustReceived_OnWindowAdjust_Exception + public class ChannelTest_OnSessionChannelWindowAdjustReceived_OnWindowAdjust_Exception : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; @@ -22,38 +21,39 @@ namespace Renci.SshNet.Tests.Classes.Channels private Exception _onWindowAdjustException; private uint _bytesToAdd; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localChannelNumber = (uint)random.Next(0, int.MaxValue); - _localWindowSize = (uint)random.Next(1000, int.MaxValue); + + _localChannelNumber = (uint) random.Next(0, int.MaxValue); + _localWindowSize = (uint) random.Next(1000, int.MaxValue); _localPacketSize = _localWindowSize - 1; - _remoteChannelNumber = (uint)random.Next(0, int.MaxValue); - _remoteWindowSize = (uint)random.Next(1000, int.MaxValue); + _remoteChannelNumber = (uint) random.Next(0, int.MaxValue); + _remoteWindowSize = (uint) random.Next(1000, int.MaxValue); _remotePacketSize = _localWindowSize - 1; - _bytesToAdd = (uint)random.Next(0, int.MaxValue); + _bytesToAdd = (uint) random.Next(0, int.MaxValue); _onWindowAdjustException = new SystemException(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.InitializeRemoteChannelInfo(_remoteChannelNumber, _remoteWindowSize, _remotePacketSize); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.OnWindowAdjustException = _onWindowAdjustException; } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.ChannelWindowAdjustReceived += null, - new MessageEventArgs(new ChannelWindowAdjustMessage(_localChannelNumber, _bytesToAdd))); + SessionMock.Raise(s => s.ChannelWindowAdjustReceived += null, + new MessageEventArgs(new ChannelWindowAdjustMessage(_localChannelNumber, _bytesToAdd))); } [TestMethod] @@ -70,4 +70,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreSame(_onWindowAdjustException, _channel.OnErrorOccurredInvocations[0]); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionDisconnected_OnDisconnected_Exception.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionDisconnected_OnDisconnected_Exception.cs index e570a215..4796c4e6 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionDisconnected_OnDisconnected_Exception.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionDisconnected_OnDisconnected_Exception.cs @@ -7,9 +7,8 @@ using Renci.SshNet.Common; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionDisconnected_OnDisconnected_Exception + public class ChannelTest_OnSessionDisconnected_OnDisconnected_Exception : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -17,32 +16,33 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelExceptionRegister; private Exception _onDisconnectedException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localWindowSize = (uint)random.Next(1000, int.MaxValue); + + _localWindowSize = (uint) random.Next(1000, int.MaxValue); _localPacketSize = _localWindowSize - 1; - _localChannelNumber = (uint)random.Next(0, int.MaxValue); + _localChannelNumber = (uint) random.Next(0, int.MaxValue); _onDisconnectedException = new SystemException(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.OnDisconnectedException = _onDisconnectedException; } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.Disconnected += null, EventArgs.Empty); + SessionMock.Raise(s => s.Disconnected += null, EventArgs.Empty); } [TestMethod] @@ -59,4 +59,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreSame(_onDisconnectedException, _channel.OnErrorOccurredInvocations[0]); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionDisconnected_SessionIsConnectedAndChannelIsOpen.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionDisconnected_SessionIsConnectedAndChannelIsOpen.cs index c5c890b9..e228c36b 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionDisconnected_SessionIsConnectedAndChannelIsOpen.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionDisconnected_SessionIsConnectedAndChannelIsOpen.cs @@ -7,9 +7,8 @@ using Renci.SshNet.Common; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionDisconnected_SessionIsConnectedAndChannelIsOpen + public class ChannelTest_OnSessionDisconnected_SessionIsConnectedAndChannelIsOpen : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; @@ -20,39 +19,39 @@ namespace Renci.SshNet.Tests.Classes.Channels private List _channelClosedRegister; private IList _channelExceptionRegister; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + SessionMock.Setup(p => p.IsConnected).Returns(true); + } - _sessionMock.Setup(p => p.IsConnected).Returns(true); + protected override void Arrange() + { + base.Arrange(); - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.InitializeRemoteChannelInfo(_remoteChannelNumber, _remoteWindowSize, _remotePacketSize); _channel.SetIsOpen(true); } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.Disconnected += null, EventArgs.Empty); + SessionMock.Raise(s => s.Disconnected += null, EventArgs.Empty); } [TestMethod] @@ -73,4 +72,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreEqual(0, _channelExceptionRegister.Count); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionErrorOccurred_OnErrorOccurred_Exception.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionErrorOccurred_OnErrorOccurred_Exception.cs index 21e8d91d..ddbae080 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionErrorOccurred_OnErrorOccurred_Exception.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_OnSessionErrorOccurred_OnErrorOccurred_Exception.cs @@ -1,15 +1,13 @@ using System; using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; using Renci.SshNet.Common; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_OnSessionErrorOccurred_OnErrorOccurred_Exception + public class ChannelTest_OnSessionErrorOccurred_OnErrorOccurred_Exception : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -18,33 +16,34 @@ namespace Renci.SshNet.Tests.Classes.Channels private Exception _onErrorOccurredException; private Exception _errorOccurredException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override void SetupData() { var random = new Random(); - _localWindowSize = (uint)random.Next(1000, int.MaxValue); + + _localWindowSize = (uint) random.Next(1000, int.MaxValue); _localPacketSize = _localWindowSize - 1; - _localChannelNumber = (uint)random.Next(0, int.MaxValue); + _localChannelNumber = (uint) random.Next(0, int.MaxValue); _onErrorOccurredException = new SystemException(); _channelExceptionRegister = new List(); _errorOccurredException = new SystemException(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.OnErrorOccurredException = _onErrorOccurredException; } - private void Act() + protected override void Act() { - _sessionMock.Raise(s => s.ErrorOccured += null, new ExceptionEventArgs(_errorOccurredException)); + SessionMock.Raise(s => s.ErrorOccured += null, new ExceptionEventArgs(_errorOccurredException)); } [TestMethod] @@ -61,4 +60,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreSame(_errorOccurredException, _channel.OnErrorOccurredInvocations[0]); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_SendEof_ChannelIsNotOpen.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_SendEof_ChannelIsNotOpen.cs index da712f4b..83d4ac3f 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_SendEof_ChannelIsNotOpen.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_SendEof_ChannelIsNotOpen.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_SendEof_ChannelIsNotOpen + public class ChannelTest_SendEof_ChannelIsNotOpen : ChannelTestBase { - private Mock _sessionMock; private uint _localWindowSize; private uint _localPacketSize; private uint _localChannelNumber; @@ -19,31 +18,32 @@ namespace Renci.SshNet.Tests.Classes.Channels private IList _channelExceptionRegister; private InvalidOperationException _actualException; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _localChannelNumber = (uint) random.Next(0, int.MaxValue); + _localWindowSize = (uint) random.Next(0, int.MaxValue); + _localPacketSize = (uint) random.Next(0, int.MaxValue); _channelClosedRegister = new List(); _channelExceptionRegister = new List(); _actualException = null; + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + } - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + protected override void Arrange() + { + base.Arrange(); + + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); } - private void Act() + protected override void Act() { try { @@ -73,7 +73,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void SendMessageOnSessionShouldNeverBeInvoked() { - _sessionMock.Verify(p => p.SendMessage(It.IsAny()), Times.Never); + SessionMock.Verify(p => p.SendMessage(It.IsAny()), Times.Never); } [TestMethod] @@ -88,4 +88,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreEqual(0, _channelExceptionRegister.Count); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_SendEof_ChannelIsOpen.cs b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_SendEof_ChannelIsOpen.cs index 9a28db11..ff843491 100644 --- a/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_SendEof_ChannelIsOpen.cs +++ b/src/Renci.SshNet.Tests/Classes/Channels/ChannelTest_SendEof_ChannelIsOpen.cs @@ -8,9 +8,8 @@ using Renci.SshNet.Messages.Connection; namespace Renci.SshNet.Tests.Classes.Channels { [TestClass] - public class ChannelTest_SendEof_ChannelIsOpen + public class ChannelTest_SendEof_ChannelIsOpen : ChannelTestBase { - private Mock _sessionMock; private uint _localChannelNumber; private uint _localWindowSize; private uint _localPacketSize; @@ -21,37 +20,37 @@ namespace Renci.SshNet.Tests.Classes.Channels private List _channelClosedRegister; private IList _channelExceptionRegister; - [TestInitialize] - public void Initialize() - { - Arrange(); - Act(); - } - - private void Arrange() + protected override 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); + + _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(); _channelExceptionRegister = new List(); + } - _sessionMock = new Mock(MockBehavior.Strict); + protected override void SetupMocks() + { + SessionMock.Setup(p => p.SendMessage(It.Is(e => e.LocalChannelNumber == _remoteChannelNumber))); + } - _sessionMock.Setup(p => p.SendMessage(It.Is(e => e.LocalChannelNumber == _remoteChannelNumber))); + protected override void Arrange() + { + base.Arrange(); - _channel = new ChannelStub(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); + _channel = new ChannelStub(SessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize); _channel.Closed += (sender, args) => _channelClosedRegister.Add(args); _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args); _channel.InitializeRemoteChannelInfo(_remoteChannelNumber, _remoteWindowSize, _remotePacketSize); _channel.SetIsOpen(true); } - private void Act() + protected override void Act() { _channel.SendEof(); } @@ -65,7 +64,7 @@ namespace Renci.SshNet.Tests.Classes.Channels [TestMethod] public void SendMessageOnSessionShouldBeInvokedOnceWithChannelEofMessage() { - _sessionMock.Verify( + SessionMock.Verify( p => p.SendMessage(It.Is(e => e.LocalChannelNumber == _remoteChannelNumber)), Times.Once); } @@ -82,4 +81,4 @@ namespace Renci.SshNet.Tests.Classes.Channels Assert.AreEqual(0, _channelExceptionRegister.Count); } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs index d46d3798..0d8f2412 100644 --- a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs +++ b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs @@ -71,7 +71,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void WaitOnHandle_WaitHandle_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() { - WaitHandle waitHandle = null; + const WaitHandle waitHandle = null; try { @@ -88,7 +88,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void WaitOnHandle_WaitHandleAndTimeout_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() { - WaitHandle waitHandle = null; + const WaitHandle waitHandle = null; var timeout = TimeSpan.FromMinutes(5); try @@ -151,7 +151,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void ISession_WaitOnHandleShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() { - WaitHandle waitHandle = null; + const WaitHandle waitHandle = null; var session = (ISession) Session; try @@ -165,5 +165,91 @@ namespace Renci.SshNet.Tests.Classes Assert.AreEqual("waitHandle", ex.ParamName); } } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnSuccessIfWaitHandleIsSignaled() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(true); + + var result = session.TryWait(waitHandle, TimeSpan.FromMilliseconds(0)); + + Assert.AreEqual(WaitResult.Success, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnTimedOutIfWaitHandleIsNotSignaled() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + var result = session.TryWait(waitHandle, TimeSpan.FromMilliseconds(0)); + + Assert.AreEqual(WaitResult.TimedOut, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() + { + var session = (ISession) Session; + const WaitHandle waitHandle = null; + + try + { + session.TryWait(waitHandle, Session.InfiniteTimeSpan); + Assert.Fail(); + } + catch (ArgumentNullException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("waitHandle", ex.ParamName); + } + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnSuccessIfWaitHandleIsSignaled() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(true); + Exception exception; + + var result = session.TryWait(waitHandle, TimeSpan.FromMilliseconds(0), out exception); + + Assert.AreEqual(WaitResult.Success, result); + Assert.IsNull(exception); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnTimedOutIfWaitHandleIsNotSignaled() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + Exception exception; + + var result = session.TryWait(waitHandle, TimeSpan.FromMilliseconds(0), out exception); + + Assert.AreEqual(WaitResult.TimedOut, result); + Assert.IsNull(exception); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() + { + var session = (ISession) Session; + const WaitHandle waitHandle = null; + Exception exception = null; + + try + { + session.TryWait(waitHandle, Session.InfiniteTimeSpan, out exception); + Assert.Fail(); + } + catch (ArgumentNullException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("waitHandle", ex.ParamName); + Assert.IsNull(exception); + } + } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ConnectionReset.cs b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ConnectionReset.cs index 464cf05b..c10e2799 100644 --- a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ConnectionReset.cs +++ b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ConnectionReset.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.Net.Sockets; using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -69,9 +70,8 @@ namespace Renci.SshNet.Tests.Classes Assert.AreEqual(typeof(SocketException), innerException.GetType()); var socketException = (SocketException) innerException; + Assert.AreSame(connectionException.Message, socketException.Message); Assert.AreEqual(SocketError.ConnectionReset, socketException.SocketErrorCode); - - Assert.AreSame(innerException.Message, connectionException.Message); } [TestMethod] @@ -140,7 +140,7 @@ namespace Renci.SshNet.Tests.Classes } [TestMethod] - public void ISession_WaitOnHandleShouldThrowSshConnectionExceptionDetailingConnectionReset() + public void ISession_WaitOnHandle_WaitHandle_ShouldThrowSshConnectionExceptionDetailingConnectionReset() { var session = (ISession) Session; var waitHandle = new ManualResetEvent(false); @@ -158,12 +158,63 @@ namespace Renci.SshNet.Tests.Classes Assert.IsNotNull(innerException); Assert.AreEqual(typeof(SocketException), innerException.GetType()); - var socketException = (SocketException)ex.InnerException; - Assert.AreEqual(SocketError.ConnectionReset, socketException.SocketErrorCode); - + var socketException = (SocketException) ex.InnerException; + Assert.IsNotNull(socketException); + Assert.IsNull(socketException.InnerException); Assert.AreSame(innerException.Message, ex.Message); - + Assert.AreEqual(SocketError.ConnectionReset, socketException.SocketErrorCode); } } + + [TestMethod] + public void ISession_WaitOnHandle_WaitHandleAndTimeout_ShouldThrowSshConnectionExceptionDetailingConnectionReset() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + try + { + session.WaitOnHandle(waitHandle, Session.InfiniteTimeSpan); + Assert.Fail(); + } + catch (SshConnectionException ex) + { + Assert.AreEqual(DisconnectReason.ConnectionLost, ex.DisconnectReason); + + var innerException = ex.InnerException; + Assert.IsNotNull(innerException); + Assert.AreEqual(typeof(SocketException), innerException.GetType()); + + var socketException = (SocketException) ex.InnerException; + Assert.IsNotNull(socketException); + Assert.IsNull(socketException.InnerException); + Assert.AreSame(innerException.Message, socketException.Message); + Assert.AreEqual(SocketError.ConnectionReset, socketException.SocketErrorCode); + } + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan); + + Assert.AreEqual(WaitResult.Disconnected, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + Exception exception; + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan, out exception); + + Assert.AreEqual(WaitResult.Disconnected, result); + Assert.IsNull(exception); + } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_Disconnect.cs b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_Disconnect.cs index cf2827cc..3aed3027 100644 --- a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_Disconnect.cs +++ b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_Disconnect.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.Net.Sockets; using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -92,7 +93,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void ISession_MessageListenerCompletedShouldBeSignaled() { - var session = (ISession)Session; + var session = (ISession) Session; Assert.IsNotNull(session.MessageListenerCompleted); Assert.IsTrue(session.MessageListenerCompleted.WaitOne()); @@ -127,7 +128,7 @@ namespace Renci.SshNet.Tests.Classes } [TestMethod] - public void ISession_WaitOnHandleShouldThrowSshConnectionExceptionDetailingBadPacket() + public void ISession_WaitOnHandle_WaitHandle_ShouldThrowSshConnectionExceptionDetailingBadPacket() { var session = (ISession) Session; var waitHandle = new ManualResetEvent(false); @@ -144,5 +145,48 @@ namespace Renci.SshNet.Tests.Classes Assert.AreEqual("Client not connected.", ex.Message); } } + + [TestMethod] + public void ISession_WaitOnHandle_WaitHandleAndTimeout_ShouldThrowSshConnectionExceptionDetailingBadPacket() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + try + { + session.WaitOnHandle(waitHandle, Session.InfiniteTimeSpan); + Assert.Fail(); + } + catch (SshConnectionException ex) + { + Assert.AreEqual(DisconnectReason.None, ex.DisconnectReason); + Assert.IsNull(ex.InnerException); + Assert.AreEqual("Client not connected.", ex.Message); + } + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan); + + Assert.AreEqual(WaitResult.Disconnected, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + Exception exception; + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan, out exception); + + Assert.AreEqual(WaitResult.Disconnected, result); + Assert.IsNull(exception); + } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsBadPacket.cs b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsBadPacket.cs index 4eaed4a3..df9790f9 100644 --- a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsBadPacket.cs +++ b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsBadPacket.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.Net.Sockets; using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -11,12 +12,20 @@ namespace Renci.SshNet.Tests.Classes [TestClass] public class SessionTest_Connected_ServerSendsBadPacket : SessionTest_ConnectedBase { + private byte[] _packet; + + protected override void SetupData() + { + base.SetupData(); + + _packet = new byte[] {0x0a, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05}; + } + protected override void Act() { - var badPacket = new byte[] { 0x0a, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05 }; - ServerSocket.Send(badPacket, 0, badPacket.Length, SocketFlags.None); + ServerSocket.Send(_packet, 0, _packet.Length, SocketFlags.None); - // give session some time to react to bad packet + // give session some time to process packet Thread.Sleep(200); } @@ -60,7 +69,7 @@ namespace Renci.SshNet.Tests.Classes var exception = errorOccurred.Exception; Assert.IsNotNull(exception); - Assert.AreEqual(typeof (SshConnectionException), exception.GetType()); + Assert.AreEqual(typeof(SshConnectionException), exception.GetType()); var connectionException = (SshConnectionException) exception; Assert.AreEqual(DisconnectReason.ProtocolError, connectionException.DisconnectReason); @@ -109,7 +118,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void ISession_MessageListenerCompletedShouldBeSignaled() { - var session = (ISession)Session; + var session = (ISession) Session; Assert.IsNotNull(session.MessageListenerCompleted); Assert.IsTrue(session.MessageListenerCompleted.WaitOne()); @@ -144,7 +153,7 @@ namespace Renci.SshNet.Tests.Classes } [TestMethod] - public void ISession_WaitOnHandleShouldThrowSshConnectionExceptionDetailingBadPacket() + public void ISession_WaitOnHandle_WaitHandle_ShouldThrowSshConnectionExceptionDetailingBadPacket() { var session = (ISession) Session; var waitHandle = new ManualResetEvent(false); @@ -161,5 +170,48 @@ namespace Renci.SshNet.Tests.Classes Assert.AreEqual("Bad packet length: 168101125.", ex.Message); } } + + [TestMethod] + public void ISession_WaitOnHandleAndTimeout_WaitHandle_ShouldThrowSshConnectionExceptionDetailingBadPacket() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + try + { + session.WaitOnHandle(waitHandle, Session.InfiniteTimeSpan); + Assert.Fail(); + } + catch (SshConnectionException ex) + { + Assert.AreEqual(DisconnectReason.ProtocolError, ex.DisconnectReason); + Assert.IsNull(ex.InnerException); + Assert.AreEqual("Bad packet length: 168101125.", ex.Message); + } + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan); + + Assert.AreEqual(WaitResult.Disconnected, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + Exception exception; + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan, out exception); + + Assert.AreEqual(WaitResult.Disconnected, result); + Assert.IsNull(exception); + } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsDisconnectMessage.cs b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsDisconnectMessage.cs index 65a64878..1b887dc6 100644 --- a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsDisconnectMessage.cs +++ b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsDisconnectMessage.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.Globalization; using System.Net.Sockets; using System.Threading; @@ -8,8 +9,10 @@ using Renci.SshNet.Messages.Transport; namespace Renci.SshNet.Tests.Classes { + [TestClass] public class SessionTest_Connected_ServerSendsDisconnectMessage : SessionTest_ConnectedBase { + private byte[] _packet; private DisconnectMessage _disconnectMessage; protected override void SetupData() @@ -17,14 +20,15 @@ namespace Renci.SshNet.Tests.Classes base.SetupData(); _disconnectMessage = new DisconnectMessage(DisconnectReason.ServiceNotAvailable, "Not today!"); + _packet = _disconnectMessage.GetPacket(8, null); } protected override void Act() { - var disconnect = _disconnectMessage.GetPacket(8, null); - ServerSocket.Send(disconnect, 4, disconnect.Length - 4, SocketFlags.None); + ServerSocket.Send(_packet, 4, _packet.Length - 4, SocketFlags.None); - Session.Disconnect(); + // give session some time to process packet + Thread.Sleep(200); } [TestMethod] @@ -110,7 +114,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void ISession_MessageListenerCompletedShouldBeSignaled() { - var session = (ISession)Session; + var session = (ISession) Session; Assert.IsNotNull(session.MessageListenerCompleted); Assert.IsTrue(session.MessageListenerCompleted.WaitOne()); @@ -145,9 +149,9 @@ namespace Renci.SshNet.Tests.Classes } [TestMethod] - public void ISession_WaitOnHandleShouldThrowSshConnectionExceptionDetailingDisconnectReason() + public void ISession_WaitOnHandle_WaitHandle_ShouldThrowSshConnectionExceptionDetailingDisconnectReason() { - var session = (ISession)Session; + var session = (ISession) Session; var waitHandle = new ManualResetEvent(false); try @@ -159,8 +163,59 @@ namespace Renci.SshNet.Tests.Classes { Assert.AreEqual(DisconnectReason.ServiceNotAvailable, ex.DisconnectReason); Assert.IsNull(ex.InnerException); - Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, "The connection was closed by the server: {0} ({1}).", _disconnectMessage.Description, _disconnectMessage.ReasonCode), ex.Message); + Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, + "The connection was closed by the server: {0} ({1}).", + _disconnectMessage.Description, + _disconnectMessage.ReasonCode), + ex.Message); } } + + [TestMethod] + public void ISession_WaitOnHandle_WaitHandleAndTimeout_ShouldThrowSshConnectionExceptionDetailingDisconnectReason() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + try + { + session.WaitOnHandle(waitHandle, Session.InfiniteTimeSpan); + Assert.Fail(); + } + catch (SshConnectionException ex) + { + Assert.AreEqual(DisconnectReason.ServiceNotAvailable, ex.DisconnectReason); + Assert.IsNull(ex.InnerException); + Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, + "The connection was closed by the server: {0} ({1}).", + _disconnectMessage.Description, + _disconnectMessage.ReasonCode), + ex.Message); + } + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan); + + Assert.AreEqual(WaitResult.Disconnected, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + Exception exception; + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan, out exception); + + Assert.AreEqual(WaitResult.Disconnected, result); + Assert.IsNull(exception); + } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsDisconnectMessageAndShutsDownSocket.cs b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsDisconnectMessageAndShutsDownSocket.cs index 0985794a..d8a50a3d 100644 --- a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsDisconnectMessageAndShutsDownSocket.cs +++ b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsDisconnectMessageAndShutsDownSocket.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.Globalization; using System.Net.Sockets; using System.Threading; @@ -143,7 +144,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void ISession_TrySendMessageShouldReturnFalse() { - var session = (ISession)Session; + var session = (ISession) Session; var actual = session.TrySendMessage(new IgnoreMessage()); @@ -151,9 +152,9 @@ namespace Renci.SshNet.Tests.Classes } [TestMethod] - public void ISession_WaitOnHandleShouldThrowSshConnectionExceptionDetailingDisconnectReason() + public void ISession_WaitOnHandle_WaitHandle_ShouldThrowSshConnectionExceptionDetailingDisconnectReason() { - var session = (ISession)Session; + var session = (ISession) Session; var waitHandle = new ManualResetEvent(false); try @@ -165,8 +166,36 @@ namespace Renci.SshNet.Tests.Classes { Assert.AreEqual(DisconnectReason.ServiceNotAvailable, ex.DisconnectReason); Assert.IsNull(ex.InnerException); - Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, "The connection was closed by the server: {0} ({1}).", _disconnectMessage.Description, _disconnectMessage.ReasonCode), ex.Message); + Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, + "The connection was closed by the server: {0} ({1}).", + _disconnectMessage.Description, + _disconnectMessage.ReasonCode), + ex.Message); } } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan); + + Assert.AreEqual(WaitResult.Disconnected, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + Exception exception; + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan, out exception); + + Assert.AreEqual(WaitResult.Disconnected, result); + Assert.IsNull(exception); + } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsUnsupportedMessageType.cs b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsUnsupportedMessageType.cs new file mode 100644 index 00000000..02e998a4 --- /dev/null +++ b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerSendsUnsupportedMessageType.cs @@ -0,0 +1,236 @@ +using System; +using System.Diagnostics; +using System.Net.Sockets; +using System.Threading; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Renci.SshNet.Common; +using Renci.SshNet.Messages.Transport; + +namespace Renci.SshNet.Tests.Classes +{ + /// + /// This test verifies the current behavior, but this is not necessarily the behavior we want. + /// We should consider treating any exception as a "disconnect" since we're effectively interrupting + /// the message loop. + /// + [TestClass] + public class SessionTest_Connected_ServerSendsUnsupportedMessageType : SessionTest_ConnectedBase + { + private byte[] _packet; + + protected override void SetupData() + { + base.SetupData(); + + _packet = CreatePacketForUnsupportedMessageType(); + } + + protected override void Act() + { + ServerSocket.Send(_packet, 0, _packet.Length, SocketFlags.None); + + // give session some time to process packet + Thread.Sleep(200); + } + + [TestMethod] + public void IsConnectedShouldReturnFalse() + { + Assert.IsFalse(Session.IsConnected); + } + + [TestMethod] + public void DisconnectShouldFinishImmediately() + { + var stopwatch = new Stopwatch(); + stopwatch.Start(); + + Session.Disconnect(); + + stopwatch.Stop(); + Assert.IsTrue(stopwatch.ElapsedMilliseconds < 500); + } + + [TestMethod] + public void DisconnectedIsNeverRaised() + { + Assert.AreEqual(0, DisconnectedRegister.Count); + } + + [TestMethod] + public void DisconnectReceivedIsNeverRaised() + { + Assert.AreEqual(0, DisconnectReceivedRegister.Count); + } + + [TestMethod] + public void ErrorOccurredIsRaisedOnce() + { + Assert.AreEqual(1, ErrorOccurredRegister.Count); + + var errorOccurred = ErrorOccurredRegister[0]; + Assert.IsNotNull(errorOccurred); + + var exception = errorOccurred.Exception; + Assert.IsNotNull(exception); + Assert.AreEqual(typeof(SshException), exception.GetType()); + + var sshException = (SshException) exception; + Assert.IsNull(sshException.InnerException); + Assert.AreEqual("Message type 255 is not supported.", sshException.Message); + } + + [TestMethod] + public void DisposeShouldFinishImmediately() + { + var stopwatch = new Stopwatch(); + stopwatch.Start(); + + Session.Dispose(); + + stopwatch.Stop(); + Assert.IsTrue(stopwatch.ElapsedMilliseconds < 500); + } + + [TestMethod] + public void ReceiveOnServerSocketShouldTimeout() + { + var buffer = new byte[1]; + + ServerSocket.ReceiveTimeout = 500; + try + { + ServerSocket.Receive(buffer, 0, buffer.Length, SocketFlags.None); + Assert.Fail(); + } + catch (SocketException ex) + { + Assert.AreEqual(SocketError.TimedOut, ex.SocketErrorCode); + } + } + + [TestMethod] + public void SendMessageShouldSendMessageToServer() + { + byte[] bytesReceivedByServer = null; + ServerListener.BytesReceived += (received, socket) => bytesReceivedByServer = received; + + Session.SendMessage(new IgnoreMessage()); + + // allow "server" some time to receive message + Thread.Sleep(100); + + Assert.IsNotNull(bytesReceivedByServer); + Assert.AreEqual(24, bytesReceivedByServer.Length); + } + + [TestMethod] + public void ISession_MessageListenerCompletedShouldBeSignaled() + { + var session = (ISession) Session; + + Assert.IsNotNull(session.MessageListenerCompleted); + Assert.IsTrue(session.MessageListenerCompleted.WaitOne()); + } + + [TestMethodAttribute] + public void ISession_SendMessageShouldSendMessageToServer() + { + var session = (ISession) Session; + + byte[] bytesReceivedByServer = null; + ServerListener.BytesReceived += (received, socket) => bytesReceivedByServer = received; + + session.SendMessage(new IgnoreMessage()); + + // allow "server" some time to receive message + Thread.Sleep(100); + + Assert.IsNotNull(bytesReceivedByServer); + Assert.AreEqual(24, bytesReceivedByServer.Length); + } + + [TestMethod] + public void ISession_TrySendMessageShouldReturnTrueAndSendMessageToServer() + { + var session = (ISession) Session; + + byte[] bytesReceivedByServer = null; + ServerListener.BytesReceived += (received, socket) => bytesReceivedByServer = received; + + var actual = session.TrySendMessage(new IgnoreMessage()); + + Assert.IsTrue(actual); + + // allow "server" some time to receive message + Thread.Sleep(100); + + Assert.IsNotNull(bytesReceivedByServer); + Assert.AreEqual(24, bytesReceivedByServer.Length); + } + + [TestMethod] + public void ISession_WaitOnHandleShouldThrowSshExceptionDetailingError() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + try + { + session.WaitOnHandle(waitHandle); + Assert.Fail(); + } + catch (SshException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("Message type 255 is not supported.", ex.Message); + } + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnFailed() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan); + + Assert.AreEqual(WaitResult.Failed, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnFailed() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + Exception exception; + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan, out exception); + + Assert.AreEqual(WaitResult.Failed, result); + Assert.IsNotNull(exception); + Assert.AreEqual(typeof(SshException), exception.GetType()); + + var sshException = exception as SshException; + Assert.IsNotNull(sshException); + Assert.IsNull(sshException.InnerException); + Assert.AreEqual("Message type 255 is not supported.", sshException.Message); + } + + private static byte[] CreatePacketForUnsupportedMessageType() + { + byte messageType = 255; + byte messageLength = 1; + byte paddingLength = 10; + var packetDataLength = (uint) messageLength + paddingLength + 1; + + var sshDataStream = new SshDataStream(4 + 1 + messageLength + paddingLength); + sshDataStream.Write(packetDataLength); + sshDataStream.WriteByte(paddingLength); + sshDataStream.WriteByte(messageType); + sshDataStream.Write(new byte[paddingLength]); + + return sshDataStream.ToArray(); + } + } +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSendAfterSendingIncompletePacket.cs b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSendAfterSendingIncompletePacket.cs index 5aa48762..5fbfb8a2 100644 --- a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSendAfterSendingIncompletePacket.cs +++ b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSendAfterSendingIncompletePacket.cs @@ -146,7 +146,7 @@ namespace Renci.SshNet.Tests.Classes } [TestMethod] - public void ISession_WaitOnHandleShouldThrowSshConnectionExceptionDetailingBadPacket() + public void ISession_WaitOnHandle_WaitHandle_ShouldThrowSshConnectionExceptionDetailingBadPacket() { var session = (ISession) Session; var waitHandle = new ManualResetEvent(false); @@ -163,5 +163,48 @@ namespace Renci.SshNet.Tests.Classes Assert.AreEqual("An established connection was aborted by the server.", ex.Message); } } + + [TestMethod] + public void ISession_WaitOnHandle_WaitHandleAndTimeout_ShouldThrowSshConnectionExceptionDetailingBadPacket() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + try + { + session.WaitOnHandle(waitHandle, Session.InfiniteTimeSpan); + Assert.Fail(); + } + catch (SshConnectionException ex) + { + Assert.AreEqual(DisconnectReason.ConnectionLost, ex.DisconnectReason); + Assert.IsNull(ex.InnerException); + Assert.AreEqual("An established connection was aborted by the server.", ex.Message); + } + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan); + + Assert.AreEqual(WaitResult.Disconnected, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + Exception exception; + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan, out exception); + + Assert.AreEqual(WaitResult.Disconnected, result); + Assert.IsNull(exception); + } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSocket.cs b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSocket.cs index 72e27cd1..02d1f4c7 100644 --- a/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSocket.cs +++ b/src/Renci.SshNet.Tests/Classes/SessionTest_Connected_ServerShutsDownSocket.cs @@ -1,4 +1,5 @@ -using System.Diagnostics; +using System; +using System.Diagnostics; using System.Net.Sockets; using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -107,7 +108,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void ISession_MessageListenerCompletedShouldBeSignaled() { - var session = (ISession)Session; + var session = (ISession) Session; Assert.IsNotNull(session.MessageListenerCompleted); Assert.IsTrue(session.MessageListenerCompleted.WaitOne()); @@ -133,7 +134,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void ISession_TrySendMessageShouldReturnFalse() { - var session = (ISession)Session; + var session = (ISession) Session; var actual = session.TrySendMessage(new IgnoreMessage()); @@ -141,9 +142,9 @@ namespace Renci.SshNet.Tests.Classes } [TestMethod] - public void ISession_WaitOnHandleShouldThrowSshConnectionExceptionDetailingAbortedConnection() + public void ISession_WaitOnHandle_WaitHandle_ShouldThrowSshConnectionExceptionDetailingAbortedConnection() { - var session = (ISession)Session; + var session = (ISession) Session; var waitHandle = new ManualResetEvent(false); try @@ -157,5 +158,88 @@ namespace Renci.SshNet.Tests.Classes Assert.AreEqual("An established connection was aborted by the server.", ex.Message); } } + + [TestMethod] + public void ISession_WaitOnHandle_WaitHandleAndTimeout_ShouldThrowSshConnectionExceptionDetailingAbortedConnection() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + try + { + session.WaitOnHandle(waitHandle, Session.InfiniteTimeSpan); + Assert.Fail(); + } + catch (SshConnectionException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("An established connection was aborted by the server.", ex.Message); + } + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan); + + Assert.AreEqual(WaitResult.Disconnected, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() + { + var session = (ISession) Session; + const WaitHandle waitHandle = null; + var timeout = TimeSpan.FromMinutes(5); + + try + { + session.TryWait(waitHandle, timeout); + Assert.Fail(); + } + catch (ArgumentNullException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("waitHandle", ex.ParamName); + } + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnDisconnected() + { + var session = (ISession) Session; + var waitHandle = new ManualResetEvent(false); + Exception exception; + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan, out exception); + + Assert.AreEqual(WaitResult.Disconnected, result); + Assert.IsNull(exception); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() + { + var session = (ISession) Session; + const WaitHandle waitHandle = null; + var timeout = TimeSpan.FromMinutes(5); + Exception exception = null; + + try + { + session.TryWait(waitHandle, timeout, out exception); + Assert.Fail(); + } + catch (ArgumentNullException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("waitHandle", ex.ParamName); + } + + Assert.IsNull(exception); + } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet.Tests/Classes/SessionTest_NotConnected.cs b/src/Renci.SshNet.Tests/Classes/SessionTest_NotConnected.cs index 4638b698..4a8b3ded 100644 --- a/src/Renci.SshNet.Tests/Classes/SessionTest_NotConnected.cs +++ b/src/Renci.SshNet.Tests/Classes/SessionTest_NotConnected.cs @@ -81,9 +81,9 @@ namespace Renci.SshNet.Tests.Classes } [TestMethod] - public void WaitOnHandle_WaitHandle_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() + public void WaitOnHandle_WaitOnHandle_WaitHandle_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() { - WaitHandle waitHandle = null; + const WaitHandle waitHandle = null; try { @@ -98,9 +98,9 @@ namespace Renci.SshNet.Tests.Classes } [TestMethod] - public void WaitOnHandle_WaitHandleAndTimeout_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() + public void WaitOnHandle_WaitOnHandle_WaitHandleAndTimeout_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() { - WaitHandle waitHandle = null; + const WaitHandle waitHandle = null; var timeout = TimeSpan.FromMinutes(5); try @@ -115,10 +115,34 @@ namespace Renci.SshNet.Tests.Classes } } + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeout_ShouldReturnDisconnected() + { + var session = (ISession) _session; + var waitHandle = new ManualResetEvent(false); + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan); + + Assert.AreEqual(WaitResult.Disconnected, result); + } + + [TestMethod] + public void ISession_TryWait_WaitHandleAndTimeoutAndException_ShouldReturnDisconnected() + { + var session = (ISession) _session; + var waitHandle = new ManualResetEvent(false); + Exception exception; + + var result = session.TryWait(waitHandle, Session.InfiniteTimeSpan, out exception); + + Assert.AreEqual(WaitResult.Disconnected, result); + Assert.IsNull(exception); + } + [TestMethod] public void ISession_ConnectionInfoShouldReturnConnectionInfoPassedThroughConstructor() { - var session = (ISession)_session; + var session = (ISession) _session; Assert.AreSame(_connectionInfo, session.ConnectionInfo); } @@ -134,7 +158,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void ISession_SendMessageShouldThrowShhConnectionException() { - var session = (ISession)_session; + var session = (ISession) _session; try { @@ -152,7 +176,7 @@ namespace Renci.SshNet.Tests.Classes [TestMethod] public void ISession_TrySendMessageShouldReturnFalse() { - var session = (ISession)_session; + var session = (ISession) _session; var actual = session.TrySendMessage(new IgnoreMessage()); @@ -160,10 +184,10 @@ namespace Renci.SshNet.Tests.Classes } [TestMethod] - public void ISession_WaitOnHandleShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() + public void ISession_WaitOnHandle_WaitHandle_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() { - WaitHandle waitHandle = null; - var session = (ISession)_session; + const WaitHandle waitHandle = null; + var session = (ISession) _session; try { @@ -177,6 +201,24 @@ namespace Renci.SshNet.Tests.Classes } } + [TestMethod] + public void ISession_WaitOnHandle_WaitHandleAndTimeout_ShouldThrowArgumentNullExceptionWhenWaitHandleIsNull() + { + const WaitHandle waitHandle = null; + var session = (ISession) _session; + + try + { + session.WaitOnHandle(waitHandle, Session.InfiniteTimeSpan); + Assert.Fail(); + } + catch (ArgumentNullException ex) + { + Assert.IsNull(ex.InnerException); + Assert.AreEqual("waitHandle", ex.ParamName); + } + } + private static ConnectionInfo CreateConnectionInfo(IPEndPoint serverEndPoint, TimeSpan timeout) { var connectionInfo = new ConnectionInfo( @@ -188,4 +230,4 @@ namespace Renci.SshNet.Tests.Classes return connectionInfo; } } -} +} \ No newline at end of file diff --git a/src/Renci.SshNet/Channels/Channel.cs b/src/Renci.SshNet/Channels/Channel.cs index 716d87db..a6311a98 100644 --- a/src/Renci.SshNet/Channels/Channel.cs +++ b/src/Renci.SshNet/Channels/Channel.cs @@ -5,6 +5,7 @@ using Renci.SshNet.Common; using Renci.SshNet.Messages; using Renci.SshNet.Messages.Connection; using System.Globalization; +using Renci.SshNet.Abstractions; namespace Renci.SshNet.Channels { @@ -15,7 +16,6 @@ namespace Renci.SshNet.Channels { private EventWaitHandle _channelClosedWaitHandle = new ManualResetEvent(false); private EventWaitHandle _channelServerWindowAdjustWaitHandle = new ManualResetEvent(false); - private EventWaitHandle _errorOccuredWaitHandle = new ManualResetEvent(false); private readonly object _serverWindowSizeLock = new object(); private readonly uint _initialWindowSize; private uint? _remoteWindowSize; @@ -327,11 +327,10 @@ namespace Renci.SshNet.Channels { var sizeOfCurrentMessage = GetDataLengthThatCanBeSentInMessage(totalBytesToSend); - var channelDataMessage = new ChannelDataMessage( - RemoteChannelNumber, - data, - offset, - sizeOfCurrentMessage); + var channelDataMessage = new ChannelDataMessage(RemoteChannelNumber, + data, + offset, + sizeOfCurrentMessage); _session.SendMessage(channelDataMessage); totalBytesToSend -= sizeOfCurrentMessage; @@ -549,13 +548,10 @@ namespace Renci.SshNet.Channels // only wait for the channel to be closed by the server if we didn't send a // SSH_MSG_CHANNEL_CLOSE as response to a SSH_MSG_CHANNEL_CLOSE sent by the // server - try + var closeWaitResult = _session.TryWait(_channelClosedWaitHandle, ConnectionInfo.ChannelCloseTimeout); + if (closeWaitResult != WaitResult.Success) { - WaitOnHandle(_channelClosedWaitHandle); - } - catch (SshConnectionException) - { - // ignore connection failures as we're closing the channel anyway + DiagnosticAbstraction.Log(string.Format("Wait for channel close not successful: {0:G}.", closeWaitResult)); } } } @@ -620,10 +616,6 @@ namespace Renci.SshNet.Channels try { OnErrorOccured(e.Exception); - - var errorOccuredWaitHandle = _errorOccuredWaitHandle; - if (errorOccuredWaitHandle != null) - errorOccuredWaitHandle.Set(); } catch (Exception ex) { @@ -879,13 +871,6 @@ namespace Renci.SshNet.Channels channelServerWindowAdjustWaitHandle.Dispose(); } - var errorOccuredWaitHandle = _errorOccuredWaitHandle; - if (errorOccuredWaitHandle != null) - { - _errorOccuredWaitHandle = null; - errorOccuredWaitHandle.Dispose(); - } - _isDisposed = true; } } diff --git a/src/Renci.SshNet/ConnectionInfo.cs b/src/Renci.SshNet/ConnectionInfo.cs index ba8f38b9..f9b872d3 100644 --- a/src/Renci.SshNet/ConnectionInfo.cs +++ b/src/Renci.SshNet/ConnectionInfo.cs @@ -23,6 +23,22 @@ namespace Renci.SshNet { internal static int DefaultPort = 22; + /// + /// The default connection timeout. + /// + /// + /// 30 seconds. + /// + private static readonly TimeSpan DefaultTimeout = TimeSpan.FromSeconds(30); + + /// + /// The default channel close timeout. + /// + /// + /// 1 second. + /// + private static readonly TimeSpan DefaultChannelCloseTimeout = TimeSpan.FromSeconds(1); + /// /// Gets supported key exchange algorithms for this connection. /// @@ -126,6 +142,18 @@ namespace Renci.SshNet /// public TimeSpan Timeout { get; set; } + /// + /// Gets or sets the timeout to used when waiting for a server to acknowledge closing a channel. + /// + /// + /// The channel close timeout. The default value is 1 second. + /// + /// + /// If a server does not send a SSH2_MSG_CHANNEL_CLOSE message before the specified timeout + /// elapses, the channel will be closed immediately. + /// + public TimeSpan ChannelCloseTimeout { get; set; } + /// /// Gets or sets the character encoding. /// @@ -286,7 +314,8 @@ namespace Renci.SshNet throw new ArgumentException("At least one authentication method should be specified.", "authenticationMethods"); // Set default connection values - Timeout = TimeSpan.FromSeconds(30); + Timeout = DefaultTimeout; + ChannelCloseTimeout = DefaultChannelCloseTimeout; RetryAttempts = 10; MaxSessions = 10; Encoding = Encoding.UTF8; diff --git a/src/Renci.SshNet/IConnectionInfo.cs b/src/Renci.SshNet/IConnectionInfo.cs index 27ad00d5..a50c213b 100644 --- a/src/Renci.SshNet/IConnectionInfo.cs +++ b/src/Renci.SshNet/IConnectionInfo.cs @@ -40,6 +40,18 @@ namespace Renci.SshNet /// internal interface IConnectionInfo { + /// + /// Gets or sets the timeout to used when waiting for a server to acknowledge closing a channel. + /// + /// + /// The channel close timeout. The default value is 1 second. + /// + /// + /// If a server does not send a SSH2_MSG_CHANNEL_CLOSE message before the specified timeout + /// elapses, the channel will be closed immediately. + /// + TimeSpan ChannelCloseTimeout { get; } + /// /// Gets the supported channel requests for this connection. /// diff --git a/src/Renci.SshNet/ISession.cs b/src/Renci.SshNet/ISession.cs index bb778d91..6d988766 100644 --- a/src/Renci.SshNet/ISession.cs +++ b/src/Renci.SshNet/ISession.cs @@ -156,6 +156,10 @@ namespace Renci.SshNet /// void WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout); + WaitResult TryWait(WaitHandle waitHandle, TimeSpan timeout, out Exception exception); + + WaitResult TryWait(WaitHandle waitHandle, TimeSpan timeout); + /// /// Occurs when message received /// diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index f66416d3..33af7656 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -798,6 +798,53 @@ namespace Renci.SshNet WaitOnHandle(waitHandle, ConnectionInfo.Timeout); } + WaitResult ISession.TryWait(WaitHandle waitHandle, TimeSpan timeout) + { + Exception exception; + return TryWait(waitHandle, timeout, out exception); + } + + WaitResult ISession.TryWait(WaitHandle waitHandle, TimeSpan timeout, out Exception exception) + { + return TryWait(waitHandle, timeout, out exception); + } + + private WaitResult TryWait(WaitHandle waitHandle, TimeSpan timeout, out Exception exception) + { + if (waitHandle == null) + throw new ArgumentNullException("waitHandle"); + + var waitHandles = new[] + { + _exceptionWaitHandle, + _messageListenerCompleted, + waitHandle + }; + + switch (WaitHandle.WaitAny(waitHandles, timeout)) + { + case 0: + if (_exception is SshConnectionException) + { + exception = null; + return WaitResult.Disconnected; + } + exception = _exception; + return WaitResult.Failed; + case 1: + exception = null; + return WaitResult.Disconnected; + case 2: + exception = null; + return WaitResult.Success; + case WaitHandle.WaitTimeout: + exception = null; + return WaitResult.TimedOut; + default: + throw new InvalidOperationException("Unexpected result."); + } + } + /// /// Waits for the specified handle or the exception handle for the receive thread /// to signal within the specified timeout. @@ -1077,7 +1124,7 @@ namespace Renci.SshNet var serverHash = data.Take(data.Length - serverMacLength, serverMacLength); // TODO add IsEqualTo overload that takes left+right index and number of bytes to compare; - // TODO that way we can eliminate the extrate allocation of the Take above + // TODO that way we can eliminate the extra allocation of the Take above if (!serverHash.IsEqualTo(clientHash)) { throw new SshConnectionException("MAC error", DisconnectReason.MacError); @@ -2412,8 +2459,9 @@ namespace Renci.SshNet /// /// A new "forwarded-tcpip" SSH channel. /// - IChannelForwardedTcpip ISession.CreateChannelForwardedTcpip(uint remoteChannelNumber, uint remoteWindowSize, - uint remoteChannelDataPacketSize) + IChannelForwardedTcpip ISession.CreateChannelForwardedTcpip(uint remoteChannelNumber, + uint remoteWindowSize, + uint remoteChannelDataPacketSize) { return new ChannelForwardedTcpip(this, NextChannelNumber, @@ -2455,4 +2503,12 @@ namespace Renci.SshNet #endregion ISession implementation } + + internal enum WaitResult + { + Success = 1, + TimedOut = 2, + Disconnected = 3, + Failed = 4 + } } \ No newline at end of file