Add regression test for SafeSocketHandle getting collected (dotnet/corefx#38471)
authorStephen Toub <stoub@microsoft.com>
Wed, 12 Jun 2019 16:48:57 +0000 (12:48 -0400)
committerGitHub <noreply@github.com>
Wed, 12 Jun 2019 16:48:57 +0000 (12:48 -0400)
* Add regression test for SafeSocketHandle getting collected

* Uncomment ActiveIssue for Unix

Commit migrated from https://github.com/dotnet/corefx/commit/506700913df9cd22ea13c097cfb2834f8a15677e

src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.netcoreapp.cs [new file with mode: 0644]
src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj

index 4f6c623..d2b63cf 100644 (file)
@@ -8,7 +8,7 @@ using Xunit;
 
 namespace System.Net.Sockets.Tests
 {
-    public class DisposedSocket
+    public partial class DisposedSocket
     {
         private static readonly byte[] s_buffer = new byte[1];
         private static readonly IList<ArraySegment<byte>> s_buffers = new List<ArraySegment<byte>> { new ArraySegment<byte>(s_buffer) };
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.netcoreapp.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.netcoreapp.cs
new file mode 100644 (file)
index 0000000..24e39eb
--- /dev/null
@@ -0,0 +1,72 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace System.Net.Sockets.Tests
+{
+    public partial class DisposedSocket
+    {
+        [ActiveIssue(37044, TestPlatforms.AnyUnix)]
+        [Theory]
+        [InlineData(false)]
+        [InlineData(true)]
+        public async Task NonDisposedSocket_SafeHandlesCollected(bool clientAsync)
+        {
+            List<WeakReference> handles = await CreateHandlesAsync(clientAsync);
+            RetryHelper.Execute(() =>
+            {
+                GC.Collect();
+                Assert.Equal(0, handles.Count(h => h.IsAlive));
+            });
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        private static async Task<List<WeakReference>> CreateHandlesAsync(bool clientAsync)
+        {
+            var handles = new List<WeakReference>();
+
+            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            {
+                listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+                listener.Listen(int.MaxValue);
+
+                for (int i = 0; i < 100; i++)
+                {
+                    var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // do not dispose
+                    handles.Add(new WeakReference(client.SafeHandle));
+                    if (clientAsync)
+                    {
+                        await client.ConnectAsync(listener.LocalEndPoint);
+                    }
+                    else
+                    {
+                        client.Connect(listener.LocalEndPoint);
+                    }
+
+                    using (Socket server = listener.Accept())
+                    {
+                        if (clientAsync)
+                        {
+                            Task<int> receiveTask = client.ReceiveAsync(new ArraySegment<byte>(new byte[1]), SocketFlags.None);
+                            Assert.Equal(1, server.Send(new byte[1]));
+                            Assert.Equal(1, await receiveTask);
+                        }
+                        else
+                        {
+                            Assert.Equal(1, server.Send(new byte[1]));
+                            Assert.Equal(1, client.Receive(new byte[1]));
+                        }
+                    }
+                }
+            }
+
+            return handles;
+        }
+    }
+}
index 018f950..6eab7a3 100644 (file)
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <ProjectGuid>{8CBA022C-635F-4C8D-9D29-CD8AAC68C8E6}</ProjectGuid>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@@ -16,6 +16,7 @@
     <Compile Include="CreateSocketTests.cs" />
     <Compile Include="CreateSocketTests.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="DisposedSocketTests.cs" />
+    <Compile Include="DisposedSocketTests.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="DnsEndPointTest.cs" />
     <Compile Include="DualModeSocketTest.cs" />
     <Compile Include="ExecutionContextFlowTest.cs" />