Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7d5ccb8
POC unit tests
IgorMilavec Dec 15, 2021
2a47c9e
Modify AppVeyor test script to only run net472 and net5.0
IgorMilavec Dec 16, 2021
ba7ecbb
Fix ScpClientTest_*.DisposeOnPipeStreamShouldBeInvokedOnce in modern …
IgorMilavec Dec 16, 2021
81b3a16
Fix runtime and culture dependant tests. Should we test this at all?
IgorMilavec Dec 16, 2021
be97986
Make ForwardedPortDynamic exception visible
IgorMilavec Dec 16, 2021
f91c5f1
Fix PipeStream_Close_BlockingWrite synchronization
IgorMilavec Dec 16, 2021
8c66267
Removed CountdownEventTest for FEATURE_THREAD_COUNTDOWNEVENT
IgorMilavec Dec 16, 2021
5304296
Remove Thread.Abort()
IgorMilavec Dec 16, 2021
a7a9474
Fix another runtime dependant string
IgorMilavec Dec 16, 2021
de9faec
Raise AppVeyor number of ports to avoid dynamic port exhaustion
IgorMilavec Dec 17, 2021
5bc16c8
Fix previous "speeedup" of ChannelForwardedTcpipTest_Dispose_SessionI…
IgorMilavec Dec 17, 2021
36b751b
Speedup tests
IgorMilavec Dec 17, 2021
362910f
Ignore SocketError.TryAgain when expecting SocketError.HostNotFound
IgorMilavec Dec 17, 2021
c1a657a
Better ObjectDisposedHandling in AsyncSocketListener
IgorMilavec Dec 17, 2021
bae6c54
Handle SocketError.ConnectionAborted in ForwardedPortDynamic
IgorMilavec Dec 17, 2021
48e1af3
Rename test to match implementation
IgorMilavec Dec 17, 2021
f0a8f5f
Fix BaseClientTest_Connected_KeepAliveInterval_NotNegativeOne timing
IgorMilavec Dec 17, 2021
382649b
Set C# 7.3 in Tests.csproj to limit intellisense's suggestions under …
IgorMilavec Dec 17, 2021
07c1535
Add SftpClientTest.*Async
IgorMilavec Dec 17, 2021
0030b35
Add SftpFileStreamTest_OpenAsync_*
IgorMilavec Dec 19, 2021
2fbdb46
Add SftpFileStreamTest_WriteAsync_*
IgorMilavec Dec 22, 2021
3547504
Add SftpFileStreamTest_ReadAsync_*
IgorMilavec Dec 22, 2021
3506707
Remove unrelated changes
IgorMilavec Feb 12, 2022
9f45e7f
Align AppVeyor script with Test project target frameworks
IgorMilavec Feb 12, 2022
a53f35b
Revert unrelated changes
IgorMilavec Feb 12, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
os: Visual Studio 2019

init:
- netsh int ipv4 set dynamicport tcp start=1025 num=64510
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this resolve any issues?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was more of a "we open and close a lot of ports in tests and the tests are sporadically failing with connection failures, so more client-side ports can't hurt" line of reasoning.


before_build:
- nuget restore src\Renci.SshNet.VS2019.sln

Expand All @@ -9,6 +12,6 @@ build:

test_script:
- cmd: >-
vstest.console /logger:Appveyor src\Renci.SshNet.Tests\bin\Debug\net40\Renci.SshNet.Tests.dll /TestCaseFilter:"TestCategory!=integration&TestCategory!=LongRunning"
vstest.console /logger:Appveyor src\Renci.SshNet.Tests\bin\Debug\net472\Renci.SshNet.Tests.dll /TestCaseFilter:"TestCategory!=integration&TestCategory!=LongRunning"

vstest.console /logger:Appveyor src\Renci.SshNet.Tests\bin\Debug\net35\Renci.SshNet.Tests.dll /TestCaseFilter:"TestCategory!=integration&TestCategory!=LongRunning"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd first like to discuss dropping .NET 3.5 support.
Perhaps we'll have a final release supporting the legacy frameworks.
As I said, let's discuss this first.

vstest.console /logger:Appveyor src\Renci.SshNet.Tests\bin\Debug\net5.0\Renci.SshNet.Tests.dll /TestCaseFilter:"TestCategory!=integration&TestCategory!=LongRunning"
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public void IsConnectedOnSessionShouldBeInvokedOnce()
}

