From d830a7def2fae6d688cb23292bf70735aca2f059 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 4 Feb 2021 07:10:40 +0100 Subject: [PATCH] fix #47561 (#47575) --- .../tests/FunctionalTests/ReceiveFrom.cs | 49 +++++++++++++------ .../FunctionalTests/ReceiveMessageFrom.cs | 49 +++++++++++++------ 2 files changed, 66 insertions(+), 32 deletions(-) diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveFrom.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveFrom.cs index e686dd48f79d7..362f87a54ddab 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveFrom.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveFrom.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; +using Xunit.Sdk; namespace System.Net.Sockets.Tests { @@ -141,7 +142,6 @@ public async Task ClosedBeforeOperation_Throws_ObjectDisposedException(bool clos [Theory] [InlineData(true)] [InlineData(false)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/47561")] public async Task ClosedDuringOperation_Throws_ObjectDisposedExceptionOrSocketException(bool closeOrDispose) { if (UsesSync && PlatformDetection.IsOSX) @@ -151,25 +151,42 @@ public async Task ClosedDuringOperation_Throws_ObjectDisposedExceptionOrSocketEx return; } - using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - socket.BindToAnonymousPort(IPAddress.Any); - - Task receiveTask = ReceiveFromAsync(socket, new byte[1], GetGetDummyTestEndpoint()); - await Task.Delay(100); - if (closeOrDispose) socket.Close(); - else socket.Dispose(); - - if (UsesApm) + int msDelay = 100; + if (UsesSync) { - await Assert.ThrowsAsync(() => receiveTask) - .TimeoutAfter(CancellationTestTimeout); + // In sync case Dispose may happen before the operation is started, + // in that case we would see an ObjectDisposedException instead of a SocketException. + // We may need to try the run a couple of times to deal with the timing race. + await RetryHelper.ExecuteAsync(() => RunTestAsync(), maxAttempts: 10, retryWhen: e => e is XunitException); } else { - SocketException ex = await Assert.ThrowsAsync(() => receiveTask) - .TimeoutAfter(CancellationTestTimeout); - SocketError expectedError = UsesSync ? SocketError.Interrupted : SocketError.OperationAborted; - Assert.Equal(expectedError, ex.SocketErrorCode); + await RunTestAsync(); + } + + async Task RunTestAsync() + { + using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + socket.BindToAnonymousPort(IPAddress.Any); + + Task receiveTask = ReceiveFromAsync(socket, new byte[1], GetGetDummyTestEndpoint()); + await Task.Delay(msDelay); + msDelay *= 2; + if (closeOrDispose) socket.Close(); + else socket.Dispose(); + + if (DisposeDuringOperationResultsInDisposedException) + { + await Assert.ThrowsAsync(() => receiveTask) + .TimeoutAfter(CancellationTestTimeout); + } + else + { + SocketException ex = await Assert.ThrowsAsync(() => receiveTask) + .TimeoutAfter(CancellationTestTimeout); + SocketError expectedError = UsesSync ? SocketError.Interrupted : SocketError.OperationAborted; + Assert.Equal(expectedError, ex.SocketErrorCode); + } } } diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs index a9443803773d4..4985e93f78453 100644 --- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs +++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ReceiveMessageFrom.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; +using Xunit.Sdk; namespace System.Net.Sockets.Tests { @@ -110,7 +111,6 @@ public async Task ClosedBeforeOperation_Throws_ObjectDisposedException(bool clos [Theory] [InlineData(true)] [InlineData(false)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/47561")] public async Task ClosedDuringOperation_Throws_ObjectDisposedExceptionOrSocketException(bool closeOrDispose) { if (UsesSync && PlatformDetection.IsOSX) @@ -120,25 +120,42 @@ public async Task ClosedDuringOperation_Throws_ObjectDisposedExceptionOrSocketEx return; } - using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - socket.BindToAnonymousPort(IPAddress.Any); - - Task receiveTask = ReceiveMessageFromAsync(socket, new byte[1], GetGetDummyTestEndpoint()); - await Task.Delay(100); - if (closeOrDispose) socket.Close(); - else socket.Dispose(); - - if (UsesApm) + int msDelay = 100; + if (UsesSync) { - await Assert.ThrowsAsync(() => receiveTask) - .TimeoutAfter(CancellationTestTimeout); + // In sync case Dispose may happen before the operation is started, + // in that case we would see an ObjectDisposedException instead of a SocketException. + // We may need to try the run a couple of times to deal with the timing race. + await RetryHelper.ExecuteAsync(() => RunTestAsync(), maxAttempts: 10, retryWhen: e => e is XunitException); } else { - SocketException ex = await Assert.ThrowsAsync(() => receiveTask) - .TimeoutAfter(CancellationTestTimeout); - SocketError expectedError = UsesSync ? SocketError.Interrupted : SocketError.OperationAborted; - Assert.Equal(expectedError, ex.SocketErrorCode); + await RunTestAsync(); + } + + async Task RunTestAsync() + { + using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + socket.BindToAnonymousPort(IPAddress.Any); + + Task receiveTask = ReceiveMessageFromAsync(socket, new byte[1], GetGetDummyTestEndpoint()); + await Task.Delay(msDelay); + msDelay *= 2; + if (closeOrDispose) socket.Close(); + else socket.Dispose(); + + if (DisposeDuringOperationResultsInDisposedException) + { + await Assert.ThrowsAsync(() => receiveTask) + .TimeoutAfter(CancellationTestTimeout); + } + else + { + SocketException ex = await Assert.ThrowsAsync(() => receiveTask) + .TimeoutAfter(CancellationTestTimeout); + SocketError expectedError = UsesSync ? SocketError.Interrupted : SocketError.OperationAborted; + Assert.Equal(expectedError, ex.SocketErrorCode); + } } }