Skip to content

Commit 8c5b0e1

Browse files
committed
Harden test.
1 parent 5048498 commit 8c5b0e1

File tree

1 file changed

+67
-41
lines changed

1 file changed

+67
-41
lines changed

src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound.cs

Lines changed: 67 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Diagnostics;
43
using System.Globalization;
54
using System.Net;
65
using System.Threading;
@@ -22,8 +21,7 @@ public class ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound
2221
private IList<ExceptionEventArgs> _exceptionRegister;
2322
private IPEndPoint _bindEndpoint;
2423
private IPEndPoint _remoteEndpoint;
25-
private TimeSpan _expectedElapsedTime;
26-
private TimeSpan _elapsedTimeOfStop;
24+
private TimeSpan _bindSleepTime;
2725
private uint _remoteChannelNumberWhileClosing;
2826
private uint _remoteWindowSizeWhileClosing;
2927
private uint _remotePacketSizeWhileClosing;
@@ -32,23 +30,16 @@ public class ForwardedPortRemoteTest_Dispose_PortStarted_ChannelBound
3230
private uint _remotePacketSizeStarted;
3331
private string _originatorAddress;
3432
private uint _originatorPort;
33+
private ManualResetEvent _channelBindStarted;
34+
private ManualResetEvent _channelBindCompleted;
3535

3636
protected ForwardedPortRemote ForwardedPort { get; private set; }
3737

3838
[TestInitialize]
3939
public void Setup()
4040
{
4141
Arrange();
42-
43-
// calculate stop time here instead of in Act() because that method can be overridden
44-
45-
var stopwatch = new Stopwatch();
46-
stopwatch.Start();
47-
4842
Act();
49-
50-
stopwatch.Stop();
51-
_elapsedTimeOfStop = stopwatch.Elapsed;
5243
}
5344

5445
[TestCleanup]
@@ -59,30 +50,59 @@ public void Cleanup()
5950
ForwardedPort.Dispose();
6051
ForwardedPort = null;
6152
}
53+
54+
if (_channelBindStarted != null)
55+
{
56+
_channelBindStarted.Dispose();
57+
_channelBindStarted = null;
58+
}
59+
60+
if (_channelBindCompleted != null)
61+
{
62+
_channelBindCompleted.Dispose();
63+
_channelBindCompleted = null;
64+
}
6265
}
6366

64-
protected void Arrange()
67+
private void CreateMocks()
68+
{
69+
_connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict);
70+
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
71+
_channelMock = new Mock<IChannelForwardedTcpip>(MockBehavior.Strict);
72+
}
73+
74+
private void SetUpData()
6575
{
6676
var random = new Random();
77+
6778
_closingRegister = new List<EventArgs>();
6879
_exceptionRegister = new List<ExceptionEventArgs>();
6980
_bindEndpoint = new IPEndPoint(IPAddress.Any, random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort));
7081
_remoteEndpoint = new IPEndPoint(IPAddress.Parse("193.168.1.5"), random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort));
71-
_expectedElapsedTime = TimeSpan.FromMilliseconds(random.Next(100, 500));
72-
ForwardedPort = new ForwardedPortRemote(_bindEndpoint.Address, (uint)_bindEndpoint.Port, _remoteEndpoint.Address, (uint)_remoteEndpoint.Port);
82+
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 500));
7383
_remoteChannelNumberWhileClosing = (uint) random.Next(0, 1000);
7484
_remoteWindowSizeWhileClosing = (uint) random.Next(0, int.MaxValue);
7585
_remotePacketSizeWhileClosing = (uint) random.Next(0, int.MaxValue);
76-
_remoteChannelNumberStarted = (uint)random.Next(0, 1000);
77-
_remoteWindowSizeStarted = (uint)random.Next(0, int.MaxValue);
78-
_remotePacketSizeStarted = (uint)random.Next(0, int.MaxValue);
86+
_remoteChannelNumberStarted = (uint) random.Next(0, 1000);
87+
_remoteWindowSizeStarted = (uint) random.Next(0, int.MaxValue);
88+
_remotePacketSizeStarted = (uint) random.Next(0, int.MaxValue);
7989
_originatorAddress = random.Next().ToString(CultureInfo.InvariantCulture);
80-
_originatorPort = (uint)random.Next(0, int.MaxValue);
90+
_originatorPort = (uint) random.Next(0, int.MaxValue);
91+
_channelBindStarted = new ManualResetEvent(false);
92+
_channelBindCompleted = new ManualResetEvent(false);
8193

82-
_connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict);
83-
_sessionMock = new Mock<ISession>(MockBehavior.Strict);
84-
_channelMock = new Mock<IChannelForwardedTcpip>(MockBehavior.Strict);
94+
ForwardedPort = new ForwardedPortRemote(_bindEndpoint.Address, (uint)_bindEndpoint.Port, _remoteEndpoint.Address, (uint)_remoteEndpoint.Port);
95+
ForwardedPort.Closing += (sender, args) =>
96+
{
97+
_closingRegister.Add(args);
98+
_sessionMock.Raise(p => p.ChannelOpenReceived += null, new MessageEventArgs<ChannelOpenMessage>(new ChannelOpenMessage(_remoteChannelNumberWhileClosing, _remoteWindowSizeWhileClosing, _remotePacketSizeWhileClosing, new ForwardedTcpipChannelInfo(ForwardedPort.BoundHost, ForwardedPort.BoundPort, _originatorAddress, _originatorPort))));
99+
};
100+
ForwardedPort.Exception += (sender, args) => _exceptionRegister.Add(args);
101+
ForwardedPort.Session = _sessionMock.Object;
102+
}
85103