[TestMethod]
public void SendMessageOnSessionShouldBeInvokedThreeTimes()
public void SendMessageOnSessionShouldBeInvokedOneTime()
{
// allow keep-alive to be sent once
Thread.Sleep(100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class BaseClientTest_Connected_KeepAliveInterval_NotNegativeOne : BaseCli
private ConnectionInfo _connectionInfo;
private TimeSpan _keepAliveInterval;
private int _keepAliveCount;
private int _actualKeepAliveCount;

protected override void SetupData()
{
Expand Down Expand Up @@ -58,6 +59,8 @@ protected override void Act()

// allow keep-alive to be sent a few times
Thread.Sleep(195);

_actualKeepAliveCount = _keepAliveCount;
}

[TestMethod]
Expand Down Expand Up @@ -94,7 +97,7 @@ public void IsConnectedOnSessionShouldBeInvokedOnce()
[TestMethod]
public void SendMessageOnSessionShouldBeInvokedThreeTimes()
{
_sessionMock.Verify(p => p.TrySendMessage(It.IsAny<IgnoreMessage>()), Times.Exactly(3));
Assert.AreEqual(3, _actualKeepAliveCount);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you prefer this over verifying the mock?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was the only way I found to stop this test failing sporadically for me. Let me remove non-Async changes from the PR and then we'll disuss, OK?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. I flagged some other changes that you can keep in this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and .... THANKS!

}

private class MyClient : BaseClient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,13 @@ public void CleanUp()
_remoteListener = null;
}

if (_channelThread != null)
{
if (_channelThread.IsAlive)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you did this because Thread.Abort is no longer supported on .NET (Core).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

_channelThread.Abort();
_channelThread = null;
}
if (_channel != null)
{
_channel.Dispose();
_channel = null;
}

_channelThread = null;
}

private void Arrange()
Expand Down Expand Up @@ -138,10 +134,12 @@ private void Arrange()
_remoteWindowSize,
_remotePacketSize);

