diff --git a/src/Renci.SshNet.Tests/Classes/Connection/HttpConnectorTestBase.cs b/src/Renci.SshNet.Tests/Classes/Connection/HttpConnectorTestBase.cs index 661a45906..4e19bcb0c 100644 --- a/src/Renci.SshNet.Tests/Classes/Connection/HttpConnectorTestBase.cs +++ b/src/Renci.SshNet.Tests/Classes/Connection/HttpConnectorTestBase.cs @@ -26,6 +26,12 @@ protected virtual void SetupMocks() { } + protected override void AfterAct() + { + // Give some time to process all messages + Thread.Sleep(400); + } + protected sealed override void Arrange() { CreateMocks(); diff --git a/src/Renci.SshNet.Tests/Classes/Connection/HttpConnectorTest_Connect_ProxyUserNameIsNull.cs b/src/Renci.SshNet.Tests/Classes/Connection/HttpConnectorTest_Connect_ProxyUserNameIsNull.cs index c5d85b016..3de1bddb4 100644 --- a/src/Renci.SshNet.Tests/Classes/Connection/HttpConnectorTest_Connect_ProxyUserNameIsNull.cs +++ b/src/Renci.SshNet.Tests/Classes/Connection/HttpConnectorTest_Connect_ProxyUserNameIsNull.cs @@ -75,16 +75,16 @@ protected override void TearDown() { base.TearDown(); - if (_proxyServer != null) - { - _proxyServer.Dispose(); - } - if (_clientSocket != null) { _clientSocket.Shutdown(SocketShutdown.Send); _clientSocket.Close(); } + + if (_proxyServer != null) + { + _proxyServer.Dispose(); + } } protected override void Act() diff --git a/src/Renci.SshNet.Tests/Classes/Connection/Socks4ConnectorTestBase.cs b/src/Renci.SshNet.Tests/Classes/Connection/Socks4ConnectorTestBase.cs index 1b93ced3f..98b694006 100644 --- a/src/Renci.SshNet.Tests/Classes/Connection/Socks4ConnectorTestBase.cs +++ b/src/Renci.SshNet.Tests/Classes/Connection/Socks4ConnectorTestBase.cs @@ -34,6 +34,12 @@ protected sealed override void Arrange() SetupMocks(); } + protected override void AfterAct() + { + // Give some time to process all messages + Thread.Sleep(200); + } + protected ConnectionInfo CreateConnectionInfo(string proxyUser, string proxyPassword) { return new ConnectionInfo(IPAddress.Loopback.ToString(), diff --git a/src/Renci.SshNet.Tests/Classes/Connection/Socks5ConnectorTestBase.cs b/src/Renci.SshNet.Tests/Classes/Connection/Socks5ConnectorTestBase.cs index 9125fb34e..682a6fd75 100644 --- a/src/Renci.SshNet.Tests/Classes/Connection/Socks5ConnectorTestBase.cs +++ b/src/Renci.SshNet.Tests/Classes/Connection/Socks5ConnectorTestBase.cs @@ -36,6 +36,12 @@ protected sealed override void Arrange() SetupMocks(); } + protected override void AfterAct() + { + // Give some time to process all messages + Thread.Sleep(200); + } + protected ConnectionInfo CreateConnectionInfo(string proxyUser, string proxyPassword) { return new ConnectionInfo(IPAddress.Loopback.ToString(), diff --git a/src/Renci.SshNet.Tests/Common/AsyncSocketListener.cs b/src/Renci.SshNet.Tests/Common/AsyncSocketListener.cs index fe6d7736b..f3008eb87 100644 --- a/src/Renci.SshNet.Tests/Common/AsyncSocketListener.cs +++ b/src/Renci.SshNet.Tests/Common/AsyncSocketListener.cs @@ -65,10 +65,6 @@ public void Stop() { _started = false; - // Give some time to process all messages.The new .NET is faster, so the test establishes - // a connection with the server, events start to run and at the same time the test is finished. - _receiveThread.Join(400); - lock (_syncLock) { foreach (var connectedClient in _connectedClients) @@ -283,28 +279,7 @@ private void ReadCallback(IAsyncResult ar) return; } - if (bytesRead > 0) - { - var bytesReceived = new byte[bytesRead]; - Array.Copy(state.Buffer, bytesReceived, bytesRead); - SignalBytesReceived(bytesReceived, handler); - - try - { - handler.BeginReceive(state.Buffer, 0, state.Buffer.Length, 0, ReadCallback, state); - } - catch (SocketException ex) - { - if (!_started) - { - throw new Exception("BeginReceive while stopping!", ex); - } - - throw new Exception("BeginReceive while started!: " + ex.SocketErrorCode + " " + _stackTrace, ex); - } - - } - else + void ConnectionDisconnected() { SignalDisconnected(handler); @@ -322,6 +297,11 @@ private void ReadCallback(IAsyncResult ar) handler.Shutdown(SocketShutdown.Send); handler.Close(); } + catch (SocketException ex) when (ex.SocketErrorCode == SocketError.ConnectionReset) + { + // On .NET 7 we got Socker Exception with ConnectionReset from Shutdown method + // when the socket is disposed + } catch (SocketException ex) { throw new Exception("Exception in ReadCallback: " + ex.SocketErrorCode + " " + _stackTrace, ex); @@ -335,6 +315,37 @@ private void ReadCallback(IAsyncResult ar) } } } + + if (bytesRead > 0) + { + var bytesReceived = new byte[bytesRead]; + Array.Copy(state.Buffer, bytesReceived, bytesRead); + SignalBytesReceived(bytesReceived, handler); + + try + { + handler.BeginReceive(state.Buffer, 0, state.Buffer.Length, 0, ReadCallback, state); + } + catch (ObjectDisposedException ex) + { + // TODO On .NET 7, sometimes we get ObjectDisposedException when _started but only on appveyor, locally it works + ConnectionDisconnected(); + } + catch (SocketException ex) + { + if (!_started) + { + throw new Exception("BeginReceive while stopping!", ex); + } + + throw new Exception("BeginReceive while started!: " + ex.SocketErrorCode + " " + _stackTrace, ex); + } + + } + else + { + ConnectionDisconnected(); + } } private void SignalBytesReceived(byte[] bytesReceived, Socket client) diff --git a/src/Renci.SshNet.Tests/Common/TripleATestBase.cs b/src/Renci.SshNet.Tests/Common/TripleATestBase.cs index 8e8f60058..e7e79a442 100644 --- a/src/Renci.SshNet.Tests/Common/TripleATestBase.cs +++ b/src/Renci.SshNet.Tests/Common/TripleATestBase.cs @@ -9,6 +9,7 @@ public void Init() { Arrange(); Act(); + AfterAct(); } [TestCleanup] @@ -24,6 +25,10 @@ protected virtual void TearDown() protected abstract void Arrange(); protected abstract void Act(); + + protected virtual void AfterAct() + { + } } }