From 40dad2a446f4da8949d61fb397dfc648164be732 Mon Sep 17 00:00:00 2001 From: Robert Hague Date: Sat, 6 Jul 2024 16:56:04 +0200 Subject: [PATCH 1/2] Stabilise some more tests --- ...nected_KeepAliveInterval_NotNegativeOne.cs | 12 +++---- ...pose_SessionIsConnectedAndChannelIsOpen.cs | 34 ++++++++----------- .../Classes/SessionTest_Connected.cs | 27 +++++++++++---- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/test/Renci.SshNet.Tests/Classes/BaseClientTest_Connected_KeepAliveInterval_NotNegativeOne.cs b/test/Renci.SshNet.Tests/Classes/BaseClientTest_Connected_KeepAliveInterval_NotNegativeOne.cs index cbc740b01..ba70f1938 100644 --- a/test/Renci.SshNet.Tests/Classes/BaseClientTest_Connected_KeepAliveInterval_NotNegativeOne.cs +++ b/test/Renci.SshNet.Tests/Classes/BaseClientTest_Connected_KeepAliveInterval_NotNegativeOne.cs @@ -59,13 +59,7 @@ protected override void Act() { _client.KeepAliveInterval = _keepAliveInterval; - // allow keep-alive to be sent a few times. .NET 8 is faster and - // we need to wait less because we want exactly three messages in a session. -#if NETFRAMEWORK - Thread.Sleep(195); -#else - Thread.Sleep(170); -#endif + Thread.Sleep(200); } [TestMethod] @@ -102,7 +96,9 @@ public void IsConnectedOnSessionShouldBeInvokedOnce() [TestMethod] public void SendMessageOnSessionShouldBeInvokedThreeTimes() { - SessionMock.Verify(p => p.TrySendMessage(It.IsAny()), Times.Exactly(3)); +#pragma warning disable IDE0002 // Name can be simplified; "Ambiguous reference between Moq.Range and System.Range" + SessionMock.Verify(p => p.TrySendMessage(It.IsAny()), Times.Between(2, 4, Moq.Range.Inclusive)); +#pragma warning restore IDE0002 } private class MyClient : BaseClient diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs index b92ebfebb..8b372e23c 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs @@ -30,7 +30,6 @@ public class ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpe private TimeSpan _channelCloseTimeout; private IPEndPoint _remoteEndpoint; private AsyncSocketListener _remoteListener; - private EventWaitHandle _channelBindFinishedWaitHandle; private Exception _channelException; private IList _connectedRegister; private IList _disconnectedRegister; @@ -76,7 +75,7 @@ private void Arrange() _remoteWindowSize = (uint)random.Next(0, int.MaxValue); _remotePacketSize = (uint)random.Next(100, 200); _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); - _channelBindFinishedWaitHandle = new ManualResetEvent(false); + using var channelOpened = new ManualResetEventSlim(false); _channelException = null; _connectedRegister = new List(); _disconnectedRegister = new List(); @@ -104,7 +103,8 @@ private void Arrange() m.LocalChannelNumber == _remoteChannelNumber && m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize && - m.RemoteChannelNumber == _localChannelNumber))); + m.RemoteChannelNumber == _localChannelNumber))) + .Callback(channelOpened.Set); _ = _sessionMock.InSequence(sequence) .Setup(p => p.IsConnected) .Returns(true); @@ -148,29 +148,26 @@ private void Arrange() _remotePacketSize); _channelThread = new Thread(() => + { + try + { + _channel.Bind(_remoteEndpoint, _forwardedPortMock.Object); + } + catch (Exception ex) { - try - { - _channel.Bind(_remoteEndpoint, _forwardedPortMock.Object); - } - catch (Exception ex) - { - _channelException = ex; - } - finally - { - _ = _channelBindFinishedWaitHandle.Set(); - } - }); + _channelException = ex; + } + }); _channelThread.Start(); - // give channel time to bind to remote endpoint - Thread.Sleep(100); + Assert.IsTrue(channelOpened.Wait(TimeSpan.FromSeconds(1))); } private void Act() { _channel.Dispose(); + + Assert.IsTrue(_channelThread.Join(TimeSpan.FromSeconds(1))); } [TestMethod] @@ -185,7 +182,6 @@ public void ChannelShouldShutdownSocketToRemoteListener() public void BindShouldHaveFinishedWithoutException() { Assert.IsNull(_channelException, _channelException?.ToString()); - Assert.IsTrue(_channelBindFinishedWaitHandle.WaitOne(0)); } [TestMethod] diff --git a/test/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs b/test/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs index d872ff183..bebbe14ec 100644 --- a/test/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs +++ b/test/Renci.SshNet.Tests/Classes/SessionTest_Connected.cs @@ -47,16 +47,29 @@ public void IncludeStrictKexPseudoAlgorithmInInitKex() [TestMethod] public void ShouldNotIncludeStrictKexPseudoAlgorithmInSubsequentKex() { - ServerBytesReceivedRegister.Clear(); - Session.SendMessage(Session.ClientInitMessage); + using var kexReceived = new ManualResetEventSlim(); + bool kexContainsPseudoAlg = true; - Thread.Sleep(100); + ServerListener.BytesReceived += ServerListener_BytesReceived; - Assert.IsTrue(ServerBytesReceivedRegister.Count > 0); + void ServerListener_BytesReceived(byte[] bytesReceived, System.Net.Sockets.Socket socket) + { + if (bytesReceived.Length > 5 && bytesReceived[5] == 20) + { + // SSH_MSG_KEXINIT = 20 + var kexInitMessage = new KeyExchangeInitMessage(); + kexInitMessage.Load(bytesReceived, 6, bytesReceived.Length - 6); + kexContainsPseudoAlg = kexInitMessage.KeyExchangeAlgorithms.Contains("kex-strict-c-v00@openssh.com"); + kexReceived.Set(); + } + } - var kexInitMessage = new KeyExchangeInitMessage(); - kexInitMessage.Load(ServerBytesReceivedRegister[0], 4 + 1 + 1, ServerBytesReceivedRegister[0].Length - 4 - 1 - 1); - Assert.IsFalse(kexInitMessage.KeyExchangeAlgorithms.Contains("kex-strict-c-v00@openssh.com")); + Session.SendMessage(Session.ClientInitMessage); + + Assert.IsTrue(kexReceived.Wait(1000)); + Assert.IsFalse(kexContainsPseudoAlg); + + ServerListener.BytesReceived -= ServerListener_BytesReceived; } [TestMethod] From 8f383f66272f2c594f5582101dfba469efa7232f Mon Sep 17 00:00:00 2001 From: Robert Hague Date: Sun, 7 Jul 2024 13:49:48 +0200 Subject: [PATCH 2/2] just increase the timeout --- ...TcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs index 8b372e23c..8eab76554 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelForwardedTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs @@ -75,7 +75,6 @@ private void Arrange() _remoteWindowSize = (uint)random.Next(0, int.MaxValue); _remotePacketSize = (uint)random.Next(100, 200); _channelCloseTimeout = TimeSpan.FromSeconds(random.Next(10, 20)); - using var channelOpened = new ManualResetEventSlim(false); _channelException = null; _connectedRegister = new List(); _disconnectedRegister = new List(); @@ -103,8 +102,7 @@ private void Arrange() m.LocalChannelNumber == _remoteChannelNumber && m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize && - m.RemoteChannelNumber == _localChannelNumber))) - .Callback(channelOpened.Set); + m.RemoteChannelNumber == _localChannelNumber))); _ = _sessionMock.InSequence(sequence) .Setup(p => p.IsConnected) .Returns(true); @@ -160,7 +158,8 @@ private void Arrange() }); _channelThread.Start(); - Assert.IsTrue(channelOpened.Wait(TimeSpan.FromSeconds(1))); + // give channel time to bind to remote endpoint + Thread.Sleep(300); } private void Act()