diff --git a/appveyor.yml b/appveyor.yml index 74f4f927b..88a674cff 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -28,7 +28,7 @@ for: - sh: dotnet test -f net8.0 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_unit_test_net_8_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_unit_test_net_8_coverage.xml test/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj - sh: echo "Run integration tests" - sh: dotnet test -f net8.0 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_integration_test_net_8_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_integration_test_net_8_coverage.xml test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj - - sh: dotnet test -f net48 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_integration_test_net_48_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_integration_test_net_48_coverage.xml --filter "Name=ChaCha20Poly1305|Name~Ecdh|Name~Zlib" test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj + - sh: dotnet test -f net48 -c Debug --no-restore --no-build --results-directory artifacts --logger Appveyor --logger "console;verbosity=normal" --logger "liquid.md;LogFileName=linux_integration_test_net_48_report.md" -p:CollectCoverage=true -p:CoverletOutputFormat=cobertura -p:CoverletOutput=../../artifacts/linux_integration_test_net_48_coverage.xml --filter Name\!~ECDsa test/Renci.SshNet.IntegrationTests/Renci.SshNet.IntegrationTests.csproj - matrix: diff --git a/test/Renci.SshNet.IntegrationTests/SshTests.cs b/test/Renci.SshNet.IntegrationTests/SshTests.cs index ba179d7e3..2888e74e2 100644 --- a/test/Renci.SshNet.IntegrationTests/SshTests.cs +++ b/test/Renci.SshNet.IntegrationTests/SshTests.cs @@ -655,17 +655,32 @@ public void Ssh_RemotePortForwarding() var endpoint1 = new IPEndPoint(ipv4HostAddress, 10000); var endpoint2 = new IPEndPoint(ipv4HostAddress, 10001); + var areBytesReceivedOnListener1 = false; + var areBytesReceivedOnListener2 = false; + var bytesReceivedOnListener1 = new List(); var bytesReceivedOnListener2 = new List(); using (var socketListener1 = new AsyncSocketListener(endpoint1)) using (var socketListener2 = new AsyncSocketListener(endpoint2)) + using (var bytesReceivedEventOnListener1 = new AutoResetEvent(false)) + using (var bytesReceivedEventOnListener2 = new AutoResetEvent(false)) using (var client = new SshClient(_connectionInfoFactory.Create())) { - socketListener1.BytesReceived += (received, socket) => bytesReceivedOnListener1.AddRange(received); + socketListener1.BytesReceived += (received, socket) => + { + bytesReceivedOnListener1.AddRange(received); + bytesReceivedEventOnListener1.Set(); + }; + socketListener1.Start(); - socketListener2.BytesReceived += (received, socket) => bytesReceivedOnListener2.AddRange(received); + socketListener2.BytesReceived += (received, socket) => + { + bytesReceivedOnListener2.AddRange(received); + bytesReceivedEventOnListener2.Set(); + }; + socketListener2.Start(); client.Connect(); @@ -706,10 +721,16 @@ public void Ssh_RemotePortForwarding() s.Close(); } + areBytesReceivedOnListener1 = bytesReceivedEventOnListener1.WaitOne(1000); + areBytesReceivedOnListener2 = bytesReceivedEventOnListener2.WaitOne(1000); + forwardedPort1.Stop(); forwardedPort2.Stop(); } + Assert.IsTrue(areBytesReceivedOnListener1); + Assert.IsTrue(areBytesReceivedOnListener2); + var textReceivedOnListener1 = Encoding.ASCII.GetString(bytesReceivedOnListener1.ToArray()); Assert.AreEqual("ABC\r\n", textReceivedOnListener1); diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs index e6af7394b..db8440036 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived.cs @@ -61,6 +61,7 @@ protected override void SetupMocks() { new Thread(() => { + _closeTimer.Start(); Thread.Sleep(100); // raise ChannelCloseReceived event to set waithandle for receiving // SSH_MSG_CHANNEL_CLOSE message from server which is waited on after @@ -68,7 +69,6 @@ protected override void SetupMocks() SessionMock.Raise(s => s.ChannelCloseReceived += null, new MessageEventArgs(new ChannelCloseMessage(_localChannelNumber))); }).Start(); - _closeTimer.Start(); try { waitHandle.WaitOne(); diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs index 89dc6c987..f6eb2933b 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelTest_Dispose_SessionIsConnectedAndChannelIsOpen_EofNotReceived_SendEofInvoked.cs @@ -66,6 +66,7 @@ protected override void SetupMocks() { new Thread(() => { + _closeTimer.Start(); Thread.Sleep(100); // raise ChannelCloseReceived event to set waithandle for receiving // SSH_MSG_CHANNEL_CLOSE message from server which is waited on after @@ -74,7 +75,6 @@ protected override void SetupMocks() new MessageEventArgs( new ChannelCloseMessage(_localChannelNumber))); }).Start(); - _closeTimer.Start(); try { w.WaitOne(); diff --git a/test/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs b/test/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs index d105d9a35..db0f10f25 100644 --- a/test/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs +++ b/test/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs @@ -41,6 +41,7 @@ public void ClientVersionIsRenciSshNet() [TestMethod] public void IncludeStrictKexPseudoAlgorithmInInitKex() { + Assert.IsTrue(FirstKexReceived.Wait(1000)); Assert.IsTrue(ServerBytesReceivedRegister.Count > 0); var kexInitMessage = new KeyExchangeInitMessage(); @@ -51,7 +52,9 @@ public void IncludeStrictKexPseudoAlgorithmInInitKex() [TestMethod] public void ShouldNotIncludeStrictKexPseudoAlgorithmInSubsequentKex() { - using var kexReceived = new ManualResetEventSlim(); + Assert.IsTrue(FirstKexReceived.Wait(1000)); + + using var subsequentKexReceived = new ManualResetEventSlim(); bool kexContainsPseudoAlg = true; ServerListener.BytesReceived += ServerListener_BytesReceived; @@ -64,13 +67,13 @@ void ServerListener_BytesReceived(byte[] bytesReceived, System.Net.Sockets.Socke var kexInitMessage = new KeyExchangeInitMessage(); kexInitMessage.Load(bytesReceived, 6, bytesReceived.Length - 6); kexContainsPseudoAlg = kexInitMessage.KeyExchangeAlgorithms.Contains("kex-strict-c-v00@openssh.com"); - kexReceived.Set(); + subsequentKexReceived.Set(); } } Session.SendMessage(Session.ClientInitMessage); - Assert.IsTrue(kexReceived.Wait(1000)); + Assert.IsTrue(subsequentKexReceived.Wait(1000)); Assert.IsFalse(kexContainsPseudoAlg); ServerListener.BytesReceived -= ServerListener_BytesReceived; diff --git a/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectedBase.cs b/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectedBase.cs index b507aac9f..0b7fad0e5 100644 --- a/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectedBase.cs +++ b/test/Renci.SshNet.Tests/Classes/SessionTest_ConnectedBase.cs @@ -4,6 +4,7 @@ using System.Net; using System.Net.Sockets; using System.Security.Cryptography; +using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -43,6 +44,7 @@ public abstract class SessionTest_ConnectedBase protected IList ErrorOccurredRegister { get; private set; } protected AsyncSocketListener ServerListener { get; private set; } protected IList ServerBytesReceivedRegister { get; private set; } + protected ManualResetEventSlim FirstKexReceived { get; private set; } protected Session Session { get; private set; } protected Socket ClientSocket { get; private set; } protected Socket ServerSocket { get; private set; } @@ -87,6 +89,12 @@ public void TearDown() ClientSocket.Shutdown(SocketShutdown.Both); ClientSocket.Dispose(); } + + if (FirstKexReceived != null) + { + FirstKexReceived.Dispose(); + FirstKexReceived = null; + } } protected virtual void SetupData() @@ -107,6 +115,7 @@ protected virtual void SetupData() DisconnectReceivedRegister = new List>(); ErrorOccurredRegister = new List(); ServerBytesReceivedRegister = new List(); + FirstKexReceived = new ManualResetEventSlim(); ServerIdentification = new SshIdentification("2.0", "OurServerStub"); _authenticationStarted = false; _socketFactory = new SocketFactory(); @@ -151,11 +160,16 @@ protected virtual void SetupData() { ServerBytesReceivedRegister.Add(received); - if (WaitForClientKeyExchangeInit && received.Length > 5 && received[5] == 20) + if (received.Length > 5 && received[5] == 20) { - // This is the KEXINIT. Send one back. - SendKeyExchangeInit(); - WaitForClientKeyExchangeInit = false; + if (WaitForClientKeyExchangeInit) + { + // This is the KEXINIT. Send one back. + SendKeyExchangeInit(); + WaitForClientKeyExchangeInit = false; + } + + FirstKexReceived.Set(); } }; ServerListener.Start();