104+
private void SetupMocks()
105+
{
86106
_connectionInfoMock.Setup(p => p.Timeout).Returns(TimeSpan.FromSeconds(15));
87107
_sessionMock.Setup(p => p.IsConnected).Returns(true);
88108
_sessionMock.Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
@@ -109,7 +129,12 @@ protected void Arrange()
109129
p.Bind(
110130
It.Is<IPEndPoint>(
111131
ep => ep.Address.Equals(_remoteEndpoint.Address) && ep.Port == _remoteEndpoint.Port),
112-
ForwardedPort)).Callback(() => Thread.Sleep(_expectedElapsedTime));
132+
ForwardedPort)).Callback(() =>
133+
{
134+
_channelBindStarted.Set();
135+
Thread.Sleep(_bindSleepTime);
136+
_channelBindCompleted.Set();
137+
});
113138
_channelMock.Setup(p => p.Close());
114139
_channelMock.Setup(p => p.Dispose());
115140
_sessionMock.Setup(
@@ -118,37 +143,38 @@ protected void Arrange()
118143
It.Is<GlobalRequestMessage>(
119144
g =>
120145
g.RequestName == GlobalRequestName.CancelTcpIpForward &&
121-
g.AddressToBind == ForwardedPort.BoundHost && g.PortToBind == ForwardedPort.BoundPort)));
122-
_sessionMock.Setup(p => p.MessageListenerCompleted).Returns(new ManualResetEvent(true));
146+
g.AddressToBind == ForwardedPort.BoundHost && g.PortToBind == ForwardedPort.BoundPort))).Callback(
147+
() =>
148+
{
149+
// raise event confirming that forwarded port was cancelled
150+
_sessionMock.Raise(p => p.RequestSuccessReceived += null, new MessageEventArgs<RequestSuccessMessage>(new RequestSuccessMessage()));
151+
});
152+
_sessionMock.Setup(p => p.MessageListenerCompleted).Returns(new ManualResetEvent(false));
153+
}
154+
155+
protected void Arrange()
156+
{
157+
CreateMocks();
158+
SetUpData();
159+
SetupMocks();
123160

124-
ForwardedPort.Closing += (sender, args) =>
125-
{
126-
_closingRegister.Add(args);
127-
_sessionMock.Raise(p => p.ChannelOpenReceived += null, new MessageEventArgs<ChannelOpenMessage>(new ChannelOpenMessage(_remoteChannelNumberWhileClosing, _remoteWindowSizeWhileClosing, _remotePacketSizeWhileClosing, new ForwardedTcpipChannelInfo(ForwardedPort.BoundHost, ForwardedPort.BoundPort, _originatorAddress, _originatorPort))));
128-
};
129-
ForwardedPort.Exception += (sender, args) => _exceptionRegister.Add(args);
130-
ForwardedPort.Session = _sessionMock.Object;
131161
ForwardedPort.Start();
132162

133163
_sessionMock.Raise(p => p.ChannelOpenReceived += null, new MessageEventArgs<ChannelOpenMessage>(new ChannelOpenMessage(_remoteChannelNumberStarted, _remoteWindowSizeStarted, _remotePacketSizeStarted, new ForwardedTcpipChannelInfo(ForwardedPort.BoundHost, ForwardedPort.BoundPort, _originatorAddress, _originatorPort))));
164+
165+
// wait until channel is bound
166+
Assert.IsTrue(_channelBindStarted.WaitOne(TimeSpan.FromMilliseconds(200)));
134167
}
135168

136169
protected virtual void Act()
137170
{
138-
var stopwatch = new Stopwatch();
139-
stopwatch.Start();
140-
141171
ForwardedPort.Dispose();
142-
143-
stopwatch.Stop();
144-
_elapsedTimeOfStop = stopwatch.Elapsed;
145172
}
146173

147174
[TestMethod]
148-
public void StopShouldBlockUntilBoundChannelHasClosed()
175+
public void ShouldBlockUntilBindHasCompleted()
149176
{
150-
Assert.IsTrue(_elapsedTimeOfStop >= _expectedElapsedTime, string.Format("Expected {0} or greater but was {1}.", _expectedElapsedTime.TotalMilliseconds, _elapsedTimeOfStop.TotalMilliseconds));
151-
Assert.IsTrue(_elapsedTimeOfStop < _expectedElapsedTime.Add(TimeSpan.FromMilliseconds(200)));
177+
Assert.IsTrue(_channelBindCompleted.WaitOne(0));
152178
}
153179

154180
[TestMethod]

0 commit comments

Comments
 (0)