ManualResetEvent isReady = new ManualResetEvent(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this resolves an issue, but I always prefer to see the issue before a fix is applied for it.

_channelThread = new Thread(() =>
{
try
{
isReady.Set();
_channel.Bind(_remoteEndpoint, _forwardedPortMock.Object);
}
catch (Exception ex)
Expand All @@ -156,6 +154,7 @@ private void Arrange()
_channelThread.Start();

// give channel time to bind to remote endpoint
isReady.WaitOne(10000);
Thread.Sleep(100);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofReceived
private ManualResetEvent _channelClosedReceived;
private ManualResetEvent _channelClosedEventHandlerCompleted;
private Thread _raiseChannelCloseReceivedThread;
private ManualResetEvent _threadStopEvent;

protected override void SetupData()
{
Expand All @@ -43,6 +44,7 @@ protected override void SetupData()
_channelClosedReceived = new ManualResetEvent(false);
_channelClosedEventHandlerCompleted = new ManualResetEvent(false);
_raiseChannelCloseReceivedThread = null;
_threadStopEvent = new ManualResetEvent(false);
}

protected override void SetupMocks()
Expand Down Expand Up @@ -80,7 +82,9 @@ protected override void SetupMocks()
SessionMock.Raise(s => s.ChannelCloseReceived += null, new MessageEventArgs<ChannelCloseMessage>(new ChannelCloseMessage(_localChannelNumber)));
});
_raiseChannelCloseReceivedThread.Start();
waitHandle.WaitOne();

WaitHandle[] waitHandles = new WaitHandle[2] { waitHandle, _threadStopEvent };
WaitHandle.WaitAny(waitHandles);
})
.Returns(WaitResult.Success);
}
Expand All @@ -98,7 +102,7 @@ public void TearDown()
{
if (!_raiseChannelCloseReceivedThread.Join(1000))
{
_raiseChannelCloseReceivedThread.Abort();
_threadStopEvent.Set();
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/Renci.SshNet.Tests/Classes/ClientAuthenticationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public void Ctor_PartialSuccessLimit_Zero()
catch (ArgumentOutOfRangeException ex)
{
Assert.IsNull(ex.InnerException);
#if NETFRAMEWORK
Assert.AreEqual(string.Format("Cannot be less than one.{0}Parameter name: {1}", Environment.NewLine, ex.ParamName), ex.Message);
#else
Assert.AreEqual(string.Format("Cannot be less than one. (Parameter '{1}')", Environment.NewLine, ex.ParamName), ex.Message);
#endif
Assert.AreEqual("partialSuccessLimit", ex.ParamName);
}
}
Expand All @@ -46,7 +50,11 @@ public void Ctor_PartialSuccessLimit_Negative()
catch (ArgumentOutOfRangeException ex)
{
Assert.IsNull(ex.InnerException);
#if NETFRAMEWORK
Assert.AreEqual(string.Format("Cannot be less than one.{0}Parameter name: {1}", Environment.NewLine, ex.ParamName), ex.Message);
#else
Assert.AreEqual(string.Format("Cannot be less than one. (Parameter '{1}')", Environment.NewLine, ex.ParamName), ex.Message);
#endif
Assert.AreEqual("partialSuccessLimit", ex.ParamName);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/Renci.SshNet.Tests/Classes/Common/CountdownEventTest.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
#if !FEATURE_THREAD_COUNTDOWNEVENT
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
#if !FEATURE_THREAD_COUNTDOWNEVENT
using CountdownEvent = Renci.SshNet.Common.CountdownEvent;
#endif

namespace Renci.SshNet.Tests.Classes.Common
{
Expand Down Expand Up @@ -336,3 +335,4 @@ private static CountdownEvent CreateCountdownEvent(int initialCount)
}
}
}
#endif
4 changes: 4 additions & 0 deletions src/Renci.SshNet.Tests/Classes/Common/PacketDumpTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ public void Create_ByteArrayAndIndentLevel_IndentLevelLessThanZero()
catch (ArgumentOutOfRangeException ex)
{
Assert.IsNull(ex.InnerException);
#if NETFRAMEWORK
Assert.AreEqual(string.Format("Cannot be less than zero.{0}Parameter name: {1}", Environment.NewLine, ex.ParamName), ex.Message);
#else
Assert.AreEqual(string.Format("Cannot be less than zero. (Parameter '{1}')", Environment.NewLine, ex.ParamName), ex.Message);
#endif
Assert.AreEqual("indentLevel", ex.ParamName);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ public class PipeStream_Close_BlockingWrite : TripleATestBase
{
private PipeStream _pipeStream;
private Exception _writeException;
private Thread _writehread;
private Thread _writeThread;

protected override void Arrange()
{
_pipeStream = new PipeStream {MaxBufferLength = 3};

_writehread = new Thread(() =>
ManualResetEvent isArranged = new ManualResetEvent(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this resolves an issue, but I always prefer to see the issue before a fix is applied for it.
Let's separate this and similar changes out.

_writeThread = new Thread(() =>
{
_pipeStream.WriteByte(10);
_pipeStream.WriteByte(13);
Expand All @@ -27,32 +28,32 @@ protected override void Arrange()
// until bytes are read or the stream is closed
try
{
isArranged.Set();
_pipeStream.WriteByte(35);
}
catch (Exception ex)
{
_writeException = ex;
throw;
}
});
_writehread.Start();
_writeThread.Start();

// ensure we've started writing
Assert.IsFalse(_writehread.Join(50));
isArranged.WaitOne(10000);
}

protected override void Act()
{
_pipeStream.Close();

// give write time to complete
_writehread.Join(100);
Assert.IsTrue(_writeThread.Join(10000));
}

[TestMethod]
public void BlockingWriteShouldHaveBeenInterrupted()
{
Assert.AreEqual(ThreadState.Stopped, _writehread.ThreadState);
Assert.AreEqual(ThreadState.Stopped, _writeThread.ThreadState);
}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading;
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Renci.SshNet.Common;
using Renci.SshNet.Tests.Common;
Expand Down Expand Up @@ -97,20 +98,25 @@ public void WriteCausesSubsequentReadToBlockUntilRequestedNumberOfBytesAreAvaila
var buffer = new byte[4];
int bytesRead = int.MaxValue;

ManualResetEvent isReady = new ManualResetEvent(false);
Thread readThread = new Thread(() =>
{
isReady.Set();
bytesRead = _pipeStream.Read(buffer, 0, buffer.Length);
});
readThread.Start();

Assert.IsTrue(isReady.WaitOne(10000));
Assert.IsFalse(readThread.Join(500));
readThread.Abort();

Assert.AreEqual(int.MaxValue, bytesRead);
Assert.AreEqual(0, buffer[0]);
Assert.AreEqual(0, buffer[1]);
Assert.AreEqual(0, buffer[2]);
Assert.AreEqual(0, buffer[3]);

Assert.IsFalse(readThread.Join(50));
_pipeStream.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ public void Path_Empty()
catch (ArgumentException ex)
{
Assert.IsNull(ex.InnerException);
#if NETFRAMEWORK
Assert.AreEqual(string.Format("The path is a zero-length string.{0}Parameter name: {1}", Environment.NewLine, ex.ParamName), ex.Message);
#else
Assert.AreEqual(string.Format("The path is a zero-length string. (Parameter '{1}')", Environment.NewLine, ex.ParamName), ex.Message);
#endif
Assert.AreEqual("path", ex.ParamName);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ public void ConnectShouldHaveThrownSocketException()
{
Assert.IsNotNull(_actualException);
Assert.IsNull(_actualException.InnerException);
Assert.AreEqual(SocketError.HostNotFound, _actualException.SocketErrorCode);
if (_actualException.SocketErrorCode != SocketError.TryAgain)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this resolves an issue, but I always prefer to see the issue before a fix is applied for it.

{
Assert.AreEqual(SocketError.HostNotFound, _actualException.SocketErrorCode);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ public void ConnectShouldHaveThrownSocketException()
{
Assert.IsNotNull(_actualException);
Assert.IsNull(_actualException.InnerException);
Assert.AreEqual(SocketError.HostNotFound, _actualException.SocketErrorCode);
if (_actualException.SocketErrorCode != SocketError.TryAgain)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this resolves an issue, but I always prefer to see the issue before a fix is applied for it.

{
Assert.AreEqual(SocketError.HostNotFound, _actualException.SocketErrorCode);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private void SetupData()
_exceptionRegister = new List<ExceptionEventArgs>();
_endpoint = new IPEndPoint(IPAddress.Loopback, 8122);
_remoteEndpoint = new IPEndPoint(IPAddress.Parse("193.168.1.5"), random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 500));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 200));
_userName = random.Next().ToString(CultureInfo.InvariantCulture);
_channelBindStarted = new ManualResetEvent(false);
_channelBindCompleted = new ManualResetEvent(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ public void ClosingShouldHaveFiredOnce()
[TestMethod]
public void ExceptionShouldNotHaveFired()
{
Assert.AreEqual(0, _exceptionRegister.Count);
if (_exceptionRegister.Count > 0)
{
throw new Exception("ForwardedPortDynamic rased an exception: " + _exceptionRegister[0].Exception.Message, _exceptionRegister[0].Exception);
}
}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private void SetupData()
_exceptionRegister = new List<ExceptionEventArgs>();
_endpoint = new IPEndPoint(IPAddress.Loopback, 8122);
_remoteEndpoint = new IPEndPoint(IPAddress.Parse("193.168.1.5"), random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 500));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 200));
_userName = random.Next().ToString(CultureInfo.InvariantCulture);
_forwardedPort = new ForwardedPortDynamic(_endpoint.Address.ToString(), (uint) _endpoint.Port);
_sessionException = new Exception();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private void SetupData()
_exceptionRegister = new List<ExceptionEventArgs>();
_endpoint = new IPEndPoint(IPAddress.Loopback, 8122);
_remoteEndpoint = new IPEndPoint(IPAddress.Parse("193.168.1.5"), random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 500));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 200));
_userName = random.Next().ToString(CultureInfo.InvariantCulture);
_channelBindStarted = new ManualResetEvent(false);
_channelBindCompleted = new ManualResetEvent(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,10 @@ public void ClosingShouldHaveFiredOnce()
[TestMethod]
public void ExceptionShouldNotHaveFired()
{
Assert.AreEqual(0, _exceptionRegister.Count);
if (_exceptionRegister.Count > 0)
{
throw new Exception("ForwardedPortDynamic rased an exception: " + _exceptionRegister[0].Exception.Message, _exceptionRegister[0].Exception);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IgorMilavec No need to move these changes (here and elsewhere) out of this PR.

}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ protected void Arrange()
_exceptionRegister = new List<ExceptionEventArgs>();
_localEndpoint = new IPEndPoint(IPAddress.Loopback, 8122);
_remoteEndpoint = new IPEndPoint(IPAddress.Parse("193.168.1.5"), random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 500));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 200));
_forwardedPort = new ForwardedPortLocal(_localEndpoint.Address.ToString(), (uint) _localEndpoint.Port, _remoteEndpoint.Address.ToString(), (uint) _remoteEndpoint.Port);
_channelBindStarted = new ManualResetEvent(false);
_channelBindCompleted = new ManualResetEvent(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ private void SetupData()
_exceptionRegister = new List<ExceptionEventArgs>();
_localEndpoint = new IPEndPoint(IPAddress.Loopback, 8122);
_remoteEndpoint = new IPEndPoint(IPAddress.Parse("193.168.1.5"), random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 500));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 200));
_channelBound = new ManualResetEvent(false);
_channelBindCompleted = new ManualResetEvent(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ private void SetUpData()
_exceptionRegister = new List<ExceptionEventArgs>();
_bindEndpoint = new IPEndPoint(IPAddress.Any, random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort));
_remoteEndpoint = new IPEndPoint(IPAddress.Parse("193.168.1.5"), random.Next(IPEndPoint.MinPort, IPEndPoint.MaxPort));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 500));
_bindSleepTime = TimeSpan.FromMilliseconds(random.Next(100, 200));
_remoteChannelNumberWhileClosing = (uint) random.Next(0, 1000);
_remoteWindowSizeWhileClosing = (uint) random.Next(0, int.MaxValue);
_remotePacketSizeWhileClosing = (uint) random.Next(0, int.MaxValue);
Expand Down
Loading