From 8d20a614d916f12d71dec4844814eeac3aa914c4 Mon Sep 17 00:00:00 2001 From: Rob Hague Date: Sat, 18 May 2024 12:22:51 +0200 Subject: [PATCH 1/2] More AsyncSocketListener patchwork This is Whack-a-mole part 2 in diagnosing or preventing the test host from crashing in CI. --- .../Common/AsyncSocketListener.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs b/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs index e162c9ef6..9727764fa 100644 --- a/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs +++ b/test/Renci.SshNet.Tests/Common/AsyncSocketListener.cs @@ -234,11 +234,7 @@ private void ReadCallback(IAsyncResult ar) try { // Read data from the client socket. - bytesRead = handler.EndReceive(ar, out var errorCode); - if (errorCode != SocketError.Success) - { - bytesRead = 0; - } + bytesRead = handler.EndReceive(ar); } catch (SocketException ex) { @@ -275,7 +271,7 @@ private void ReadCallback(IAsyncResult ar) return; } - void ConnectionDisconnected(bool doShutdownIfApplicable) + void ConnectionDisconnected() { SignalDisconnected(handler); @@ -290,11 +286,12 @@ void ConnectionDisconnected(bool doShutdownIfApplicable) try { - if (doShutdownIfApplicable) + if (handler.Connected) { handler.Shutdown(SocketShutdown.Send); - handler.Close(); } + + handler.Close(); } catch (SocketException ex) when (ex.SocketErrorCode == SocketError.ConnectionReset) { @@ -328,7 +325,7 @@ void ConnectionDisconnected(bool doShutdownIfApplicable) catch (ObjectDisposedException) { // TODO On .NET 7, sometimes we get ObjectDisposedException when _started but only on appveyor, locally it works - ConnectionDisconnected(doShutdownIfApplicable: false); + ConnectionDisconnected(); } catch (SocketException ex) { @@ -343,7 +340,7 @@ void ConnectionDisconnected(bool doShutdownIfApplicable) } else { - ConnectionDisconnected(doShutdownIfApplicable: true); + ConnectionDisconnected(); } } From cabb1ae1a77dbfee325e73e4a8c471bfc5de4054 Mon Sep 17 00:00:00 2001 From: Rob Hague Date: Sat, 18 May 2024 18:15:03 +0200 Subject: [PATCH 2/2] Fix test --- ...pTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs b/test/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs index ba0e44458..ae7abed92 100644 --- a/test/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs +++ b/test/Renci.SshNet.Tests/Classes/Channels/ChannelDirectTcpipTest_Dispose_SessionIsConnectedAndChannelIsOpen.cs @@ -130,12 +130,21 @@ private void Arrange() }) .Returns(WaitResult.Success); + using var barrier = new Barrier(2); + var localEndpoint = new IPEndPoint(IPAddress.Loopback, 8122); _listener = new AsyncSocketListener(localEndpoint); _listener.Connected += socket => { try { + // We need the Connect side and the Accept side to be + // fully completed before continuing: we are implicitly + // checking that RemoteEndPoint on the Accept socket + // matches LocalEndPoint on the Connect socket when + // checking the correctness of the ChannelOpenMessage + // in the mock. + _ = barrier.SignalAndWait(TimeSpan.FromSeconds(1)); _channel = new ChannelDirectTcpip(_sessionMock.Object, _localChannelNumber, _localWindowSize, @@ -156,6 +165,7 @@ private void Arrange() _client = new Socket(localEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _client.Connect(localEndpoint); + _ = barrier.SignalAndWait(TimeSpan.FromSeconds(1)); var clientReceiveThread = new Thread( () =>