Consolidate .netcoreapp.cs test files in System.Net.* (#664)
authorRoman Marusyk <Marusyk@users.noreply.github.com>
Mon, 9 Dec 2019 13:48:49 +0000 (14:48 +0100)
committerDavid Shulman <david.shulman@microsoft.com>
Mon, 9 Dec 2019 13:48:49 +0000 (05:48 -0800)
* Consolidate .netcoreapp.cs files because System.Net.* projects is no longer cross-compiled

* Fix build

* Add end-of-line

43 files changed:
src/libraries/System.Net.Http/src/System.Net.Http.csproj
src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs
src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.netcoreapp.cs [deleted file]
src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.cs
src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.netcoreapp.cs [deleted file]
src/libraries/System.Net.Http/tests/FunctionalTests/HttpMethodTest.cs
src/libraries/System.Net.Http/tests/FunctionalTests/HttpMethodTest.netcoreapp.cs [deleted file]
src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj
src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieCollectionTest.cs
src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieCollectionTest.netcoreapp.cs [deleted file]
src/libraries/System.Net.Primitives/tests/FunctionalTests/System.Net.Primitives.Functional.Tests.csproj
src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.cs
src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.netcoreapp.cs [deleted file]
src/libraries/System.Net.Security/tests/FunctionalTests/System.Net.Security.Tests.csproj
src/libraries/System.Net.Sockets/tests/FunctionalTests/CreateSocketTests.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/CreateSocketTests.netcoreapp.cs [deleted file]
src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.netcoreapp.cs [deleted file]
src/libraries/System.Net.Sockets/tests/FunctionalTests/ExecutionContextFlowTest.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/ExecutionContextFlowTest.netcoreapp.cs [deleted file]
src/libraries/System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.cs [moved from src/libraries/System.Net.Sockets/tests/FunctionalTests/KeepAliveTest.netcoreapp.cs with 100% similarity]
src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.netcoreapp.cs [deleted file]
src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.netcoreapp.cs [deleted file]
src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsElementTest.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsElementTest.netcoreapp.cs [deleted file]
src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive.netcoreapp.cs [deleted file]
src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.netcoreapp.cs [deleted file]
src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.cs
src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.netcoreapp.cs [deleted file]
src/libraries/System.Net.Sockets/tests/FunctionalTests/System.Net.Sockets.Tests.csproj
src/libraries/System.Net.Sockets/tests/FunctionalTests/UnixDomainSocketTest.cs [moved from src/libraries/System.Net.Sockets/tests/FunctionalTests/UnixDomainSocketTest.netcoreapp.cs with 99% similarity]
src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketOptionsTests.cs
src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketOptionsTests.netcoreapp.cs [deleted file]
src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.cs
src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.netcoreapp.cs [deleted file]
src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj
src/libraries/System.Net.WebSockets/tests/System.Net.WebSockets.Tests.csproj
src/libraries/System.Net.WebSockets/tests/WebSocketTests.cs
src/libraries/System.Net.WebSockets/tests/WebSocketTests.netcoreapp.cs [deleted file]

index 1575a92..72302df 100644 (file)
@@ -25,7 +25,6 @@
     <Compile Include="System\Net\Http\HttpClient.cs" />
     <Compile Include="System\Net\Http\HttpClientHandler.cs" />
     <Compile Include="System\Net\Http\HttpClientHandler.Core.cs" />
-    <Compile Include="System\Net\Http\HttpClientHandler.netcoreapp.cs" />
     <Compile Include="System\Net\Http\HttpCompletionOption.cs" />
     <Compile Include="System\Net\Http\HttpContent.cs" />
     <Compile Include="System\Net\Http\HttpMessageHandler.cs" />
index 11e459e..280b506 100644 (file)
@@ -2,7 +2,6 @@
 // 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.Diagnostics;
 using System.Net.Security;
 using System.Collections.Generic;
 using System.Security.Authentication;
@@ -222,6 +221,14 @@ namespace System.Net.Http
                 _diagnosticsHandler.SendAsync(request, cancellationToken) :
                 _socketsHttpHandler.SendAsync(request, cancellationToken);
         }
+
         public static Func<HttpRequestMessage, X509Certificate2, X509Chain, SslPolicyErrors, bool> DangerousAcceptAnyServerCertificateValidator { get; } = delegate { return true; };
+
+        private void ThrowForModifiedManagedSslOptionsIfStarted()
+        {
+            // Hack to trigger an InvalidOperationException if a property that's stored on
+            // SslOptions is changed, since SslOptions itself does not do any such checks.
+            _socketsHttpHandler.SslOptions = _socketsHttpHandler.SslOptions;
+        }
     }
 }
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.netcoreapp.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.netcoreapp.cs
deleted file mode 100644 (file)
index 8296f91..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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.Net.Security;
-using System.Security.Authentication;
-using System.Security.Cryptography.X509Certificates;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace System.Net.Http
-{
-    // This partial implementation contains members common to NetCoreApp
-    public partial class HttpClientHandler : HttpMessageHandler
-    {
-        private void ThrowForModifiedManagedSslOptionsIfStarted()
-        {
-            // Hack to trigger an InvalidOperationException if a property that's stored on
-            // SslOptions is changed, since SslOptions itself does not do any such checks.
-            _socketsHttpHandler.SslOptions = _socketsHttpHandler.SslOptions;
-        }
-    }
-}
index d2cf4b3..b6ee608 100644 (file)
@@ -2,6 +2,7 @@
 // The .NET Foundation licenses this file to you under the MIT license.
 // See the LICENSE file in the project root for more information.
 
+using Microsoft.DotNet.RemoteExecutor;
 using System.IO;
 using System.Linq;
 using System.Threading;
@@ -11,7 +12,7 @@ using Xunit;
 
 namespace System.Net.Http.Functional.Tests
 {
-    public sealed partial class HttpClientTest
+    public sealed class HttpClientTest
     {
         [Fact]
         public void Dispose_MultipleTimes_Success()
@@ -410,6 +411,161 @@ namespace System.Net.Http.Functional.Tests
             }
         }
 
+        [Fact]
+        public void DefaultProxy_SetNull_Throws()
+        {
+            Assert.Throws<ArgumentNullException>(() => HttpClient.DefaultProxy = null );
+        }
+
+        [Fact]
+        public void DefaultProxy_Get_ReturnsNotNull()
+        {
+            IWebProxy proxy = HttpClient.DefaultProxy;
+            Assert.NotNull(proxy);
+        }
+
+        [Fact]
+        public void DefaultProxy_SetGet_Roundtrips()
+        {
+            RemoteExecutor.Invoke(() =>
+            {
+                IWebProxy proxy = new WebProxy("http://localhost:3128/");
+                HttpClient.DefaultProxy = proxy;
+                Assert.True(Object.ReferenceEquals(proxy, HttpClient.DefaultProxy));
+            }).Dispose();
+        }
+
+        [Fact]
+        public void DefaultProxy_Credentials_SetGet_Roundtrips()
+        {
+            RemoteExecutor.Invoke(() =>
+            {
+                IWebProxy proxy = HttpClient.DefaultProxy;
+                ICredentials nc = proxy.Credentials;
+
+                proxy.Credentials = null;
+                Assert.Null(proxy.Credentials);
+
+                proxy.Credentials = nc;
+                Assert.Same(nc, proxy.Credentials);
+
+                return RemoteExecutor.SuccessExitCode;
+            }).Dispose();
+        }
+
+        [Fact]
+        public async Task PatchAsync_Canceled_Throws()
+        {
+            using (var client = new HttpClient(new CustomResponseHandler((r, c) => WhenCanceled<HttpResponseMessage>(c))))
+            {
+                var content = new ByteArrayContent(new byte[1]);
+                var cts = new CancellationTokenSource();
+
+                Task t1 = client.PatchAsync(CreateFakeUri(), content, cts.Token);
+
+                cts.Cancel();
+
+                await Assert.ThrowsAsync<TaskCanceledException>(() => t1);
+            }
+        }
+
+        [Fact]
+        public async Task PatchAsync_Success()
+        {
+            static void Verify(HttpResponseMessage message)
+            {
+                using (message)
+                {
+                    Assert.Equal(HttpStatusCode.OK, message.StatusCode);
+                }
+            }
+
+            using (var client = new HttpClient(new CustomResponseHandler((r, c) => Task.FromResult(new HttpResponseMessage()))))
+            {
+                Verify(await client.PatchAsync(CreateFakeUri(), new ByteArrayContent(new byte[1])));
+                Verify(await client.PatchAsync(CreateFakeUri(), new ByteArrayContent(new byte[1]), CancellationToken.None));
+            }
+        }
+
+        [Fact]
+        public void Dispose_UsePatchAfterDispose_Throws()
+        {
+            var client = new HttpClient(new CustomResponseHandler((r, c) => Task.FromResult(new HttpResponseMessage())));
+            client.Dispose();
+
+            Assert.Throws<ObjectDisposedException>(() => { client.PatchAsync(CreateFakeUri(), new ByteArrayContent(new byte[1])); });
+        }
+
+        [Fact]
+        public void DefaultRequestVersion_InitialValueExpected()
+        {
+            using (var client = new HttpClient())
+            {
+                Assert.Equal(HttpVersion.Version11, client.DefaultRequestVersion);
+                Assert.Same(client.DefaultRequestVersion, client.DefaultRequestVersion);
+            }
+        }
+
+        [Fact]
+        public void DefaultRequestVersion_Roundtrips()
+        {
+            using (var client = new HttpClient())
+            {
+                for (int i = 3; i < 5; i++)
+                {
+                    var newVersion = new Version(i, i, i, i);
+                    client.DefaultRequestVersion = newVersion;
+                    Assert.Same(newVersion, client.DefaultRequestVersion);
+                }
+            }
+        }
+
+        [Fact]
+        public void DefaultRequestVersion_InvalidArgument_Throws()
+        {
+            using (var client = new HttpClient())
+            {
+                AssertExtensions.Throws<ArgumentNullException>("value", () => client.DefaultRequestVersion = null);
+                client.DefaultRequestVersion = new Version(1, 0); // still usable after
+                Assert.Equal(new Version(1, 0), client.DefaultRequestVersion);
+            }
+        }
+
+        [Fact]
+        public async Task DefaultRequestVersion_SetAfterUse_Throws()
+        {
+            var handler = new StoreMessageHttpMessageInvoker();
+            using (var client = new HttpClient(handler))
+            {
+                await client.GetAsync("http://doesntmatter", HttpCompletionOption.ResponseHeadersRead);
+                Assert.Throws<InvalidOperationException>(() => client.DefaultRequestVersion = new Version(1, 1));
+            }
+        }
+
+        [Fact]
+        public async Task DefaultRequestVersion_UsedInCreatedMessages()
+        {
+            var handler = new StoreMessageHttpMessageInvoker();
+            using (var client = new HttpClient(handler))
+            {
+                var version = new Version(1, 2, 3, 4);
+                client.DefaultRequestVersion = version;
+                await client.GetAsync("http://doesntmatter", HttpCompletionOption.ResponseHeadersRead);
+                Assert.Same(version, handler.Message.Version);
+            }
+        }
+
+        private sealed class StoreMessageHttpMessageInvoker : HttpMessageHandler
+        {
+            public HttpRequestMessage Message;
+
+            protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
+            {
+                Message = request;
+                return Task.FromResult(new HttpResponseMessage());
+            }
+        }
+
         private static string CreateFakeUri() => $"http://{Guid.NewGuid().ToString("N")}";
 
         private static async Task<T> WhenCanceled<T>(CancellationToken cancellationToken)
diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.netcoreapp.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientTest.netcoreapp.cs
deleted file mode 100644 (file)
index 19b0e05..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-// 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.Threading;
-using System.Threading.Tasks;
-using Microsoft.DotNet.RemoteExecutor;
-using Xunit;
-
-namespace System.Net.Http.Functional.Tests
-{
-    public sealed partial class HttpClientTest
-    {
-        [Fact]
-        public void DefaultProxy_SetNull_Throws()
-        {
-            Assert.Throws<ArgumentNullException>(() => HttpClient.DefaultProxy = null );
-        }
-
-        [Fact]
-        public void DefaultProxy_Get_ReturnsNotNull()
-        {
-            IWebProxy proxy = HttpClient.DefaultProxy;
-            Assert.NotNull(proxy);
-        }
-
-        [Fact]
-        public void DefaultProxy_SetGet_Roundtrips()
-        {
-            RemoteExecutor.Invoke(() =>
-            {
-                IWebProxy proxy = new WebProxy("http://localhost:3128/");
-                HttpClient.DefaultProxy = proxy;
-                Assert.True(Object.ReferenceEquals(proxy, HttpClient.DefaultProxy));
-            }).Dispose();
-        }
-
-        [Fact]
-        public void DefaultProxy_Credentials_SetGet_Roundtrips()
-        {
-            RemoteExecutor.Invoke(() =>
-            {
-                IWebProxy proxy = HttpClient.DefaultProxy;
-                ICredentials nc = proxy.Credentials;
-
-                proxy.Credentials = null;
-                Assert.Null(proxy.Credentials);
-
-                proxy.Credentials = nc;
-                Assert.Same(nc, proxy.Credentials);
-
-                return RemoteExecutor.SuccessExitCode;
-            }).Dispose();
-        }
-
-        [Fact]
-        public async Task PatchAsync_Canceled_Throws()
-        {
-            using (var client = new HttpClient(new CustomResponseHandler((r, c) => WhenCanceled<HttpResponseMessage>(c))))
-            {
-                var content = new ByteArrayContent(new byte[1]);
-                var cts = new CancellationTokenSource();
-
-                Task t1 = client.PatchAsync(CreateFakeUri(), content, cts.Token);
-
-                cts.Cancel();
-
-                await Assert.ThrowsAsync<TaskCanceledException>(() => t1);
-            }
-        }
-
-        [Fact]
-        public async Task PatchAsync_Success()
-        {
-            static void Verify(HttpResponseMessage message)
-            {
-                using (message)
-                {
-                    Assert.Equal(HttpStatusCode.OK, message.StatusCode);
-                }
-            }
-
-            using (var client = new HttpClient(new CustomResponseHandler((r, c) => Task.FromResult(new HttpResponseMessage()))))
-            {
-                Verify(await client.PatchAsync(CreateFakeUri(), new ByteArrayContent(new byte[1])));
-                Verify(await client.PatchAsync(CreateFakeUri(), new ByteArrayContent(new byte[1]), CancellationToken.None));
-            }
-        }
-
-        [Fact]
-        public void Dispose_UsePatchAfterDispose_Throws()
-        {
-            var client = new HttpClient(new CustomResponseHandler((r, c) => Task.FromResult(new HttpResponseMessage())));
-            client.Dispose();
-
-            Assert.Throws<ObjectDisposedException>(() => { client.PatchAsync(CreateFakeUri(), new ByteArrayContent(new byte[1])); });
-        }
-
-        [Fact]
-        public void DefaultRequestVersion_InitialValueExpected()
-        {
-            using (var client = new HttpClient())
-            {
-                Assert.Equal(HttpVersion.Version11, client.DefaultRequestVersion);
-                Assert.Same(client.DefaultRequestVersion, client.DefaultRequestVersion);
-            }
-        }
-
-        [Fact]
-        public void DefaultRequestVersion_Roundtrips()
-        {
-            using (var client = new HttpClient())
-            {
-                for (int i = 3; i < 5; i++)
-                {
-                    var newVersion = new Version(i, i, i, i);
-                    client.DefaultRequestVersion = newVersion;
-                    Assert.Same(newVersion, client.DefaultRequestVersion);
-                }
-            }
-        }
-
-        [Fact]
-        public void DefaultRequestVersion_InvalidArgument_Throws()
-        {
-            using (var client = new HttpClient())
-            {
-                AssertExtensions.Throws<ArgumentNullException>("value", () => client.DefaultRequestVersion = null);
-                client.DefaultRequestVersion = new Version(1, 0); // still usable after
-                Assert.Equal(new Version(1, 0), client.DefaultRequestVersion);
-            }
-        }
-
-        [Fact]
-        public async Task DefaultRequestVersion_SetAfterUse_Throws()
-        {
-            var handler = new StoreMessageHttpMessageInvoker();
-            using (var client = new HttpClient(handler))
-            {
-                await client.GetAsync("http://doesntmatter", HttpCompletionOption.ResponseHeadersRead);
-                Assert.Throws<InvalidOperationException>(() => client.DefaultRequestVersion = new Version(1, 1));
-            }
-        }
-
-        [Fact]
-        public async Task DefaultRequestVersion_UsedInCreatedMessages()
-        {
-            var handler = new StoreMessageHttpMessageInvoker();
-            using (var client = new HttpClient(handler))
-            {
-                var version = new Version(1, 2, 3, 4);
-                client.DefaultRequestVersion = version;
-                await client.GetAsync("http://doesntmatter", HttpCompletionOption.ResponseHeadersRead);
-                Assert.Same(version, handler.Message.Version);
-            }
-        }
-
-        private sealed class StoreMessageHttpMessageInvoker : HttpMessageHandler
-        {
-            public HttpRequestMessage Message;
-
-            protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
-            {
-                Message = request;
-                return Task.FromResult(new HttpResponseMessage());
-            }
-        }
-    }
-}
index 9a1df63..4feb773 100644 (file)
@@ -2,16 +2,13 @@
 // 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;
 using System.Collections.Generic;
-using System.Net;
-using System.Net.Http;
 
 using Xunit;
 
 namespace System.Net.Http.Functional.Tests
 {
-    public partial class HttpMethodTest
+    public class HttpMethodTest
     {
         public static IEnumerable<object[]> StaticHttpMethods { get;  }
 
@@ -31,8 +28,6 @@ namespace System.Net.Http.Functional.Tests
             StaticHttpMethods = staticHttpMethods;
         }
 
-        static partial void AddStaticHttpMethods(List<object[]> staticHttpMethods);
-
         [Fact]
         public void StaticProperties_VerifyValues_PropertyNameMatchesHttpMethodName()
         {
@@ -149,5 +144,16 @@ namespace System.Net.Http.Functional.Tests
             HttpMethod method = new HttpMethod("custom");
             Assert.Equal("custom", method.Method);
         }
+
+        [Fact]
+        public void Patch_VerifyValue_PropertyNameMatchesHttpMethodName()
+        {
+            Assert.Equal("PATCH", HttpMethod.Patch.Method);
+        }
+
+        private static void AddStaticHttpMethods(List<object[]> staticHttpMethods)
+        {
+            staticHttpMethods.Add(new object[] { HttpMethod.Patch });
+        }
     }
 }
diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpMethodTest.netcoreapp.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpMethodTest.netcoreapp.cs
deleted file mode 100644 (file)
index 3d9324b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// 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 Xunit;
-
-namespace System.Net.Http.Functional.Tests
-{
-    public partial class HttpMethodTest
-    {
-        [Fact]
-        public void Patch_VerifyValue_PropertyNameMatchesHttpMethodName()
-        {
-            Assert.Equal("PATCH", HttpMethod.Patch.Method);
-        }
-
-        static partial void AddStaticHttpMethods(List<object[]> staticHttpMethods)
-        {
-            staticHttpMethods.Add(new object[] { HttpMethod.Patch });
-        }
-    }
-}
index b5a374c..5c97da2 100644 (file)
   <ItemGroup>
     <Compile Include="CustomContent.netcore.cs" />
     <Compile Include="HPackTest.cs" />
-    <Compile Include="HttpClientTest.netcoreapp.cs" />
     <Compile Include="HttpClientHandlerTest.Http1.cs" />
     <Compile Include="HttpClientHandlerTest.Http2.cs" />
     <Compile Include="HttpClientHandlerTest.AcceptAllCerts.cs" />
     <Compile Include="HttpClientHandlerTest.Decompression.cs" />
     <Compile Include="HttpClientMiniStressTest.cs" />
-    <Compile Include="HttpMethodTest.netcoreapp.cs" />
     <Compile Include="NtAuthTests.cs" />
     <Compile Include="ReadOnlyMemoryContentTest.cs" />
     <Compile Include="SocketsHttpHandlerTest.cs" />
index a3c089c..5b6b34c 100644 (file)
@@ -8,7 +8,7 @@ using Xunit;
 
 namespace System.Net.Primitives.Functional.Tests
 {
-    public static partial class CookieCollectionTest
+    public static class CookieCollectionTest
     {
         //These cookies are designed to have some similar and different properties so that each is unique in the eyes of a CookieComparer object
         private static Cookie c1 = new Cookie("name1", "value");
@@ -169,5 +169,50 @@ namespace System.Net.Primitives.Functional.Tests
 
             Assert.Throws<InvalidOperationException>(() => enumerator.MoveNext()); // Enumerator out of sync
         }
+
+        [Fact]
+        public static void Clear_Success()
+        {
+            ICollection<Cookie> cc = CreateCookieCollection1();
+            Assert.InRange(cc.Count, 1, int.MaxValue);
+            cc.Clear();
+            Assert.Equal(0, cc.Count);
+        }
+
+        [Fact]
+        public static void Contains_Success()
+        {
+            ICollection<Cookie> cc = new CookieCollection();
+            cc.Add(c1);
+            Assert.True(cc.Contains(c1));
+            Assert.False(cc.Contains(c2));
+        }
+
+        [Fact]
+        public static void Remove_Success()
+        {
+            ICollection<Cookie> cc = CreateCookieCollection1();
+            Assert.Equal(5, cc.Count);
+            Assert.True(cc.Remove(c1));
+            Assert.False(cc.Contains(c1));
+            Assert.Equal(4, cc.Count);
+        }
+
+        [Fact]
+        public static void Remove_NonExistantCookie_ReturnsFalse()
+        {
+            ICollection<Cookie> cc = CreateCookieCollection1();
+            Assert.Equal(5, cc.Count);
+
+            cc.Remove(c1);
+            cc.Remove(c2);
+
+            Assert.Equal(3, cc.Count);
+
+            Assert.False(cc.Remove(c1));
+            Assert.False(cc.Remove(c2));
+
+            Assert.Equal(3, cc.Count);
+        }
     }
 }
diff --git a/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieCollectionTest.netcoreapp.cs b/src/libraries/System.Net.Primitives/tests/FunctionalTests/CookieCollectionTest.netcoreapp.cs
deleted file mode 100644 (file)
index d732fba..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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;
-using System.Collections.Generic;
-using Xunit;
-
-namespace System.Net.Primitives.Functional.Tests
-{
-    public static partial class CookieCollectionTest
-    {
-        [Fact]
-        public static void Clear_Success()
-        {
-            ICollection<Cookie> cc = CreateCookieCollection1();
-            Assert.InRange(cc.Count, 1, int.MaxValue);
-            cc.Clear();
-            Assert.Equal(0, cc.Count);
-        }
-
-        [Fact]
-        public static void Contains_Success()
-        {
-            ICollection<Cookie> cc = new CookieCollection();
-            cc.Add(c1);
-            Assert.True(cc.Contains(c1));
-            Assert.False(cc.Contains(c2));
-        }
-
-        [Fact]
-        public static void Remove_Success()
-        {
-            ICollection<Cookie> cc = CreateCookieCollection1();
-            Assert.Equal(5, cc.Count);
-            Assert.True(cc.Remove(c1));
-            Assert.False(cc.Contains(c1));
-            Assert.Equal(4, cc.Count);
-        }
-
-        [Fact]
-        public static void Remove_NonExistantCookie_ReturnsFalse()
-        {
-            ICollection<Cookie> cc = CreateCookieCollection1();
-            Assert.Equal(5, cc.Count);
-
-            cc.Remove(c1);
-            cc.Remove(c2);
-
-            Assert.Equal(3, cc.Count);
-
-            Assert.False(cc.Remove(c1));
-            Assert.False(cc.Remove(c2));
-
-            Assert.Equal(3, cc.Count);
-        }
-    }
-}
index 9e1091b..c9203bb 100644 (file)
     <Compile Include="CredentialCacheTest.cs" />
     <Compile Include="DnsEndPointTest.cs" />
     <Compile Include="EndPointTest.cs" />
+    <Compile Include="IPAddressMappingTest.cs" />
     <Compile Include="IPAddressParsing.cs" />
+    <Compile Include="IPAddressParsingSpan.cs" />
+    <Compile Include="IPAddressSpanTest.cs" />
     <Compile Include="IPAddressTest.cs" />
-    <Compile Include="IPAddressMappingTest.cs" />
+    <Compile Include="IPEndPointParsing.cs" />
     <Compile Include="IPEndPointTest.cs" />
     <Compile Include="NetworkCredentialTest.cs" />
     <Compile Include="SocketAddressTest.cs" />
       <Link>Common\System\Diagnostics\Tracing\TestEventListener.cs</Link>
     </Compile>
   </ItemGroup>
-  <ItemGroup Condition="'$(TargetGroup)' == 'netcoreapp'">
-    <Compile Include="CookieCollectionTest.netcoreapp.cs" />
-    <Compile Include="IPAddressSpanTest.cs" />
-    <Compile Include="IPAddressParsingSpan.cs" />
-    <Compile Include="IPEndPointParsing.cs" />
-  </ItemGroup>
   <ItemGroup>
     <Reference Include="System.Memory" />
   </ItemGroup>
index 0e36c49..dfee6bc 100644 (file)
@@ -5,6 +5,7 @@
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Net.Sockets;
 using System.Net.Test.Common;
 using System.Security.Authentication;
 using System.Security.Cryptography.X509Certificates;
@@ -868,4 +869,113 @@ namespace System.Net.Security.Tests
             }
         }
     }
+
+    public sealed class SslStreamStreamToStreamTest_MemoryAsync : SslStreamStreamToStreamTest_CancelableReadWriteAsync
+    {
+        protected override async Task DoHandshake(SslStream clientSslStream, SslStream serverSslStream, X509Certificate serverCertificate = null, X509Certificate clientCertificate = null)
+        {
+            X509CertificateCollection clientCerts = clientCertificate != null ? new X509CertificateCollection() { clientCertificate } : null;
+            await WithServerCertificate(serverCertificate, async(certificate, name) =>
+            {
+                Task t1 = clientSslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions() { TargetHost = name, ClientCertificates = clientCerts }, CancellationToken.None);
+                Task t2 = serverSslStream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions() { ServerCertificate = certificate, ClientCertificateRequired = clientCertificate != null }, CancellationToken.None);
+                await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);
+            });
+        }
+
+        protected override Task<int> ReadAsync(Stream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
+            stream.ReadAsync(new Memory<byte>(buffer, offset, count), cancellationToken).AsTask();
+
+        protected override Task WriteAsync(Stream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
+            stream.WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), cancellationToken).AsTask();
+
+        [Fact]
+        public async Task Authenticate_Precanceled_ThrowsOperationCanceledException()
+        {
+            var network = new VirtualNetwork();
+            using (var clientSslStream = new SslStream(new VirtualNetworkStream(network, isServer: false), false, AllowAnyServerCertificate))
+            using (var serverSslStream = new SslStream(new VirtualNetworkStream(network, isServer: true)))
+            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
+            {
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => clientSslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions() { TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false) }, new CancellationToken(true)));
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => serverSslStream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions() { ServerCertificate = certificate }, new CancellationToken(true)));
+            }
+        }
+
+        [Fact]
+        public async Task AuthenticateAsClientAsync_VirtualNetwork_CanceledAfterStart_ThrowsOperationCanceledException()
+        {
+            var network = new VirtualNetwork();
+            using (var clientSslStream = new SslStream(new VirtualNetworkStream(network, isServer: false), false, AllowAnyServerCertificate))
+            using (var serverSslStream = new SslStream(new VirtualNetworkStream(network, isServer: true)))
+            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
+            {
+                var cts = new CancellationTokenSource();
+                Task t = clientSslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions() { TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false) }, cts.Token);
+                cts.Cancel();
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
+            }
+        }
+
+        [Fact]
+        public async Task AuthenticateAsClientAsync_Sockets_CanceledAfterStart_ThrowsOperationCanceledException()
+        {
+            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            {
+                listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+                listener.Listen(1);
+
+                await client.ConnectAsync(listener.LocalEndPoint);
+                using (Socket server = await listener.AcceptAsync())
+                using (var clientSslStream = new SslStream(new NetworkStream(client), false, AllowAnyServerCertificate))
+                using (var serverSslStream = new SslStream(new NetworkStream(server)))
+                using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
+                {
+                    var cts = new CancellationTokenSource();
+                    Task t = clientSslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions() { TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false) }, cts.Token);
+                    cts.Cancel();
+                    await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
+                }
+            }
+        }
+
+        [Fact]
+        public async Task AuthenticateAsServerAsync_VirtualNetwork_CanceledAfterStart_ThrowsOperationCanceledException()
+        {
+            var network = new VirtualNetwork();
+            using (var clientSslStream = new SslStream(new VirtualNetworkStream(network, isServer: false), false, AllowAnyServerCertificate))
+            using (var serverSslStream = new SslStream(new VirtualNetworkStream(network, isServer: true)))
+            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
+            {
+                var cts = new CancellationTokenSource();
+                Task t = serverSslStream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions() { ServerCertificate = certificate }, cts.Token);
+                cts.Cancel();
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
+            }
+        }
+
+        [Fact]
+        public async Task AuthenticateAsServerAsync_Sockets_CanceledAfterStart_ThrowsOperationCanceledException()
+        {
+            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            {
+                listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+                listener.Listen(1);
+
+                await client.ConnectAsync(listener.LocalEndPoint);
+                using (Socket server = await listener.AcceptAsync())
+                using (var clientSslStream = new SslStream(new NetworkStream(client), false, AllowAnyServerCertificate))
+                using (var serverSslStream = new SslStream(new NetworkStream(server)))
+                using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
+                {
+                    var cts = new CancellationTokenSource();
+                    Task t = serverSslStream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions() { ServerCertificate = certificate }, cts.Token);
+                    cts.Cancel();
+                    await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
+                }
+            }
+        }
+    }
 }
diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.netcoreapp.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamStreamToStreamTest.netcoreapp.cs
deleted file mode 100644 (file)
index 1103a91..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-// 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.IO;
-using System.Net.Sockets;
-using System.Net.Test.Common;
-using System.Security.Cryptography.X509Certificates;
-using System.Threading;
-using System.Threading.Tasks;
-using Xunit;
-
-namespace System.Net.Security.Tests
-{
-    using Configuration = System.Net.Test.Common.Configuration;
-
-    public sealed class SslStreamStreamToStreamTest_MemoryAsync : SslStreamStreamToStreamTest_CancelableReadWriteAsync
-    {
-        protected override async Task DoHandshake(SslStream clientSslStream, SslStream serverSslStream, X509Certificate serverCertificate = null, X509Certificate clientCertificate = null)
-        {
-            X509CertificateCollection clientCerts = clientCertificate != null ? new X509CertificateCollection() { clientCertificate } : null;
-            await WithServerCertificate(serverCertificate, async(certificate, name) =>
-            {
-                Task t1 = clientSslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions() { TargetHost = name, ClientCertificates = clientCerts }, CancellationToken.None);
-                Task t2 = serverSslStream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions() { ServerCertificate = certificate, ClientCertificateRequired = clientCertificate != null }, CancellationToken.None);
-                await TestConfiguration.WhenAllOrAnyFailedWithTimeout(t1, t2);
-            });
-        }
-
-        protected override Task<int> ReadAsync(Stream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
-            stream.ReadAsync(new Memory<byte>(buffer, offset, count), cancellationToken).AsTask();
-
-        protected override Task WriteAsync(Stream stream, byte[] buffer, int offset, int count, CancellationToken cancellationToken) =>
-            stream.WriteAsync(new ReadOnlyMemory<byte>(buffer, offset, count), cancellationToken).AsTask();
-
-        [Fact]
-        public async Task Authenticate_Precanceled_ThrowsOperationCanceledException()
-        {
-            var network = new VirtualNetwork();
-            using (var clientSslStream = new SslStream(new VirtualNetworkStream(network, isServer: false), false, AllowAnyServerCertificate))
-            using (var serverSslStream = new SslStream(new VirtualNetworkStream(network, isServer: true)))
-            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
-            {
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => clientSslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions() { TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false) }, new CancellationToken(true)));
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => serverSslStream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions() { ServerCertificate = certificate }, new CancellationToken(true)));
-            }
-        }
-
-        [Fact]
-        public async Task AuthenticateAsClientAsync_VirtualNetwork_CanceledAfterStart_ThrowsOperationCanceledException()
-        {
-            var network = new VirtualNetwork();
-            using (var clientSslStream = new SslStream(new VirtualNetworkStream(network, isServer: false), false, AllowAnyServerCertificate))
-            using (var serverSslStream = new SslStream(new VirtualNetworkStream(network, isServer: true)))
-            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
-            {
-                var cts = new CancellationTokenSource();
-                Task t = clientSslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions() { TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false) }, cts.Token);
-                cts.Cancel();
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
-            }
-        }
-
-        [Fact]
-        public async Task AuthenticateAsClientAsync_Sockets_CanceledAfterStart_ThrowsOperationCanceledException()
-        {
-            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            {
-                listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
-                listener.Listen(1);
-
-                await client.ConnectAsync(listener.LocalEndPoint);
-                using (Socket server = await listener.AcceptAsync())
-                using (var clientSslStream = new SslStream(new NetworkStream(client), false, AllowAnyServerCertificate))
-                using (var serverSslStream = new SslStream(new NetworkStream(server)))
-                using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
-                {
-                    var cts = new CancellationTokenSource();
-                    Task t = clientSslStream.AuthenticateAsClientAsync(new SslClientAuthenticationOptions() { TargetHost = certificate.GetNameInfo(X509NameType.SimpleName, false) }, cts.Token);
-                    cts.Cancel();
-                    await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
-                }
-            }
-        }
-
-        [Fact]
-        public async Task AuthenticateAsServerAsync_VirtualNetwork_CanceledAfterStart_ThrowsOperationCanceledException()
-        {
-            var network = new VirtualNetwork();
-            using (var clientSslStream = new SslStream(new VirtualNetworkStream(network, isServer: false), false, AllowAnyServerCertificate))
-            using (var serverSslStream = new SslStream(new VirtualNetworkStream(network, isServer: true)))
-            using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
-            {
-                var cts = new CancellationTokenSource();
-                Task t = serverSslStream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions() { ServerCertificate = certificate }, cts.Token);
-                cts.Cancel();
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
-            }
-        }
-
-        [Fact]
-        public async Task AuthenticateAsServerAsync_Sockets_CanceledAfterStart_ThrowsOperationCanceledException()
-        {
-            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            {
-                listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
-                listener.Listen(1);
-
-                await client.ConnectAsync(listener.LocalEndPoint);
-                using (Socket server = await listener.AcceptAsync())
-                using (var clientSslStream = new SslStream(new NetworkStream(client), false, AllowAnyServerCertificate))
-                using (var serverSslStream = new SslStream(new NetworkStream(server)))
-                using (X509Certificate2 certificate = Configuration.Certificates.GetServerCertificate())
-                {
-                    var cts = new CancellationTokenSource();
-                    Task t = serverSslStream.AuthenticateAsServerAsync(new SslServerAuthenticationOptions() { ServerCertificate = certificate }, cts.Token);
-                    cts.Cancel();
-                    await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
-                }
-            }
-        }
-    }
-}
index 39a286f..5bb33e4 100644 (file)
@@ -98,7 +98,6 @@
         <Compile Include="SslStreamSchSendAuxRecordTest.cs" />
         <Compile Include="SslStreamCredentialCacheTest.cs" />
         <Compile Include="SslStreamSystemDefaultsTest.cs" />
-        <Compile Include="SslStreamStreamToStreamTest.netcoreapp.cs" />
       </ItemGroup>
       <ItemGroup>
         <Compile Include="LoggingTest.cs" />
index d41f309..194ea1a 100644 (file)
@@ -2,7 +2,6 @@
 // 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.Diagnostics;
 using System.IO;
 using System.IO.Pipes;
 using System.Threading.Tasks;
@@ -11,7 +10,7 @@ using Xunit;
 
 namespace System.Net.Sockets.Tests
 {
-    public partial class CreateSocket
+    public class CreateSocket
     {
         public static object[][] DualModeSuccessInputs = {
             new object[] { SocketType.Stream, ProtocolType.Tcp },
@@ -198,5 +197,36 @@ namespace System.Net.Sockets.Tests
                 }
             }, validateClientOuter.ToString(), acceptApiOuter.ToString()).Dispose();
         }
+
+        [Theory]
+        [InlineData(AddressFamily.Packet)]
+        [InlineData(AddressFamily.ControllerAreaNetwork)]
+        [PlatformSpecific(~TestPlatforms.Linux)]
+        public void Ctor_Netcoreapp_Throws(AddressFamily addressFamily)
+        {
+            // All protocols are Linux specific and throw on other platforms
+            Assert.Throws<SocketException>(() => new Socket(addressFamily, SocketType.Raw, 0));
+        }
+
+        [Theory]
+        [InlineData(AddressFamily.Packet)]
+        [InlineData(AddressFamily.ControllerAreaNetwork)]
+        [PlatformSpecific(TestPlatforms.Linux)]
+        public void Ctor_Netcoreapp_Success(AddressFamily addressFamily)
+        {
+            Socket s = null;
+            try
+            {
+                s = new Socket(addressFamily, SocketType.Raw, ProtocolType.Raw);
+            }
+            catch (SocketException e) when (e.SocketErrorCode == SocketError.AccessDenied ||
+                                            e.SocketErrorCode == SocketError.ProtocolNotSupported ||
+                                            e.SocketErrorCode == SocketError.AddressFamilyNotSupported)
+            {
+                // Ignore. We may not have privilege or protocol modules are not loaded.
+                return;
+            }
+            s.Close();
+        }
     }
 }
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/CreateSocketTests.netcoreapp.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/CreateSocketTests.netcoreapp.cs
deleted file mode 100644 (file)
index d9f49cc..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-// 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.Diagnostics;
-using System.IO;
-using System.IO.Pipes;
-using System.Threading.Tasks;
-using Microsoft.DotNet.RemoteExecutor;
-using Xunit;
-
-namespace System.Net.Sockets.Tests
-{
-    public partial class CreateSocket
-    {
-        [Theory]
-        [InlineData(AddressFamily.Packet)]
-        [InlineData(AddressFamily.ControllerAreaNetwork)]
-        [PlatformSpecific(~TestPlatforms.Linux)]
-        public void Ctor_Netcoreapp_Throws(AddressFamily addressFamily)
-        {
-            // All protocols are Linux specific and throw on other platforms
-            Assert.Throws<SocketException>(() => new Socket(addressFamily, SocketType.Raw, 0));
-        }
-
-        [Theory]
-        [InlineData(AddressFamily.Packet)]
-        [InlineData(AddressFamily.ControllerAreaNetwork)]
-        [PlatformSpecific(TestPlatforms.Linux)]
-        public void Ctor_Netcoreapp_Success(AddressFamily addressFamily)
-        {
-            Socket s = null;
-            try
-            {
-                s = new Socket(addressFamily, SocketType.Raw, ProtocolType.Raw);
-            }
-            catch (SocketException e) when (e.SocketErrorCode == SocketError.AccessDenied ||
-                                            e.SocketErrorCode == SocketError.ProtocolNotSupported ||
-                                            e.SocketErrorCode == SocketError.AddressFamilyNotSupported)
-            {
-                // Ignore. We may not have privilege or protocol modules are not loaded.
-                return;
-            }
-            s.Close();
-        }
-    }
-}
index d5c662b..044ee05 100644 (file)
@@ -3,12 +3,15 @@
 // 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
+    public 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) };
@@ -732,5 +735,62 @@ namespace System.Net.Sockets.Tests
         {
             Assert.Throws<ObjectDisposedException>(() => GetDisposedSocket().EndAccept(null));
         }
+
+        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsPreciseGcSupported))]
+        [InlineData(false)]
+        [InlineData(true)]
+        public async Task NonDisposedSocket_SafeHandlesCollected(bool clientAsync)
+        {
+            List<WeakReference> handles = await CreateHandlesAsync(clientAsync);
+            RetryHelper.Execute(() =>
+            {
+                GC.Collect();
+                GC.WaitForPendingFinalizers();
+                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();
+
+                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;
+        }
     }
 }
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.netcoreapp.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/DisposedSocketTests.netcoreapp.cs
deleted file mode 100644 (file)
index 41d8f18..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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
-    {
-        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsPreciseGcSupported))]
-        [InlineData(false)]
-        [InlineData(true)]
-        public async Task NonDisposedSocket_SafeHandlesCollected(bool clientAsync)
-        {
-            List<WeakReference> handles = await CreateHandlesAsync(clientAsync);
-            RetryHelper.Execute(() =>
-            {
-                GC.Collect();
-                GC.WaitForPendingFinalizers();
-                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();
-
-                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 0149910..2d2d8d9 100644 (file)
@@ -3,13 +3,15 @@
 // See the LICENSE file in the project root for more information.
 
 using System.IO;
+using System.Runtime.CompilerServices;
+using System.Text;
 using System.Threading;
 using System.Threading.Tasks;
 using Xunit;
 
 namespace System.Net.Sockets.Tests
 {
-    public partial class ExecutionContextFlowTest : FileCleanupTestBase
+    public class ExecutionContextFlowTest : FileCleanupTestBase
     {
         [Theory]
         [InlineData(false)]
@@ -497,5 +499,128 @@ namespace System.Net.Sockets.Tests
                 }
             }
         }
+
+        [OuterLoop("Relies on finalization")]
+        [Fact]
+        public void ExecutionContext_NotCachedInSocketAsyncEventArgs()
+        {
+            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            {
+                listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+                listener.Listen(1);
+
+                client.Connect(listener.LocalEndPoint);
+                using (Socket server = listener.Accept())
+                using (var saea = new SocketAsyncEventArgs())
+                {
+                    var receiveCompleted = new ManualResetEventSlim();
+                    saea.Completed += (_, __) => receiveCompleted.Set();
+                    saea.SetBuffer(new byte[1]);
+
+                    var ecDropped = new ManualResetEventSlim();
+                    var al = CreateAsyncLocalWithSetWhenFinalized(ecDropped);
+                    Assert.True(client.ReceiveAsync(saea));
+                    al.Value = null;
+
+                    server.Send(new byte[1]);
+                    Assert.True(receiveCompleted.Wait(TestSettings.PassingTestTimeout));
+
+                    for (int i = 0; i < 3; i++)
+                    {
+                        GC.Collect();
+                        GC.WaitForPendingFinalizers();
+                    }
+
+                    Assert.True(ecDropped.Wait(TestSettings.PassingTestTimeout));
+                }
+            }
+        }
+
+        [MethodImpl(MethodImplOptions.NoInlining)]
+        private static AsyncLocal<object> CreateAsyncLocalWithSetWhenFinalized(ManualResetEventSlim ecDropped) =>
+            new AsyncLocal<object>() { Value = new SetOnFinalized { _setWhenFinalized = ecDropped } };
+
+        private sealed class SetOnFinalized
+        {
+            internal ManualResetEventSlim _setWhenFinalized;
+            ~SetOnFinalized() => _setWhenFinalized.Set();
+        }
+
+        [Fact]
+        public Task ExecutionContext_FlowsOnlyOnceAcrossAsyncOperations()
+        {
+            return Task.Run(async () => // escape xunit's sync ctx
+            {
+                using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+                using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+                {
+                    listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+                    listener.Listen(1);
+
+                    client.Connect(listener.LocalEndPoint);
+                    using (Socket server = listener.Accept())
+                    {
+                        var stackLog = new StringBuilder();
+                        int executionContextChanges = 0;
+                        var asyncLocal = new AsyncLocal<int>(_ =>
+                        {
+                            lock (stackLog)
+                            {
+                                executionContextChanges++;
+                                stackLog.AppendLine($"#{executionContextChanges}: {Environment.StackTrace}");
+                            }
+                        });
+                        Assert.Equal(0, executionContextChanges);
+
+                        int numAwaits = 20;
+                        for (int i = 1; i <= numAwaits; i++)
+                        {
+                            asyncLocal.Value = i;
+
+                            await new AwaitWithOnCompletedInvocation<int>(
+                                client.ReceiveAsync(new Memory<byte>(new byte[1]), SocketFlags.None),
+                                () => server.Send(new byte[1]));
+
+                            Assert.Equal(i, asyncLocal.Value);
+                        }
+
+                        // This doesn't count EC changes where EC.Run is passed the same context
+                        // as is current, but it's the best we can track via public API.
+                        try
+                        {
+                            Assert.InRange(executionContextChanges, 1, numAwaits * 3); // at most: 1 / AsyncLocal change + 1 / suspend + 1 / resume
+                        }
+                        catch (Exception e)
+                        {
+                            throw new Exception($"{nameof(executionContextChanges)} == {executionContextChanges} with log: {stackLog.ToString()}", e);
+                        }
+                    }
+                }
+            });
+        }
+
+        private readonly struct AwaitWithOnCompletedInvocation<T> : ICriticalNotifyCompletion
+        {
+            private readonly ValueTask<T> _valueTask;
+            private readonly Action _invokeAfterOnCompleted;
+
+            public AwaitWithOnCompletedInvocation(ValueTask<T> valueTask, Action invokeAfterOnCompleted)
+            {
+                _valueTask = valueTask;
+                _invokeAfterOnCompleted = invokeAfterOnCompleted;
+            }
+
+            public AwaitWithOnCompletedInvocation<T> GetAwaiter() => this;
+
+            public bool IsCompleted => false;
+            public T GetResult() => _valueTask.GetAwaiter().GetResult();
+            public void OnCompleted(Action continuation) => throw new NotSupportedException();
+            public void UnsafeOnCompleted(Action continuation)
+            {
+                _valueTask.GetAwaiter().UnsafeOnCompleted(continuation);
+                _invokeAfterOnCompleted();
+            }
+        }
     }
 }
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/ExecutionContextFlowTest.netcoreapp.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/ExecutionContextFlowTest.netcoreapp.cs
deleted file mode 100644 (file)
index 67743d1..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-// 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.IO;
-using System.Runtime.CompilerServices;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Xunit;
-
-namespace System.Net.Sockets.Tests
-{
-    public partial class ExecutionContextFlowTest : FileCleanupTestBase
-    {
-        [OuterLoop("Relies on finalization")]
-        [Fact]
-        public void ExecutionContext_NotCachedInSocketAsyncEventArgs()
-        {
-            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            {
-                listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
-                listener.Listen(1);
-
-                client.Connect(listener.LocalEndPoint);
-                using (Socket server = listener.Accept())
-                using (var saea = new SocketAsyncEventArgs())
-                {
-                    var receiveCompleted = new ManualResetEventSlim();
-                    saea.Completed += (_, __) => receiveCompleted.Set();
-                    saea.SetBuffer(new byte[1]);
-
-                    var ecDropped = new ManualResetEventSlim();
-                    var al = CreateAsyncLocalWithSetWhenFinalized(ecDropped);
-                    Assert.True(client.ReceiveAsync(saea));
-                    al.Value = null;
-
-                    server.Send(new byte[1]);
-                    Assert.True(receiveCompleted.Wait(TestSettings.PassingTestTimeout));
-
-                    for (int i = 0; i < 3; i++)
-                    {
-                        GC.Collect();
-                        GC.WaitForPendingFinalizers();
-                    }
-
-                    Assert.True(ecDropped.Wait(TestSettings.PassingTestTimeout));
-                }
-            }
-        }
-
-        [MethodImpl(MethodImplOptions.NoInlining)]
-        private static AsyncLocal<object> CreateAsyncLocalWithSetWhenFinalized(ManualResetEventSlim ecDropped) =>
-            new AsyncLocal<object>() { Value = new SetOnFinalized { _setWhenFinalized = ecDropped } };
-
-        private sealed class SetOnFinalized
-        {
-            internal ManualResetEventSlim _setWhenFinalized;
-            ~SetOnFinalized() => _setWhenFinalized.Set();
-        }
-
-        [Fact]
-        public Task ExecutionContext_FlowsOnlyOnceAcrossAsyncOperations()
-        {
-            return Task.Run(async () => // escape xunit's sync ctx
-            {
-                using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-                using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-                {
-                    listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
-                    listener.Listen(1);
-
-                    client.Connect(listener.LocalEndPoint);
-                    using (Socket server = listener.Accept())
-                    {
-                        var stackLog = new StringBuilder();
-                        int executionContextChanges = 0;
-                        var asyncLocal = new AsyncLocal<int>(_ =>
-                        {
-                            lock (stackLog)
-                            {
-                                executionContextChanges++;
-                                stackLog.AppendLine($"#{executionContextChanges}: {Environment.StackTrace}");
-                            }
-                        });
-                        Assert.Equal(0, executionContextChanges);
-
-                        int numAwaits = 20;
-                        for (int i = 1; i <= numAwaits; i++)
-                        {
-                            asyncLocal.Value = i;
-
-                            await new AwaitWithOnCompletedInvocation<int>(
-                                client.ReceiveAsync(new Memory<byte>(new byte[1]), SocketFlags.None),
-                                () => server.Send(new byte[1]));
-
-                            Assert.Equal(i, asyncLocal.Value);
-                        }
-
-                        // This doesn't count EC changes where EC.Run is passed the same context
-                        // as is current, but it's the best we can track via public API.
-                        try
-                        {
-                            Assert.InRange(executionContextChanges, 1, numAwaits * 3); // at most: 1 / AsyncLocal change + 1 / suspend + 1 / resume
-                        }
-                        catch (Exception e)
-                        {
-                            throw new Exception($"{nameof(executionContextChanges)} == {executionContextChanges} with log: {stackLog.ToString()}", e);
-                        }
-                    }
-                }
-            });
-        }
-
-        private readonly struct AwaitWithOnCompletedInvocation<T> : ICriticalNotifyCompletion
-        {
-            private readonly ValueTask<T> _valueTask;
-            private readonly Action _invokeAfterOnCompleted;
-
-            public AwaitWithOnCompletedInvocation(ValueTask<T> valueTask, Action invokeAfterOnCompleted)
-            {
-                _valueTask = valueTask;
-                _invokeAfterOnCompleted = invokeAfterOnCompleted;
-            }
-
-            public AwaitWithOnCompletedInvocation<T> GetAwaiter() => this;
-
-            public bool IsCompleted => false;
-            public T GetResult() => _valueTask.GetAwaiter().GetResult();
-            public void OnCompleted(Action continuation) => throw new NotSupportedException();
-            public void UnsafeOnCompleted(Action continuation)
-            {
-                _valueTask.GetAwaiter().UnsafeOnCompleted(continuation);
-                _invokeAfterOnCompleted();
-            }
-        }
-    }
-}
index 3d8ffe9..e018229 100644 (file)
@@ -2,15 +2,18 @@
 // 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.IO;
+using System.Linq;
 using System.Runtime.InteropServices;
+using System.Security.Cryptography;
 using System.Threading;
 using System.Threading.Tasks;
 using Xunit;
 
 namespace System.Net.Sockets.Tests
 {
-    public partial class NetworkStreamTest
+    public class NetworkStreamTest
     {
         [Fact]
         public void Ctor_NullSocket_ThrowsArgumentNullExceptions()
@@ -723,6 +726,445 @@ namespace System.Net.Sockets.Tests
             }, serverAccess:FileAccess.Write);
         }
 
+        [Fact]
+        public async Task ReadWrite_Span_Success()
+        {
+            await RunWithConnectedNetworkStreamsAsync((server, client) =>
+            {
+                var clientData = new byte[] { 42 };
+
+                client.Write((ReadOnlySpan<byte>)clientData);
+
+                var serverData = new byte[clientData.Length];
+                Assert.Equal(serverData.Length, server.Read((Span<byte>)serverData));
+
+                Assert.Equal(clientData, serverData);
+                return Task.CompletedTask;
+            });
+        }
+
+        [Fact]
+        public async Task ReadWrite_Memory_Success()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                var clientData = new byte[] { 42 };
+
+                await client.WriteAsync((ReadOnlyMemory<byte>)clientData);
+
+                var serverData = new byte[clientData.Length];
+                Assert.Equal(serverData.Length, await server.ReadAsync((Memory<byte>)serverData));
+
+                Assert.Equal(clientData, serverData);
+            });
+        }
+
+        [Fact]
+        public async Task ReadWrite_Memory_LargeWrite_Success()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                var writeBuffer = new byte[10 * 1024 * 1024];
+                var readBuffer = new byte[writeBuffer.Length];
+                RandomNumberGenerator.Fill(writeBuffer);
+
+                ValueTask writeTask = client.WriteAsync((ReadOnlyMemory<byte>)writeBuffer);
+
+                int totalRead = 0;
+                while (totalRead < readBuffer.Length)
+                {
+                    int bytesRead = await server.ReadAsync(new Memory<byte>(readBuffer).Slice(totalRead));
+                    Assert.InRange(bytesRead, 0, int.MaxValue);
+                    if (bytesRead == 0)
+                    {
+                        break;
+                    }
+                    totalRead += bytesRead;
+                }
+                Assert.Equal(readBuffer.Length, totalRead);
+                Assert.Equal<byte>(writeBuffer, readBuffer);
+
+                await writeTask;
+            });
+        }
+
+        [Fact]
+        public async Task ReadWrite_Precanceled_Throws()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.WriteAsync((ArraySegment<byte>)new byte[0], new CancellationToken(true)));
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.ReadAsync((ArraySegment<byte>)new byte[0], new CancellationToken(true)));
+
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.WriteAsync((ReadOnlyMemory<byte>)new byte[0], new CancellationToken(true)));
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.ReadAsync((Memory<byte>)new byte[0], new CancellationToken(true)));
+            });
+        }
+
+        [Fact]
+        public async Task ReadAsync_AwaitMultipleTimes_Throws()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                var b = new byte[1];
+                ValueTask<int> r = server.ReadAsync(b);
+                await client.WriteAsync(new byte[] { 42 });
+                Assert.Equal(1, await r);
+                Assert.Equal(42, b[0]);
+                await Assert.ThrowsAsync<InvalidOperationException>(async () => await r);
+                Assert.Throws<InvalidOperationException>(() => r.GetAwaiter().IsCompleted);
+                Assert.Throws<InvalidOperationException>(() => r.GetAwaiter().OnCompleted(() => { }));
+                Assert.Throws<InvalidOperationException>(() => r.GetAwaiter().GetResult());
+            });
+        }
+
+        [Fact]
+        public async Task ReadAsync_MultipleContinuations_Throws()
+        {
+            await RunWithConnectedNetworkStreamsAsync((server, client) =>
+            {
+                var b = new byte[1];
+                ValueTask<int> r = server.ReadAsync(b);
+                r.GetAwaiter().OnCompleted(() => { });
+                Assert.Throws<InvalidOperationException>(() => r.GetAwaiter().OnCompleted(() => { }));
+                return Task.CompletedTask;
+            });
+        }
+
+        [Fact]
+        public async Task ReadAsync_MultipleConcurrentValueTaskReads_Success()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                // Technically this isn't supported behavior, but it happens to work because it's supported on socket.
+                // So validate it to alert us to any potential future breaks.
+
+                byte[] b1 = new byte[1], b2 = new byte[1], b3 = new byte[1];
+                ValueTask<int> r1 = server.ReadAsync(b1);
+                ValueTask<int> r2 = server.ReadAsync(b2);
+                ValueTask<int> r3 = server.ReadAsync(b3);
+
+                await client.WriteAsync(new byte[] { 42, 43, 44 });
+
+                Assert.Equal(3, await r1 + await r2 + await r3);
+                Assert.Equal(42 + 43 + 44, b1[0] + b2[0] + b3[0]);
+            });
+        }
+
+        [Fact]
+        public async Task ReadAsync_MultipleConcurrentValueTaskReads_AsTask_Success()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                // Technically this isn't supported behavior, but it happens to work because it's supported on socket.
+                // So validate it to alert us to any potential future breaks.
+
+                byte[] b1 = new byte[1], b2 = new byte[1], b3 = new byte[1];
+                Task<int> r1 = server.ReadAsync((Memory<byte>)b1).AsTask();
+                Task<int> r2 = server.ReadAsync((Memory<byte>)b2).AsTask();
+                Task<int> r3 = server.ReadAsync((Memory<byte>)b3).AsTask();
+
+                await client.WriteAsync(new byte[] { 42, 43, 44 });
+
+                Assert.Equal(3, await r1 + await r2 + await r3);
+                Assert.Equal(42 + 43 + 44, b1[0] + b2[0] + b3[0]);
+            });
+        }
+
+        [Fact]
+        public async Task WriteAsync_MultipleConcurrentValueTaskWrites_Success()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                // Technically this isn't supported behavior, but it happens to work because it's supported on socket.
+                // So validate it to alert us to any potential future breaks.
+
+                ValueTask s1 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 42 }));
+                ValueTask s2 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 43 }));
+                ValueTask s3 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 44 }));
+
+                byte[] b1 = new byte[1], b2 = new byte[1], b3 = new byte[1];
+                Assert.Equal(3,
+                    await client.ReadAsync((Memory<byte>)b1) +
+                    await client.ReadAsync((Memory<byte>)b2) +
+                    await client.ReadAsync((Memory<byte>)b3));
+
+                await s1;
+                await s2;
+                await s3;
+
+                Assert.Equal(42 + 43 + 44, b1[0] + b2[0] + b3[0]);
+            });
+        }
+
+        [Fact]
+        public async Task WriteAsync_MultipleConcurrentValueTaskWrites_AsTask_Success()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                // Technically this isn't supported behavior, but it happens to work because it's supported on socket.
+                // So validate it to alert us to any potential future breaks.
+
+                Task s1 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 42 })).AsTask();
+                Task s2 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 43 })).AsTask();
+                Task s3 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 44 })).AsTask();
+
+                byte[] b1 = new byte[1], b2 = new byte[1], b3 = new byte[1];
+                Task<int> r1 = client.ReadAsync((Memory<byte>)b1).AsTask();
+                Task<int> r2 = client.ReadAsync((Memory<byte>)b2).AsTask();
+                Task<int> r3 = client.ReadAsync((Memory<byte>)b3).AsTask();
+
+                await Task.WhenAll(s1, s2, s3, r1, r2, r3);
+
+                Assert.Equal(3, await r1 + await r2 + await r3);
+                Assert.Equal(42 + 43 + 44, b1[0] + b2[0] + b3[0]);
+            });
+        }
+
+        public static IEnumerable<object[]> ReadAsync_ContinuesOnCurrentContextIfDesired_MemberData() =>
+            from flowExecutionContext in new[] { true, false }
+            from continueOnCapturedContext in new bool?[] { null, false, true }
+            select new object[] { flowExecutionContext, continueOnCapturedContext };
+
+        [Theory]
+        [MemberData(nameof(ReadAsync_ContinuesOnCurrentContextIfDesired_MemberData))]
+        public async Task ReadAsync_ContinuesOnCurrentSynchronizationContextIfDesired(
+            bool flowExecutionContext, bool? continueOnCapturedContext)
+        {
+            await Task.Run(async () => // escape xunit sync ctx
+            {
+                await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+                {
+                    Assert.Null(SynchronizationContext.Current);
+
+                    var continuationRan = new TaskCompletionSource<bool>();
+                    var asyncLocal = new AsyncLocal<int>();
+                    bool schedulerWasFlowed = false;
+                    bool executionContextWasFlowed = false;
+                    Action continuation = () =>
+                    {
+                        schedulerWasFlowed = SynchronizationContext.Current is CustomSynchronizationContext;
+                        executionContextWasFlowed = 42 == asyncLocal.Value;
+                        continuationRan.SetResult(true);
+                    };
+
+                    var readBuffer = new byte[1];
+                    ValueTask<int> readValueTask = client.ReadAsync((Memory<byte>)new byte[1]);
+
+                    SynchronizationContext.SetSynchronizationContext(new CustomSynchronizationContext());
+                    asyncLocal.Value = 42;
+                    switch (continueOnCapturedContext)
+                    {
+                        case null:
+                            if (flowExecutionContext)
+                            {
+                                readValueTask.GetAwaiter().OnCompleted(continuation);
+                            }
+                            else
+                            {
+                                readValueTask.GetAwaiter().UnsafeOnCompleted(continuation);
+                            }
+                            break;
+                        default:
+                            if (flowExecutionContext)
+                            {
+                                readValueTask.ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().OnCompleted(continuation);
+                            }
+                            else
+                            {
+                                readValueTask.ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().UnsafeOnCompleted(continuation);
+                            }
+                            break;
+                    }
+                    asyncLocal.Value = 0;
+                    SynchronizationContext.SetSynchronizationContext(null);
+
+                    Assert.False(readValueTask.IsCompleted);
+                    Assert.False(readValueTask.IsCompletedSuccessfully);
+                    await server.WriteAsync(new byte[] { 42 });
+
+                    await continuationRan.Task;
+                    Assert.True(readValueTask.IsCompleted);
+                    Assert.True(readValueTask.IsCompletedSuccessfully);
+
+                    Assert.Equal(continueOnCapturedContext != false, schedulerWasFlowed);
+                    Assert.Equal(flowExecutionContext, executionContextWasFlowed);
+                });
+            });
+        }
+
+        [Theory]
+        [MemberData(nameof(ReadAsync_ContinuesOnCurrentContextIfDesired_MemberData))]
+        public async Task ReadAsync_ContinuesOnCurrentTaskSchedulerIfDesired(
+            bool flowExecutionContext, bool? continueOnCapturedContext)
+        {
+            await Task.Run(async () => // escape xunit sync ctx
+            {
+                await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+                {
+                    Assert.Null(SynchronizationContext.Current);
+
+                    var continuationRan = new TaskCompletionSource<bool>();
+                    var asyncLocal = new AsyncLocal<int>();
+                    bool schedulerWasFlowed = false;
+                    bool executionContextWasFlowed = false;
+                    Action continuation = () =>
+                    {
+                        schedulerWasFlowed = TaskScheduler.Current is CustomTaskScheduler;
+                        executionContextWasFlowed = 42 == asyncLocal.Value;
+                        continuationRan.SetResult(true);
+                    };
+
+                    var readBuffer = new byte[1];
+                    ValueTask<int> readValueTask = client.ReadAsync((Memory<byte>)new byte[1]);
+
+                    await Task.Factory.StartNew(() =>
+                    {
+                        Assert.IsType<CustomTaskScheduler>(TaskScheduler.Current);
+                        asyncLocal.Value = 42;
+                        switch (continueOnCapturedContext)
+                        {
+                            case null:
+                                if (flowExecutionContext)
+                                {
+                                    readValueTask.GetAwaiter().OnCompleted(continuation);
+                                }
+                                else
+                                {
+                                    readValueTask.GetAwaiter().UnsafeOnCompleted(continuation);
+                                }
+                                break;
+                            default:
+                                if (flowExecutionContext)
+                                {
+                                    readValueTask.ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().OnCompleted(continuation);
+                                }
+                                else
+                                {
+                                    readValueTask.ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().UnsafeOnCompleted(continuation);
+                                }
+                                break;
+                        }
+                        asyncLocal.Value = 0;
+                    }, CancellationToken.None, TaskCreationOptions.None, new CustomTaskScheduler());
+
+                    Assert.False(readValueTask.IsCompleted);
+                    Assert.False(readValueTask.IsCompletedSuccessfully);
+                    await server.WriteAsync(new byte[] { 42 });
+
+                    await continuationRan.Task;
+                    Assert.True(readValueTask.IsCompleted);
+                    Assert.True(readValueTask.IsCompletedSuccessfully);
+
+                    Assert.Equal(continueOnCapturedContext != false, schedulerWasFlowed);
+                    Assert.Equal(flowExecutionContext, executionContextWasFlowed);
+                });
+            });
+        }
+
+        [Fact]
+        public async Task DisposeAsync_ClosesStream()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                Assert.True(client.DisposeAsync().IsCompletedSuccessfully);
+                Assert.True(server.DisposeAsync().IsCompletedSuccessfully);
+
+                await client.DisposeAsync();
+                await server.DisposeAsync();
+
+                Assert.False(server.CanRead);
+                Assert.False(server.CanWrite);
+
+                Assert.False(client.CanRead);
+                Assert.False(client.CanWrite);
+            });
+        }
+
+        [Fact]
+        public async Task ReadAsync_CancelPendingRead_DoesntImpactSubsequentReads()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => client.ReadAsync(new byte[1], 0, 1, new CancellationToken(true)));
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => { await client.ReadAsync(new Memory<byte>(new byte[1]), new CancellationToken(true)); });
+
+                CancellationTokenSource cts = new CancellationTokenSource();
+                Task<int> t = client.ReadAsync(new byte[1], 0, 1, cts.Token);
+                cts.Cancel();
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
+
+                cts = new CancellationTokenSource();
+                ValueTask<int> vt = client.ReadAsync(new Memory<byte>(new byte[1]), cts.Token);
+                cts.Cancel();
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await vt);
+
+                byte[] buffer = new byte[1];
+                vt = client.ReadAsync(new Memory<byte>(buffer));
+                Assert.False(vt.IsCompleted);
+                await server.WriteAsync(new ReadOnlyMemory<byte>(new byte[1] { 42 }));
+                Assert.Equal(1, await vt);
+                Assert.Equal(42, buffer[0]);
+            });
+        }
+
+        [Fact]
+        public async Task WriteAsync_CancelPendingWrite_SucceedsOrThrowsOperationCanceled()
+        {
+            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
+            {
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => client.WriteAsync(new byte[1], 0, 1, new CancellationToken(true)));
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => { await client.WriteAsync(new Memory<byte>(new byte[1]), new CancellationToken(true)); });
+
+                byte[] hugeBuffer = new byte[100_000_000];
+                Exception e;
+
+                var cts = new CancellationTokenSource();
+                Task t = client.WriteAsync(hugeBuffer, 0, hugeBuffer.Length, cts.Token);
+                cts.Cancel();
+                e = await Record.ExceptionAsync(async () => await t);
+                if (e != null)
+                {
+                    Assert.IsAssignableFrom<OperationCanceledException>(e);
+                }
+
+                cts = new CancellationTokenSource();
+                ValueTask vt = client.WriteAsync(new Memory<byte>(hugeBuffer), cts.Token);
+                cts.Cancel();
+                e = await Record.ExceptionAsync(async () => await vt);
+                if (e != null)
+                {
+                    Assert.IsAssignableFrom<OperationCanceledException>(e);
+                }
+            });
+        }
+
+        private sealed class CustomSynchronizationContext : SynchronizationContext
+        {
+            public override void Post(SendOrPostCallback d, object state)
+            {
+                ThreadPool.QueueUserWorkItem(delegate
+                {
+                    SetSynchronizationContext(this);
+                    try
+                    {
+                        d(state);
+                    }
+                    finally
+                    {
+                        SetSynchronizationContext(null);
+                    }
+                }, null);
+            }
+        }
+
+        private sealed class CustomTaskScheduler : TaskScheduler
+        {
+            protected override void QueueTask(Task task) => ThreadPool.QueueUserWorkItem(_ => TryExecuteTask(task));
+            protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) => false;
+            protected override IEnumerable<Task> GetScheduledTasks() => null;
+        }
+
         /// <summary>
         /// Creates a pair of connected NetworkStreams and invokes the provided <paramref name="func"/>
         /// with them as arguments.
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.netcoreapp.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/NetworkStreamTest.netcoreapp.cs
deleted file mode 100644 (file)
index f072953..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-// 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.Security.Cryptography;
-using System.Threading;
-using System.Threading.Tasks;
-using Xunit;
-
-namespace System.Net.Sockets.Tests
-{
-    public partial class NetworkStreamTest
-    {
-        [Fact]
-        public async Task ReadWrite_Span_Success()
-        {
-            await RunWithConnectedNetworkStreamsAsync((server, client) =>
-            {
-                var clientData = new byte[] { 42 };
-
-                client.Write((ReadOnlySpan<byte>)clientData);
-
-                var serverData = new byte[clientData.Length];
-                Assert.Equal(serverData.Length, server.Read((Span<byte>)serverData));
-
-                Assert.Equal(clientData, serverData);
-                return Task.CompletedTask;
-            });
-        }
-
-        [Fact]
-        public async Task ReadWrite_Memory_Success()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                var clientData = new byte[] { 42 };
-
-                await client.WriteAsync((ReadOnlyMemory<byte>)clientData);
-
-                var serverData = new byte[clientData.Length];
-                Assert.Equal(serverData.Length, await server.ReadAsync((Memory<byte>)serverData));
-
-                Assert.Equal(clientData, serverData);
-            });
-        }
-
-        [Fact]
-        public async Task ReadWrite_Memory_LargeWrite_Success()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                var writeBuffer = new byte[10 * 1024 * 1024];
-                var readBuffer = new byte[writeBuffer.Length];
-                RandomNumberGenerator.Fill(writeBuffer);
-
-                ValueTask writeTask = client.WriteAsync((ReadOnlyMemory<byte>)writeBuffer);
-
-                int totalRead = 0;
-                while (totalRead < readBuffer.Length)
-                {
-                    int bytesRead = await server.ReadAsync(new Memory<byte>(readBuffer).Slice(totalRead));
-                    Assert.InRange(bytesRead, 0, int.MaxValue);
-                    if (bytesRead == 0)
-                    {
-                        break;
-                    }
-                    totalRead += bytesRead;
-                }
-                Assert.Equal(readBuffer.Length, totalRead);
-                Assert.Equal<byte>(writeBuffer, readBuffer);
-
-                await writeTask;
-            });
-        }
-
-        [Fact]
-        public async Task ReadWrite_Precanceled_Throws()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.WriteAsync((ArraySegment<byte>)new byte[0], new CancellationToken(true)));
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.ReadAsync((ArraySegment<byte>)new byte[0], new CancellationToken(true)));
-
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.WriteAsync((ReadOnlyMemory<byte>)new byte[0], new CancellationToken(true)));
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.ReadAsync((Memory<byte>)new byte[0], new CancellationToken(true)));
-            });
-        }
-
-        [Fact]
-        public async Task ReadAsync_AwaitMultipleTimes_Throws()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                var b = new byte[1];
-                ValueTask<int> r = server.ReadAsync(b);
-                await client.WriteAsync(new byte[] { 42 });
-                Assert.Equal(1, await r);
-                Assert.Equal(42, b[0]);
-                await Assert.ThrowsAsync<InvalidOperationException>(async () => await r);
-                Assert.Throws<InvalidOperationException>(() => r.GetAwaiter().IsCompleted);
-                Assert.Throws<InvalidOperationException>(() => r.GetAwaiter().OnCompleted(() => { }));
-                Assert.Throws<InvalidOperationException>(() => r.GetAwaiter().GetResult());
-            });
-        }
-
-        [Fact]
-        public async Task ReadAsync_MultipleContinuations_Throws()
-        {
-            await RunWithConnectedNetworkStreamsAsync((server, client) =>
-            {
-                var b = new byte[1];
-                ValueTask<int> r = server.ReadAsync(b);
-                r.GetAwaiter().OnCompleted(() => { });
-                Assert.Throws<InvalidOperationException>(() => r.GetAwaiter().OnCompleted(() => { }));
-                return Task.CompletedTask;
-            });
-        }
-
-        [Fact]
-        public async Task ReadAsync_MultipleConcurrentValueTaskReads_Success()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                // Technically this isn't supported behavior, but it happens to work because it's supported on socket.
-                // So validate it to alert us to any potential future breaks.
-
-                byte[] b1 = new byte[1], b2 = new byte[1], b3 = new byte[1];
-                ValueTask<int> r1 = server.ReadAsync(b1);
-                ValueTask<int> r2 = server.ReadAsync(b2);
-                ValueTask<int> r3 = server.ReadAsync(b3);
-
-                await client.WriteAsync(new byte[] { 42, 43, 44 });
-
-                Assert.Equal(3, await r1 + await r2 + await r3);
-                Assert.Equal(42 + 43 + 44, b1[0] + b2[0] + b3[0]);
-            });
-        }
-
-        [Fact]
-        public async Task ReadAsync_MultipleConcurrentValueTaskReads_AsTask_Success()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                // Technically this isn't supported behavior, but it happens to work because it's supported on socket.
-                // So validate it to alert us to any potential future breaks.
-
-                byte[] b1 = new byte[1], b2 = new byte[1], b3 = new byte[1];
-                Task<int> r1 = server.ReadAsync((Memory<byte>)b1).AsTask();
-                Task<int> r2 = server.ReadAsync((Memory<byte>)b2).AsTask();
-                Task<int> r3 = server.ReadAsync((Memory<byte>)b3).AsTask();
-
-                await client.WriteAsync(new byte[] { 42, 43, 44 });
-
-                Assert.Equal(3, await r1 + await r2 + await r3);
-                Assert.Equal(42 + 43 + 44, b1[0] + b2[0] + b3[0]);
-            });
-        }
-
-        [Fact]
-        public async Task WriteAsync_MultipleConcurrentValueTaskWrites_Success()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                // Technically this isn't supported behavior, but it happens to work because it's supported on socket.
-                // So validate it to alert us to any potential future breaks.
-
-                ValueTask s1 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 42 }));
-                ValueTask s2 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 43 }));
-                ValueTask s3 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 44 }));
-
-                byte[] b1 = new byte[1], b2 = new byte[1], b3 = new byte[1];
-                Assert.Equal(3,
-                    await client.ReadAsync((Memory<byte>)b1) +
-                    await client.ReadAsync((Memory<byte>)b2) +
-                    await client.ReadAsync((Memory<byte>)b3));
-
-                await s1;
-                await s2;
-                await s3;
-
-                Assert.Equal(42 + 43 + 44, b1[0] + b2[0] + b3[0]);
-            });
-        }
-
-        [Fact]
-        public async Task WriteAsync_MultipleConcurrentValueTaskWrites_AsTask_Success()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                // Technically this isn't supported behavior, but it happens to work because it's supported on socket.
-                // So validate it to alert us to any potential future breaks.
-
-                Task s1 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 42 })).AsTask();
-                Task s2 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 43 })).AsTask();
-                Task s3 = server.WriteAsync(new ReadOnlyMemory<byte>(new byte[] { 44 })).AsTask();
-
-                byte[] b1 = new byte[1], b2 = new byte[1], b3 = new byte[1];
-                Task<int> r1 = client.ReadAsync((Memory<byte>)b1).AsTask();
-                Task<int> r2 = client.ReadAsync((Memory<byte>)b2).AsTask();
-                Task<int> r3 = client.ReadAsync((Memory<byte>)b3).AsTask();
-
-                await Task.WhenAll(s1, s2, s3, r1, r2, r3);
-
-                Assert.Equal(3, await r1 + await r2 + await r3);
-                Assert.Equal(42 + 43 + 44, b1[0] + b2[0] + b3[0]);
-            });
-        }
-
-        public static IEnumerable<object[]> ReadAsync_ContinuesOnCurrentContextIfDesired_MemberData() =>
-            from flowExecutionContext in new[] { true, false }
-            from continueOnCapturedContext in new bool?[] { null, false, true }
-            select new object[] { flowExecutionContext, continueOnCapturedContext };
-
-        [Theory]
-        [MemberData(nameof(ReadAsync_ContinuesOnCurrentContextIfDesired_MemberData))]
-        public async Task ReadAsync_ContinuesOnCurrentSynchronizationContextIfDesired(
-            bool flowExecutionContext, bool? continueOnCapturedContext)
-        {
-            await Task.Run(async () => // escape xunit sync ctx
-            {
-                await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-                {
-                    Assert.Null(SynchronizationContext.Current);
-
-                    var continuationRan = new TaskCompletionSource<bool>();
-                    var asyncLocal = new AsyncLocal<int>();
-                    bool schedulerWasFlowed = false;
-                    bool executionContextWasFlowed = false;
-                    Action continuation = () =>
-                    {
-                        schedulerWasFlowed = SynchronizationContext.Current is CustomSynchronizationContext;
-                        executionContextWasFlowed = 42 == asyncLocal.Value;
-                        continuationRan.SetResult(true);
-                    };
-
-                    var readBuffer = new byte[1];
-                    ValueTask<int> readValueTask = client.ReadAsync((Memory<byte>)new byte[1]);
-
-                    SynchronizationContext.SetSynchronizationContext(new CustomSynchronizationContext());
-                    asyncLocal.Value = 42;
-                    switch (continueOnCapturedContext)
-                    {
-                        case null:
-                            if (flowExecutionContext)
-                            {
-                                readValueTask.GetAwaiter().OnCompleted(continuation);
-                            }
-                            else
-                            {
-                                readValueTask.GetAwaiter().UnsafeOnCompleted(continuation);
-                            }
-                            break;
-                        default:
-                            if (flowExecutionContext)
-                            {
-                                readValueTask.ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().OnCompleted(continuation);
-                            }
-                            else
-                            {
-                                readValueTask.ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().UnsafeOnCompleted(continuation);
-                            }
-                            break;
-                    }
-                    asyncLocal.Value = 0;
-                    SynchronizationContext.SetSynchronizationContext(null);
-
-                    Assert.False(readValueTask.IsCompleted);
-                    Assert.False(readValueTask.IsCompletedSuccessfully);
-                    await server.WriteAsync(new byte[] { 42 });
-
-                    await continuationRan.Task;
-                    Assert.True(readValueTask.IsCompleted);
-                    Assert.True(readValueTask.IsCompletedSuccessfully);
-
-                    Assert.Equal(continueOnCapturedContext != false, schedulerWasFlowed);
-                    Assert.Equal(flowExecutionContext, executionContextWasFlowed);
-                });
-            });
-        }
-
-        [Theory]
-        [MemberData(nameof(ReadAsync_ContinuesOnCurrentContextIfDesired_MemberData))]
-        public async Task ReadAsync_ContinuesOnCurrentTaskSchedulerIfDesired(
-            bool flowExecutionContext, bool? continueOnCapturedContext)
-        {
-            await Task.Run(async () => // escape xunit sync ctx
-            {
-                await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-                {
-                    Assert.Null(SynchronizationContext.Current);
-
-                    var continuationRan = new TaskCompletionSource<bool>();
-                    var asyncLocal = new AsyncLocal<int>();
-                    bool schedulerWasFlowed = false;
-                    bool executionContextWasFlowed = false;
-                    Action continuation = () =>
-                    {
-                        schedulerWasFlowed = TaskScheduler.Current is CustomTaskScheduler;
-                        executionContextWasFlowed = 42 == asyncLocal.Value;
-                        continuationRan.SetResult(true);
-                    };
-
-                    var readBuffer = new byte[1];
-                    ValueTask<int> readValueTask = client.ReadAsync((Memory<byte>)new byte[1]);
-
-                    await Task.Factory.StartNew(() =>
-                    {
-                        Assert.IsType<CustomTaskScheduler>(TaskScheduler.Current);
-                        asyncLocal.Value = 42;
-                        switch (continueOnCapturedContext)
-                        {
-                            case null:
-                                if (flowExecutionContext)
-                                {
-                                    readValueTask.GetAwaiter().OnCompleted(continuation);
-                                }
-                                else
-                                {
-                                    readValueTask.GetAwaiter().UnsafeOnCompleted(continuation);
-                                }
-                                break;
-                            default:
-                                if (flowExecutionContext)
-                                {
-                                    readValueTask.ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().OnCompleted(continuation);
-                                }
-                                else
-                                {
-                                    readValueTask.ConfigureAwait(continueOnCapturedContext.Value).GetAwaiter().UnsafeOnCompleted(continuation);
-                                }
-                                break;
-                        }
-                        asyncLocal.Value = 0;
-                    }, CancellationToken.None, TaskCreationOptions.None, new CustomTaskScheduler());
-
-                    Assert.False(readValueTask.IsCompleted);
-                    Assert.False(readValueTask.IsCompletedSuccessfully);
-                    await server.WriteAsync(new byte[] { 42 });
-
-                    await continuationRan.Task;
-                    Assert.True(readValueTask.IsCompleted);
-                    Assert.True(readValueTask.IsCompletedSuccessfully);
-
-                    Assert.Equal(continueOnCapturedContext != false, schedulerWasFlowed);
-                    Assert.Equal(flowExecutionContext, executionContextWasFlowed);
-                });
-            });
-        }
-
-        [Fact]
-        public async Task DisposeAsync_ClosesStream()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                Assert.True(client.DisposeAsync().IsCompletedSuccessfully);
-                Assert.True(server.DisposeAsync().IsCompletedSuccessfully);
-
-                await client.DisposeAsync();
-                await server.DisposeAsync();
-
-                Assert.False(server.CanRead);
-                Assert.False(server.CanWrite);
-
-                Assert.False(client.CanRead);
-                Assert.False(client.CanWrite);
-            });
-        }
-
-        [Fact]
-        public async Task ReadAsync_CancelPendingRead_DoesntImpactSubsequentReads()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => client.ReadAsync(new byte[1], 0, 1, new CancellationToken(true)));
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => { await client.ReadAsync(new Memory<byte>(new byte[1]), new CancellationToken(true)); });
-
-                CancellationTokenSource cts = new CancellationTokenSource();
-                Task<int> t = client.ReadAsync(new byte[1], 0, 1, cts.Token);
-                cts.Cancel();
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => t);
-
-                cts = new CancellationTokenSource();
-                ValueTask<int> vt = client.ReadAsync(new Memory<byte>(new byte[1]), cts.Token);
-                cts.Cancel();
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await vt);
-
-                byte[] buffer = new byte[1];
-                vt = client.ReadAsync(new Memory<byte>(buffer));
-                Assert.False(vt.IsCompleted);
-                await server.WriteAsync(new ReadOnlyMemory<byte>(new byte[1] { 42 }));
-                Assert.Equal(1, await vt);
-                Assert.Equal(42, buffer[0]);
-            });
-        }
-
-        [Fact]
-        public async Task WriteAsync_CancelPendingWrite_SucceedsOrThrowsOperationCanceled()
-        {
-            await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
-            {
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(() => client.WriteAsync(new byte[1], 0, 1, new CancellationToken(true)));
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => { await client.WriteAsync(new Memory<byte>(new byte[1]), new CancellationToken(true)); });
-
-                byte[] hugeBuffer = new byte[100_000_000];
-                Exception e;
-
-                var cts = new CancellationTokenSource();
-                Task t = client.WriteAsync(hugeBuffer, 0, hugeBuffer.Length, cts.Token);
-                cts.Cancel();
-                e = await Record.ExceptionAsync(async () => await t);
-                if (e != null)
-                {
-                    Assert.IsAssignableFrom<OperationCanceledException>(e);
-                }
-
-                cts = new CancellationTokenSource();
-                ValueTask vt = client.WriteAsync(new Memory<byte>(hugeBuffer), cts.Token);
-                cts.Cancel();
-                e = await Record.ExceptionAsync(async () => await vt);
-                if (e != null)
-                {
-                    Assert.IsAssignableFrom<OperationCanceledException>(e);
-                }
-            });
-        }
-
-        private sealed class CustomSynchronizationContext : SynchronizationContext
-        {
-            public override void Post(SendOrPostCallback d, object state)
-            {
-                ThreadPool.QueueUserWorkItem(delegate
-                {
-                    SetSynchronizationContext(this);
-                    try
-                    {
-                        d(state);
-                    }
-                    finally
-                    {
-                        SetSynchronizationContext(null);
-                    }
-                }, null);
-            }
-        }
-
-        private sealed class CustomTaskScheduler : TaskScheduler
-        {
-            protected override void QueueTask(Task task) => ThreadPool.QueueUserWorkItem(_ => TryExecuteTask(task));
-            protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) => false;
-            protected override IEnumerable<Task> GetScheduledTasks() => null;
-        }
-    }
-}
index 22fdc1a..cc87154 100644 (file)
@@ -11,7 +11,7 @@ using Xunit.Abstractions;
 
 namespace System.Net.Sockets.Tests
 {
-    public partial class SendPacketsAsync
+    public class SendPacketsAsync
     {
         private readonly ITestOutputHelper _log;
 
@@ -51,7 +51,6 @@ namespace System.Net.Sockets.Tests
 
         #endregion Additional test attributes
 
-
         #region Basic Arguments
 
         [OuterLoop] // TODO: Issue #11345
@@ -438,8 +437,250 @@ namespace System.Net.Sockets.Tests
             }
         }
 
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileZeroCount_OffsetLong_Success(SocketImplementationType type)
+        {
+            var element = new SendPacketsElement(TestFileName, 0L, 0);
+            SendPackets(type, element, s_testFileSize, GetExpectedContent(element));  // Whole File
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FilePart_OffsetLong_Success(SocketImplementationType type)
+        {
+            var element = new SendPacketsElement(TestFileName, 10L, 20);
+            SendPackets(type, element, 20, GetExpectedContent(element));
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileMultiPart_OffsetLong_Success(SocketImplementationType type)
+        {
+            var elements = new[]
+            {
+                new SendPacketsElement(TestFileName, 10L, 20),
+                new SendPacketsElement(TestFileName, 30L, 10),
+                new SendPacketsElement(TestFileName, 0L, 10),
+            };
+            SendPackets(type, elements, SocketError.Success, 40, GetExpectedContent(elements));
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileLargeOffset_OffsetLong_Throws(SocketImplementationType type)
+        {
+            // Length is validated on Send
+            SendPackets(type, new SendPacketsElement(TestFileName, (long)uint.MaxValue + 11000, 1), SocketError.InvalidArgument, 0);
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileLargeCount_OffsetLong_Throws(SocketImplementationType type)
+        {
+            // Length is validated on Send
+            SendPackets(type, new SendPacketsElement(TestFileName, 5L, 10000), SocketError.InvalidArgument, 0);
+        }
+
         #endregion Files
 
+        #region FileStreams
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStream_Success(SocketImplementationType type)
+        {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
+            {
+                stream.Seek(s_testFileSize / 2, SeekOrigin.Begin);
+                SendPackets(type, new SendPacketsElement(stream), s_testFileSize); // Whole File
+                Assert.Equal(s_testFileSize / 2, stream.Position);
+
+                SendPackets(type, new SendPacketsElement(stream), s_testFileSize); // Whole File
+                Assert.Equal(s_testFileSize / 2, stream.Position);
+            }
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStreamZeroCount_Success(SocketImplementationType type)
+        {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
+            {
+                stream.Seek(s_testFileSize / 2, SeekOrigin.Begin);
+                SendPackets(type, new SendPacketsElement(stream, 0, 0), s_testFileSize); // Whole File
+                Assert.Equal(s_testFileSize / 2, stream.Position);
+
+                SendPackets(type, new SendPacketsElement(stream, 0, 0), s_testFileSize); // Whole File
+                Assert.Equal(s_testFileSize / 2, stream.Position);
+            }
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStreamSizeCount_Success(SocketImplementationType type)
+        {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
+            {
+                stream.Seek(s_testFileSize / 2, SeekOrigin.Begin);
+                SendPackets(type, new SendPacketsElement(stream, 0, s_testFileSize), s_testFileSize); // Whole File
+                Assert.Equal(s_testFileSize / 2, stream.Position);
+
+                SendPackets(type, new SendPacketsElement(stream, 0, s_testFileSize), s_testFileSize); // Whole File
+                Assert.Equal(s_testFileSize / 2, stream.Position);
+            }
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStreamPart_Success(SocketImplementationType type)
+        {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
+            {
+                stream.Seek(s_testFileSize - 10, SeekOrigin.Begin);
+                SendPackets(type, new SendPacketsElement(stream, 0, 20), 20);
+                Assert.Equal(s_testFileSize - 10, stream.Position);
+
+                SendPackets(type, new SendPacketsElement(stream, 10, 20), 20);
+                Assert.Equal(s_testFileSize - 10, stream.Position);
+
+                SendPackets(type, new SendPacketsElement(stream, s_testFileSize - 20, 20), 20);
+                Assert.Equal(s_testFileSize - 10, stream.Position);
+            }
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStreamMultiPart_Success(SocketImplementationType type)
+        {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous))
+            {
+                var elements = new[]
+                {
+                    new SendPacketsElement(stream, 0, 20),
+                    new SendPacketsElement(stream, s_testFileSize - 10, 10),
+                    new SendPacketsElement(stream, 0, 10),
+                    new SendPacketsElement(stream, 10, 20),
+                    new SendPacketsElement(stream, 30, 10),
+                };
+                stream.Seek(s_testFileSize - 10, SeekOrigin.Begin);
+                SendPackets(type, elements, SocketError.Success, 70, GetExpectedContent(elements));
+                Assert.Equal(s_testFileSize - 10, stream.Position);
+
+                SendPackets(type, elements, SocketError.Success, 70, GetExpectedContent(elements));
+                Assert.Equal(s_testFileSize - 10, stream.Position);
+            }
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStreamLargeOffset_Throws(SocketImplementationType type)
+        {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
+            {
+                stream.Seek(s_testFileSize / 2, SeekOrigin.Begin);
+                // Length is validated on Send
+                SendPackets(type, new SendPacketsElement(stream, (long)uint.MaxValue + 11000, 1), SocketError.InvalidArgument, 0);
+            }
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStreamLargeCount_Throws(SocketImplementationType type)
+        {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
+            {
+                stream.Seek(s_testFileSize / 2, SeekOrigin.Begin);
+                // Length is validated on Send
+                SendPackets(type, new SendPacketsElement(stream, 5, 10000),
+                    SocketError.InvalidArgument, 0);
+            }
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStreamWithOptions_Success(SocketImplementationType type) {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, FileOptions.Asynchronous | FileOptions.SequentialScan)) {
+                var element = new SendPacketsElement(stream, 0, s_testFileSize);
+                SendPackets(type, element, s_testFileSize, GetExpectedContent(element));
+            }
+        }
+
+        #endregion FileStreams
+
+        #region Mixed Buffer, FilePath, FileStream tests
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStreamMultiPartMixed_Success(SocketImplementationType type) {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) {
+                var elements = new[]
+                {
+                    new SendPacketsElement(new byte[] { 5, 6, 7 }, 0, 3),
+                    new SendPacketsElement(stream, s_testFileSize - 10, 10),
+                    new SendPacketsElement(TestFileName, 0L, 10),
+                    new SendPacketsElement(stream, 10L, 20),
+                    new SendPacketsElement(TestFileName, 30, 10),
+                    new SendPacketsElement(new byte[] { 8, 9, 10 }, 0, 3),
+                };
+                byte[] expected = GetExpectedContent(elements);
+                SendPackets(type, elements, SocketError.Success, expected.Length, expected);
+            }
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStreamMultiPartMixed_MultipleFileStreams_Success(SocketImplementationType type) {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous))
+            using (var stream2 = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) {
+                var elements = new[]
+                {
+                    new SendPacketsElement(new byte[] { 5, 6, 7 }, 0, 0),
+                    new SendPacketsElement(stream, s_testFileSize - 10, 10),
+                    new SendPacketsElement(stream2, s_testFileSize - 100, 10),
+                    new SendPacketsElement(TestFileName, 0L, 10),
+                    new SendPacketsElement(new byte[] { 8, 9, 10 }, 0, 1),
+                    new SendPacketsElement(TestFileName, 30, 10),
+                };
+                byte[] expected = GetExpectedContent(elements);
+                SendPackets(type, elements, SocketError.Success, expected.Length, expected);
+            }
+        }
+
+        [Theory]
+        [InlineData(SocketImplementationType.APM)]
+        [InlineData(SocketImplementationType.Async)]
+        public void SendPacketsElement_FileStreamMultiPartMixed_MultipleWholeFiles_Success(SocketImplementationType type) {
+            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) {
+                var elements = new[]
+                {
+                    new SendPacketsElement(stream, 0L, 0),
+                    new SendPacketsElement(TestFileName, 0L, 10),
+                    new SendPacketsElement(stream, 0L, 0),
+                    new SendPacketsElement(TestFileName, 0L, 10),
+                };
+                byte[] expected = GetExpectedContent(elements);
+                SendPackets(type, elements, SocketError.Success, expected.Length, expected);
+            }
+        }
+
+        #endregion
+        
         #region Helpers
         private void SendPackets(SocketImplementationType type, SendPacketsElement element, TransmitFileOptions flags, int bytesExpected)
         {
@@ -540,6 +781,63 @@ namespace System.Net.Sockets.Tests
             handle.Set();
         }
 
+        /// <summary>
+        /// Recreate what SendPacketsAsync should send given the <paramref name="elements"/>,
+        /// directly by collating their buffers or reading from their files.
+        /// </summary>
+        /// <param name="elements"></param>
+        /// <returns></returns>
+        private byte[] GetExpectedContent(params SendPacketsElement[] elements) {
+
+            void ReadFromFile(string filePath, long offset, long count, byte[] destination, ref long destinationOffset) {
+                using (FileStream fs = new FileStream(filePath, FileMode.Open,FileAccess.Read, FileShare.Read)) {
+                    // Passing a zero count to SendPacketsElement means it sends the whole file.
+                    if (count == 0) {
+                        count = fs.Length;
+                    }
+                    fs.Position = offset;
+                    int actualRead = 0;
+                    do {
+                        actualRead += fs.Read(destination, (int) destinationOffset + actualRead, (int) count - actualRead);
+                    } while (actualRead != count && fs.Position < fs.Length);
+                    destinationOffset += actualRead;
+                }
+            }
+
+            int FileCount(SendPacketsElement element) {
+                if (element.Count != 0) return element.Count;
+                if (element.FilePath != null) {
+                    return (int) new FileInfo(element.FilePath).Length;
+                }
+                else if (element.FileStream != null) {
+                    return (int) element.FileStream.Length;
+                }
+                throw new ArgumentException("Expected SendPacketsElement with FilePath or FileStream set.", nameof(element));
+            }
+
+            int totalCount = 0;
+            foreach (var element in elements) {
+                totalCount += element.Buffer != null ? element.Count : FileCount(element);
+            }
+            var result = new byte[totalCount];
+            long resultOffset = 0L;
+            foreach (var spe in elements) {
+                if (spe.FilePath != null) {
+                    ReadFromFile(spe.FilePath, spe.OffsetLong, spe.Count, result, ref resultOffset);
+                }
+                else if (spe.FileStream != null) {
+                    ReadFromFile(spe.FileStream.Name, spe.OffsetLong, spe.Count, result, ref resultOffset);
+                }
+                else if (spe.Buffer != null && spe.Count > 0) {
+                    Array.Copy(spe.Buffer, spe.OffsetLong, result, resultOffset, spe.Count);
+                    resultOffset += spe.Count;
+                }
+            }
+
+            Assert.Equal(totalCount, resultOffset);
+            return result;
+        }
+
         #endregion Helpers
     }
 }
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.netcoreapp.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsAsync.netcoreapp.cs
deleted file mode 100644 (file)
index 9a18cf1..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-// 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.IO;
-using System.Runtime.InteropServices;
-using Xunit;
-
-namespace System.Net.Sockets.Tests
-{
-    public partial class SendPacketsAsync
-    {
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileZeroCount_OffsetLong_Success(SocketImplementationType type)
-        {
-            var element = new SendPacketsElement(TestFileName, 0L, 0);
-            SendPackets(type, element, s_testFileSize, GetExpectedContent(element));  // Whole File
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FilePart_OffsetLong_Success(SocketImplementationType type)
-        {
-            var element = new SendPacketsElement(TestFileName, 10L, 20);
-            SendPackets(type, element, 20, GetExpectedContent(element));
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileMultiPart_OffsetLong_Success(SocketImplementationType type)
-        {
-            var elements = new[]
-            {
-                new SendPacketsElement(TestFileName, 10L, 20),
-                new SendPacketsElement(TestFileName, 30L, 10),
-                new SendPacketsElement(TestFileName, 0L, 10),
-            };
-            SendPackets(type, elements, SocketError.Success, 40, GetExpectedContent(elements));
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileLargeOffset_OffsetLong_Throws(SocketImplementationType type)
-        {
-            // Length is validated on Send
-            SendPackets(type, new SendPacketsElement(TestFileName, (long)uint.MaxValue + 11000, 1), SocketError.InvalidArgument, 0);
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileLargeCount_OffsetLong_Throws(SocketImplementationType type)
-        {
-            // Length is validated on Send
-            SendPackets(type, new SendPacketsElement(TestFileName, 5L, 10000), SocketError.InvalidArgument, 0);
-        }
-
-        #region FileStreams
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStream_Success(SocketImplementationType type)
-        {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
-            {
-                stream.Seek(s_testFileSize / 2, SeekOrigin.Begin);
-                SendPackets(type, new SendPacketsElement(stream), s_testFileSize); // Whole File
-                Assert.Equal(s_testFileSize / 2, stream.Position);
-
-                SendPackets(type, new SendPacketsElement(stream), s_testFileSize); // Whole File
-                Assert.Equal(s_testFileSize / 2, stream.Position);
-            }
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStreamZeroCount_Success(SocketImplementationType type)
-        {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
-            {
-                stream.Seek(s_testFileSize / 2, SeekOrigin.Begin);
-                SendPackets(type, new SendPacketsElement(stream, 0, 0), s_testFileSize); // Whole File
-                Assert.Equal(s_testFileSize / 2, stream.Position);
-
-                SendPackets(type, new SendPacketsElement(stream, 0, 0), s_testFileSize); // Whole File
-                Assert.Equal(s_testFileSize / 2, stream.Position);
-            }
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStreamSizeCount_Success(SocketImplementationType type)
-        {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
-            {
-                stream.Seek(s_testFileSize / 2, SeekOrigin.Begin);
-                SendPackets(type, new SendPacketsElement(stream, 0, s_testFileSize), s_testFileSize); // Whole File
-                Assert.Equal(s_testFileSize / 2, stream.Position);
-
-                SendPackets(type, new SendPacketsElement(stream, 0, s_testFileSize), s_testFileSize); // Whole File
-                Assert.Equal(s_testFileSize / 2, stream.Position);
-            }
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStreamPart_Success(SocketImplementationType type)
-        {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
-            {
-                stream.Seek(s_testFileSize - 10, SeekOrigin.Begin);
-                SendPackets(type, new SendPacketsElement(stream, 0, 20), 20);
-                Assert.Equal(s_testFileSize - 10, stream.Position);
-
-                SendPackets(type, new SendPacketsElement(stream, 10, 20), 20);
-                Assert.Equal(s_testFileSize - 10, stream.Position);
-
-                SendPackets(type, new SendPacketsElement(stream, s_testFileSize - 20, 20), 20);
-                Assert.Equal(s_testFileSize - 10, stream.Position);
-            }
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStreamMultiPart_Success(SocketImplementationType type)
-        {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous))
-            {
-                var elements = new[]
-                {
-                    new SendPacketsElement(stream, 0, 20),
-                    new SendPacketsElement(stream, s_testFileSize - 10, 10),
-                    new SendPacketsElement(stream, 0, 10),
-                    new SendPacketsElement(stream, 10, 20),
-                    new SendPacketsElement(stream, 30, 10),
-                };
-                stream.Seek(s_testFileSize - 10, SeekOrigin.Begin);
-                SendPackets(type, elements, SocketError.Success, 70, GetExpectedContent(elements));
-                Assert.Equal(s_testFileSize - 10, stream.Position);
-
-                SendPackets(type, elements, SocketError.Success, 70, GetExpectedContent(elements));
-                Assert.Equal(s_testFileSize - 10, stream.Position);
-            }
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStreamLargeOffset_Throws(SocketImplementationType type)
-        {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
-            {
-                stream.Seek(s_testFileSize / 2, SeekOrigin.Begin);
-                // Length is validated on Send
-                SendPackets(type, new SendPacketsElement(stream, (long)uint.MaxValue + 11000, 1), SocketError.InvalidArgument, 0);
-            }
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStreamLargeCount_Throws(SocketImplementationType type)
-        {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: true))
-            {
-                stream.Seek(s_testFileSize / 2, SeekOrigin.Begin);
-                // Length is validated on Send
-                SendPackets(type, new SendPacketsElement(stream, 5, 10000),
-                    SocketError.InvalidArgument, 0);
-            }
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStreamWithOptions_Success(SocketImplementationType type) {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, 4096, FileOptions.Asynchronous | FileOptions.SequentialScan)) {
-                var element = new SendPacketsElement(stream, 0, s_testFileSize);
-                SendPackets(type, element, s_testFileSize, GetExpectedContent(element));
-            }
-        }
-
-        #endregion FileStreams
-
-        #region Mixed Buffer, FilePath, FileStream tests
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStreamMultiPartMixed_Success(SocketImplementationType type) {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) {
-                var elements = new[]
-                {
-                    new SendPacketsElement(new byte[] { 5, 6, 7 }, 0, 3),
-                    new SendPacketsElement(stream, s_testFileSize - 10, 10),
-                    new SendPacketsElement(TestFileName, 0L, 10),
-                    new SendPacketsElement(stream, 10L, 20),
-                    new SendPacketsElement(TestFileName, 30, 10),
-                    new SendPacketsElement(new byte[] { 8, 9, 10 }, 0, 3),
-                };
-                byte[] expected = GetExpectedContent(elements);
-                SendPackets(type, elements, SocketError.Success, expected.Length, expected);
-            }
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStreamMultiPartMixed_MultipleFileStreams_Success(SocketImplementationType type) {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous))
-            using (var stream2 = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) {
-                var elements = new[]
-                {
-                    new SendPacketsElement(new byte[] { 5, 6, 7 }, 0, 0),
-                    new SendPacketsElement(stream, s_testFileSize - 10, 10),
-                    new SendPacketsElement(stream2, s_testFileSize - 100, 10),
-                    new SendPacketsElement(TestFileName, 0L, 10),
-                    new SendPacketsElement(new byte[] { 8, 9, 10 }, 0, 1),
-                    new SendPacketsElement(TestFileName, 30, 10),
-                };
-                byte[] expected = GetExpectedContent(elements);
-                SendPackets(type, elements, SocketError.Success, expected.Length, expected);
-            }
-        }
-
-        [Theory]
-        [InlineData(SocketImplementationType.APM)]
-        [InlineData(SocketImplementationType.Async)]
-        public void SendPacketsElement_FileStreamMultiPartMixed_MultipleWholeFiles_Success(SocketImplementationType type) {
-            using (var stream = new FileStream(TestFileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous)) {
-                var elements = new[]
-                {
-                    new SendPacketsElement(stream, 0L, 0),
-                    new SendPacketsElement(TestFileName, 0L, 10),
-                    new SendPacketsElement(stream, 0L, 0),
-                    new SendPacketsElement(TestFileName, 0L, 10),
-                };
-                byte[] expected = GetExpectedContent(elements);
-                SendPackets(type, elements, SocketError.Success, expected.Length, expected);
-            }
-        }
-
-        #endregion
-
-        #region Helpers
-
-        /// <summary>
-        /// Recreate what SendPacketsAsync should send given the <paramref name="elements"/>,
-        /// directly by collating their buffers or reading from their files.
-        /// </summary>
-        /// <param name="elements"></param>
-        /// <returns></returns>
-        private byte[] GetExpectedContent(params SendPacketsElement[] elements) {
-
-            void ReadFromFile(string filePath, long offset, long count, byte[] destination, ref long destinationOffset) {
-                using (FileStream fs = new FileStream(filePath, FileMode.Open,FileAccess.Read, FileShare.Read)) {
-                    // Passing a zero count to SendPacketsElement means it sends the whole file.
-                    if (count == 0) {
-                        count = fs.Length;
-                    }
-                    fs.Position = offset;
-                    int actualRead = 0;
-                    do {
-                        actualRead += fs.Read(destination, (int) destinationOffset + actualRead, (int) count - actualRead);
-                    } while (actualRead != count && fs.Position < fs.Length);
-                    destinationOffset += actualRead;
-                }
-            }
-
-            int FileCount(SendPacketsElement element) {
-                if (element.Count != 0) return element.Count;
-                if (element.FilePath != null) {
-                    return (int) new FileInfo(element.FilePath).Length;
-                }
-                else if (element.FileStream != null) {
-                    return (int) element.FileStream.Length;
-                }
-                throw new ArgumentException("Expected SendPacketsElement with FilePath or FileStream set.", nameof(element));
-            }
-
-            int totalCount = 0;
-            foreach (var element in elements) {
-                totalCount += element.Buffer != null ? element.Count : FileCount(element);
-            }
-            var result = new byte[totalCount];
-            long resultOffset = 0L;
-            foreach (var spe in elements) {
-                if (spe.FilePath != null) {
-                    ReadFromFile(spe.FilePath, spe.OffsetLong, spe.Count, result, ref resultOffset);
-                }
-                else if (spe.FileStream != null) {
-                    ReadFromFile(spe.FileStream.Name, spe.OffsetLong, spe.Count, result, ref resultOffset);
-                }
-                else if (spe.Buffer != null && spe.Count > 0) {
-                    Array.Copy(spe.Buffer, spe.OffsetLong, result, resultOffset, spe.Count);
-                    resultOffset += spe.Count;
-                }
-            }
-
-            Assert.Equal(totalCount, resultOffset);
-            return result;
-        }
-
-        #endregion
-    }
-}
index bf31e35..647c102 100644 (file)
@@ -7,7 +7,7 @@ using Xunit;
 
 namespace System.Net.Sockets.Tests
 {
-    public partial class SendPacketsElementTest
+    public class SendPacketsElementTest
     {
         #region Buffer
 
@@ -137,6 +137,78 @@ namespace System.Net.Sockets.Tests
             Assert.Null(element.FilePath);
         }
 
+        [Fact]
+        public void EmptyBufferCtor_OffsetLong_FileStream_Success()
+        {
+            // Elements with empty Buffers are ignored on Send
+            SendPacketsElement element = new SendPacketsElement(new byte[0]);
+            Assert.NotNull(element.Buffer);
+            Assert.Equal(0, element.Buffer.Length);
+            Assert.Equal(0, element.Offset);
+            Assert.Equal(0, element.Count);
+            Assert.Equal(0, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Null(element.FilePath);
+            Assert.Null(element.FileStream);
+        }
+
+        [Fact]
+        public void BufferCtorNormal_OffsetLong_FileStream_Success()
+        {
+            SendPacketsElement element = new SendPacketsElement(new byte[10]);
+            Assert.NotNull(element.Buffer);
+            Assert.Equal(10, element.Buffer.Length);
+            Assert.Equal(0, element.Offset);
+            Assert.Equal(10, element.Count);
+            Assert.Equal(0, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Null(element.FilePath);
+            Assert.Null(element.FileStream);
+        }
+
+        [Fact]
+        public void BufferCtorEndOfBufferTrue_OffsetLong_FileStream_Success()
+        {
+            SendPacketsElement element = new SendPacketsElement(new byte[10], 2, 8, true);
+            Assert.NotNull(element.Buffer);
+            Assert.Equal(10, element.Buffer.Length);
+            Assert.Equal(2, element.Offset);
+            Assert.Equal(8, element.Count);
+            Assert.Equal(2, element.OffsetLong);
+            Assert.True(element.EndOfPacket);
+            Assert.Null(element.FilePath);
+            Assert.Null(element.FileStream);
+        }
+
+        [Fact]
+        public void BufferCtorEndOfBufferFalse_OffsetLong_FileStream_Success()
+        {
+            SendPacketsElement element = new SendPacketsElement(new byte[10], 6, 4, false);
+            Assert.NotNull(element.Buffer);
+            Assert.Equal(10, element.Buffer.Length);
+            Assert.Equal(6, element.Offset);
+            Assert.Equal(4, element.Count);
+            Assert.Equal(6, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Null(element.FilePath);
+            Assert.Null(element.FileStream);
+        }
+
+        [Fact]
+        public void BufferCtorZeroCount_OffsetLong_FileStream_Success()
+        {
+            // Elements with empty Buffers are ignored on Send
+            SendPacketsElement element = new SendPacketsElement(new byte[0], 0, 0);
+            Assert.NotNull(element.Buffer);
+            Assert.Equal(0, element.Buffer.Length);
+            Assert.Equal(0, element.Offset);
+            Assert.Equal(0, element.Count);
+            Assert.Equal(0, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Null(element.FilePath);
+            Assert.Null(element.FileStream);
+        }
+
         #endregion Buffer
 
         #region File
@@ -256,6 +328,362 @@ namespace System.Net.Sockets.Tests
             Assert.Equal("SomeFileName", element.FilePath);
         }
 
+        [Fact]
+        public void FileCtorNull_OffsetLong_Throws()
+        {
+            Assert.Throws<ArgumentNullException>(() =>
+            {
+                new SendPacketsElement((string)null, 0L, 0);
+            });
+            Assert.Throws<ArgumentNullException>(() =>
+            {
+                new SendPacketsElement((string)null, 0L, 0, true);
+            });
+        }
+
+        [Fact]
+        public void FileCtorEmpty_OffsetLong_Success()
+        {
+            // An exception will happen on send if this file doesn't exist
+            SendPacketsElement element = new SendPacketsElement(string.Empty);
+            Assert.Null(element.Buffer);
+            Assert.Equal(0, element.Offset);
+            Assert.Equal(0, element.Count);
+            Assert.Equal(0, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Equal(string.Empty, element.FilePath);
+        }
+
+        [Fact]
+        public void FileCtorNormal_OffsetLong_FileStream_Success()
+        {
+            // An exception will happen on send if this file doesn't exist
+            SendPacketsElement element = new SendPacketsElement("SomeFileName"); // Send whole file
+            Assert.Null(element.FileStream);
+            Assert.Null(element.Buffer);
+            Assert.Equal(0, element.Offset);
+            Assert.Equal(0, element.Count);
+            Assert.Equal(0, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Equal("SomeFileName", element.FilePath);
+        }
+
+        [Fact]
+        public void FileCtorZeroCountLength_OffsetLong_FileStream_Success()
+        {
+            // An exception will happen on send if this file doesn't exist
+            SendPacketsElement element = new SendPacketsElement("SomeFileName", 0, 0); // Send whole file
+            Assert.Null(element.FileStream);
+            Assert.Null(element.Buffer);
+            Assert.Equal(0, element.Offset);
+            Assert.Equal(0, element.Count);
+            Assert.Equal(0, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Equal("SomeFileName", element.FilePath);
+
+            // An exception will happen on send if this file doesn't exist
+            element = new SendPacketsElement("SomeFileName", 0L, 0); // Send whole file
+            Assert.Null(element.FileStream);
+            Assert.Null(element.Buffer);
+            Assert.Equal(0, element.Offset);
+            Assert.Equal(0, element.Count);
+            Assert.Equal(0, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Equal("SomeFileName", element.FilePath);
+        }
+
+        [Fact]
+        public void FileCtorNegOffset_OffsetLong_ArgumentOutOfRangeException()
+        {
+            Assert.Throws<ArgumentOutOfRangeException>(() =>
+            {
+                new SendPacketsElement("SomeFileName", -1L, 11);
+            });
+            Assert.Throws<ArgumentOutOfRangeException>(() =>
+            {
+                new SendPacketsElement("SomeFileName", -1L, 11, true);
+            });
+        }
+
+        [Fact]
+        public void FileCtorNegCount_OffsetLong_ArgumentOutOfRangeException()
+        {
+            Assert.Throws<ArgumentOutOfRangeException>(() =>
+            {
+                new SendPacketsElement("SomeFileName", 0L, -1);
+            });
+            Assert.Throws<ArgumentOutOfRangeException>(() =>
+            {
+                new SendPacketsElement("SomeFileName", 0L, -1, true);
+            });
+        }
+
+        [Fact]
+        public void FileCtorEndOfBufferTrue_OffsetLong_FileStream_Success()
+        {
+            SendPacketsElement element = new SendPacketsElement("SomeFileName", 2, 8, true);
+            Assert.Null(element.FileStream);
+            Assert.Null(element.Buffer);
+            Assert.Equal(2, element.Offset);
+            Assert.Equal(8, element.Count);
+            Assert.Equal(2, element.OffsetLong);
+            Assert.True(element.EndOfPacket);
+            Assert.Equal("SomeFileName", element.FilePath);
+
+            element = new SendPacketsElement("SomeFileName", 2L, 8, true);
+            Assert.Null(element.FileStream);
+            Assert.Null(element.Buffer);
+            Assert.Equal(2, element.Offset);
+            Assert.Equal(8, element.Count);
+            Assert.Equal(2, element.OffsetLong);
+            Assert.True(element.EndOfPacket);
+            Assert.Equal("SomeFileName", element.FilePath);
+
+            element = new SendPacketsElement("SomeFileName", (long)int.MaxValue + 2, 8, true);
+            Assert.Null(element.FileStream);
+            Assert.Null(element.Buffer);
+            Assert.Throws<OverflowException>(() =>
+            {
+                var ofset = element.Offset;
+            });
+            Assert.Equal(8, element.Count);
+            Assert.Equal((long)int.MaxValue + 2, element.OffsetLong);
+            Assert.True(element.EndOfPacket);
+            Assert.Equal("SomeFileName", element.FilePath);
+        }
+
+        [Fact]
+        public void FileCtorEndOfBufferFalse_OffsetLong_FileStream_Success()
+        {
+            SendPacketsElement element = new SendPacketsElement("SomeFileName", 6, 4, false);
+            Assert.Null(element.FileStream);
+            Assert.Null(element.Buffer);
+            Assert.Equal(6, element.Offset);
+            Assert.Equal(4, element.Count);
+            Assert.Equal(6, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Equal("SomeFileName", element.FilePath);
+
+            element = new SendPacketsElement("SomeFileName", 6L, 4, false);
+            Assert.Null(element.FileStream);
+            Assert.Null(element.Buffer);
+            Assert.Equal(6, element.Offset);
+            Assert.Equal(4, element.Count);
+            Assert.Equal(6, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Equal("SomeFileName", element.FilePath);
+
+            element = new SendPacketsElement("SomeFileName", (long)int.MaxValue + 6, 4, false);
+            Assert.Null(element.FileStream);
+            Assert.Null(element.Buffer);
+            Assert.Throws<OverflowException>(() =>
+            {
+                var ofset = element.Offset;
+            });
+            Assert.Equal(4, element.Count);
+            Assert.Equal((long)int.MaxValue + 6, element.OffsetLong);
+            Assert.False(element.EndOfPacket);
+            Assert.Equal("SomeFileName", element.FilePath);
+        }
+
         #endregion File
+
+        #region FileStream
+
+        [Fact]
+        public void FileStreamCtorNull_Throws()
+        {
+            Assert.Throws<ArgumentNullException>(() =>
+            {
+                new SendPacketsElement((FileStream)null);
+            });
+            Assert.Throws<ArgumentNullException>(() =>
+            {
+                new SendPacketsElement((FileStream)null, 0, 0);
+            });
+            Assert.Throws<ArgumentNullException>(() =>
+            {
+                new SendPacketsElement((FileStream)null, 0, 0, true);
+            });
+        }
+
+        [Fact]
+        public void FileStreamCtorNormal_Success()
+        {
+            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
+            {
+                SendPacketsElement element = new SendPacketsElement(stream);
+                Assert.Null(element.FilePath);
+                Assert.Equal(element.FileStream, stream);
+                Assert.Null(element.Buffer);
+                Assert.Equal(0, element.Offset);
+                Assert.Equal(0, element.Count);
+                Assert.Equal(0, element.OffsetLong);
+                Assert.False(element.EndOfPacket);
+            }
+        }
+
+        [Fact]
+        public void FileStreamCtorZeroCountLength_Success()
+        {
+            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
+            {
+                SendPacketsElement element = new SendPacketsElement(stream, 0, 0); // Send whole file
+                Assert.Null(element.FilePath);
+                Assert.Equal(element.FileStream, stream);
+                Assert.Null(element.Buffer);
+                Assert.Equal(0, element.Offset);
+                Assert.Equal(0, element.Count);
+                Assert.Equal(0, element.OffsetLong);
+                Assert.False(element.EndOfPacket);
+
+                element = new SendPacketsElement(stream, 0L, 0); // Send whole file
+                Assert.Null(element.FilePath);
+                Assert.Equal(element.FileStream, stream);
+                Assert.Null(element.Buffer);
+                Assert.Equal(0, element.Offset);
+                Assert.Equal(0, element.Count);
+                Assert.Equal(0, element.OffsetLong);
+                Assert.False(element.EndOfPacket);
+            }
+        }
+
+        [Fact]
+        public void FileStreamCtorNegOffset_ArgumentOutOfRangeException()
+        {
+            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
+            {
+                Assert.Throws<ArgumentOutOfRangeException>(() =>
+                {
+                    new SendPacketsElement(stream, -1, 11);
+                });
+                Assert.Throws<ArgumentOutOfRangeException>(() =>
+                {
+                    new SendPacketsElement(stream, -1, 11, true);
+                });
+                Assert.Throws<ArgumentOutOfRangeException>(() =>
+                {
+                    new SendPacketsElement(stream, -1L, 11);
+                });
+                Assert.Throws<ArgumentOutOfRangeException>(() =>
+                {
+                    new SendPacketsElement(stream, -1L, 11, true);
+                });
+            }
+        }
+
+        [Fact]
+        public void FileStreamCtorNegCount_ArgumentOutOfRangeException()
+        {
+            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
+            {
+                Assert.Throws<ArgumentOutOfRangeException>(() =>
+                {
+                    new SendPacketsElement(stream, 0, -1);
+                });
+                Assert.Throws<ArgumentOutOfRangeException>(() =>
+                {
+                    new SendPacketsElement(stream, 0, -1, true);
+                });
+                Assert.Throws<ArgumentOutOfRangeException>(() =>
+                {
+                    new SendPacketsElement(stream, 0L, -1);
+                });
+                Assert.Throws<ArgumentOutOfRangeException>(() =>
+                {
+                    new SendPacketsElement(stream, 0L, -1, true);
+                });
+            }
+        }
+
+        [Fact]
+        public void FileStreamCtorSynchronous_ArgumentException()
+        {
+            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose))
+            {
+                Assert.Throws<ArgumentException>(() =>
+                {
+                    new SendPacketsElement(stream, 0, 10);
+                });
+            }
+        }
+
+        // File lengths are validated on send
+
+        [Fact]
+        public void FileStreamCtorEndOfBufferTrue_Success()
+        {
+            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
+            {
+                var element = new SendPacketsElement(stream, 2, 8, true);
+                Assert.Null(element.FilePath);
+                Assert.Equal(element.FileStream, stream);
+                Assert.Null(element.Buffer);
+                Assert.Equal(2, element.Offset);
+                Assert.Equal(8, element.Count);
+                Assert.Equal(2, element.OffsetLong);
+                Assert.True(element.EndOfPacket);
+
+                element = new SendPacketsElement(stream, 2L, 8, true);
+                Assert.Null(element.FilePath);
+                Assert.Equal(element.FileStream, stream);
+                Assert.Null(element.Buffer);
+                Assert.Equal(2, element.Offset);
+                Assert.Equal(8, element.Count);
+                Assert.Equal(2, element.OffsetLong);
+                Assert.True(element.EndOfPacket);
+
+                element = new SendPacketsElement(stream, (long)int.MaxValue + 2, 8, true);
+                Assert.Null(element.FilePath);
+                Assert.Equal(element.FileStream, stream);
+                Assert.Null(element.Buffer);
+                Assert.Throws<OverflowException>(() =>
+                {
+                    var ofset = element.Offset;
+                });
+                Assert.Equal(8, element.Count);
+                Assert.Equal((long)int.MaxValue + 2, element.OffsetLong);
+                Assert.True(element.EndOfPacket);
+            }
+        }
+
+        [Fact]
+        public void FileStreamCtorEndOfBufferFalse_Success()
+        {
+            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
+            {
+                SendPacketsElement element = new SendPacketsElement(stream, 6, 4, false);
+                Assert.Null(element.FilePath);
+                Assert.Equal(element.FileStream, stream);
+                Assert.Null(element.Buffer);
+                Assert.Equal(6, element.Offset);
+                Assert.Equal(4, element.Count);
+                Assert.Equal(6, element.OffsetLong);
+                Assert.False(element.EndOfPacket);
+
+                element = new SendPacketsElement(stream, 6L, 4, false);
+                Assert.Null(element.FilePath);
+                Assert.Equal(element.FileStream, stream);
+                Assert.Null(element.Buffer);
+                Assert.Equal(6, element.Offset);
+                Assert.Equal(4, element.Count);
+                Assert.Equal(6, element.OffsetLong);
+                Assert.False(element.EndOfPacket);
+
+                element = new SendPacketsElement(stream, (long)int.MaxValue + 6, 4, false);
+                Assert.Null(element.FilePath);
+                Assert.Equal(element.FileStream, stream);
+                Assert.Null(element.Buffer);
+                Assert.Throws<OverflowException>(() =>
+                {
+                    var ofset = element.Offset;
+                });
+                Assert.Equal(4, element.Count);
+                Assert.Equal((long)int.MaxValue + 6, element.OffsetLong);
+                Assert.False(element.EndOfPacket);
+            }
+        }
+
+        #endregion FileStream
     }
 }
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsElementTest.netcoreapp.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendPacketsElementTest.netcoreapp.cs
deleted file mode 100644 (file)
index 90b7208..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-// 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.IO;
-using Xunit;
-
-namespace System.Net.Sockets.Tests
-{
-    public partial class SendPacketsElementTest
-    {
-        [Fact]
-        public void EmptyBufferCtor_OffsetLong_FileStream_Success()
-        {
-            // Elements with empty Buffers are ignored on Send
-            SendPacketsElement element = new SendPacketsElement(new byte[0]);
-            Assert.NotNull(element.Buffer);
-            Assert.Equal(0, element.Buffer.Length);
-            Assert.Equal(0, element.Offset);
-            Assert.Equal(0, element.Count);
-            Assert.Equal(0, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Null(element.FilePath);
-            Assert.Null(element.FileStream);
-        }
-
-        [Fact]
-        public void BufferCtorNormal_OffsetLong_FileStream_Success()
-        {
-            SendPacketsElement element = new SendPacketsElement(new byte[10]);
-            Assert.NotNull(element.Buffer);
-            Assert.Equal(10, element.Buffer.Length);
-            Assert.Equal(0, element.Offset);
-            Assert.Equal(10, element.Count);
-            Assert.Equal(0, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Null(element.FilePath);
-            Assert.Null(element.FileStream);
-        }
-
-        [Fact]
-        public void BufferCtorEndOfBufferTrue_OffsetLong_FileStream_Success()
-        {
-            SendPacketsElement element = new SendPacketsElement(new byte[10], 2, 8, true);
-            Assert.NotNull(element.Buffer);
-            Assert.Equal(10, element.Buffer.Length);
-            Assert.Equal(2, element.Offset);
-            Assert.Equal(8, element.Count);
-            Assert.Equal(2, element.OffsetLong);
-            Assert.True(element.EndOfPacket);
-            Assert.Null(element.FilePath);
-            Assert.Null(element.FileStream);
-        }
-
-        [Fact]
-        public void BufferCtorEndOfBufferFalse_OffsetLong_FileStream_Success()
-        {
-            SendPacketsElement element = new SendPacketsElement(new byte[10], 6, 4, false);
-            Assert.NotNull(element.Buffer);
-            Assert.Equal(10, element.Buffer.Length);
-            Assert.Equal(6, element.Offset);
-            Assert.Equal(4, element.Count);
-            Assert.Equal(6, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Null(element.FilePath);
-            Assert.Null(element.FileStream);
-        }
-
-        [Fact]
-        public void BufferCtorZeroCount_OffsetLong_FileStream_Success()
-        {
-            // Elements with empty Buffers are ignored on Send
-            SendPacketsElement element = new SendPacketsElement(new byte[0], 0, 0);
-            Assert.NotNull(element.Buffer);
-            Assert.Equal(0, element.Buffer.Length);
-            Assert.Equal(0, element.Offset);
-            Assert.Equal(0, element.Count);
-            Assert.Equal(0, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Null(element.FilePath);
-            Assert.Null(element.FileStream);
-        }
-
-        [Fact]
-        public void FileCtorNull_OffsetLong_Throws()
-        {
-            Assert.Throws<ArgumentNullException>(() =>
-            {
-                new SendPacketsElement((string)null, 0L, 0);
-            });
-            Assert.Throws<ArgumentNullException>(() =>
-            {
-                new SendPacketsElement((string)null, 0L, 0, true);
-            });
-        }
-
-        [Fact]
-        public void FileCtorEmpty_OffsetLong_Success()
-        {
-            // An exception will happen on send if this file doesn't exist
-            SendPacketsElement element = new SendPacketsElement(string.Empty);
-            Assert.Null(element.Buffer);
-            Assert.Equal(0, element.Offset);
-            Assert.Equal(0, element.Count);
-            Assert.Equal(0, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Equal(string.Empty, element.FilePath);
-        }
-
-        [Fact]
-        public void FileCtorNormal_OffsetLong_FileStream_Success()
-        {
-            // An exception will happen on send if this file doesn't exist
-            SendPacketsElement element = new SendPacketsElement("SomeFileName"); // Send whole file
-            Assert.Null(element.FileStream);
-            Assert.Null(element.Buffer);
-            Assert.Equal(0, element.Offset);
-            Assert.Equal(0, element.Count);
-            Assert.Equal(0, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Equal("SomeFileName", element.FilePath);
-        }
-
-        [Fact]
-        public void FileCtorZeroCountLength_OffsetLong_FileStream_Success()
-        {
-            // An exception will happen on send if this file doesn't exist
-            SendPacketsElement element = new SendPacketsElement("SomeFileName", 0, 0); // Send whole file
-            Assert.Null(element.FileStream);
-            Assert.Null(element.Buffer);
-            Assert.Equal(0, element.Offset);
-            Assert.Equal(0, element.Count);
-            Assert.Equal(0, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Equal("SomeFileName", element.FilePath);
-
-            // An exception will happen on send if this file doesn't exist
-            element = new SendPacketsElement("SomeFileName", 0L, 0); // Send whole file
-            Assert.Null(element.FileStream);
-            Assert.Null(element.Buffer);
-            Assert.Equal(0, element.Offset);
-            Assert.Equal(0, element.Count);
-            Assert.Equal(0, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Equal("SomeFileName", element.FilePath);
-        }
-
-        [Fact]
-        public void FileCtorNegOffset_OffsetLong_ArgumentOutOfRangeException()
-        {
-            Assert.Throws<ArgumentOutOfRangeException>(() =>
-            {
-                new SendPacketsElement("SomeFileName", -1L, 11);
-            });
-            Assert.Throws<ArgumentOutOfRangeException>(() =>
-            {
-                new SendPacketsElement("SomeFileName", -1L, 11, true);
-            });
-        }
-
-        [Fact]
-        public void FileCtorNegCount_OffsetLong_ArgumentOutOfRangeException()
-        {
-            Assert.Throws<ArgumentOutOfRangeException>(() =>
-            {
-                new SendPacketsElement("SomeFileName", 0L, -1);
-            });
-            Assert.Throws<ArgumentOutOfRangeException>(() =>
-            {
-                new SendPacketsElement("SomeFileName", 0L, -1, true);
-            });
-        }
-
-        [Fact]
-        public void FileCtorEndOfBufferTrue_OffsetLong_FileStream_Success()
-        {
-            SendPacketsElement element = new SendPacketsElement("SomeFileName", 2, 8, true);
-            Assert.Null(element.FileStream);
-            Assert.Null(element.Buffer);
-            Assert.Equal(2, element.Offset);
-            Assert.Equal(8, element.Count);
-            Assert.Equal(2, element.OffsetLong);
-            Assert.True(element.EndOfPacket);
-            Assert.Equal("SomeFileName", element.FilePath);
-
-            element = new SendPacketsElement("SomeFileName", 2L, 8, true);
-            Assert.Null(element.FileStream);
-            Assert.Null(element.Buffer);
-            Assert.Equal(2, element.Offset);
-            Assert.Equal(8, element.Count);
-            Assert.Equal(2, element.OffsetLong);
-            Assert.True(element.EndOfPacket);
-            Assert.Equal("SomeFileName", element.FilePath);
-
-            element = new SendPacketsElement("SomeFileName", (long)int.MaxValue + 2, 8, true);
-            Assert.Null(element.FileStream);
-            Assert.Null(element.Buffer);
-            Assert.Throws<OverflowException>(() =>
-            {
-                var ofset = element.Offset;
-            });
-            Assert.Equal(8, element.Count);
-            Assert.Equal((long)int.MaxValue + 2, element.OffsetLong);
-            Assert.True(element.EndOfPacket);
-            Assert.Equal("SomeFileName", element.FilePath);
-        }
-
-        [Fact]
-        public void FileCtorEndOfBufferFalse_OffsetLong_FileStream_Success()
-        {
-            SendPacketsElement element = new SendPacketsElement("SomeFileName", 6, 4, false);
-            Assert.Null(element.FileStream);
-            Assert.Null(element.Buffer);
-            Assert.Equal(6, element.Offset);
-            Assert.Equal(4, element.Count);
-            Assert.Equal(6, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Equal("SomeFileName", element.FilePath);
-
-            element = new SendPacketsElement("SomeFileName", 6L, 4, false);
-            Assert.Null(element.FileStream);
-            Assert.Null(element.Buffer);
-            Assert.Equal(6, element.Offset);
-            Assert.Equal(4, element.Count);
-            Assert.Equal(6, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Equal("SomeFileName", element.FilePath);
-
-            element = new SendPacketsElement("SomeFileName", (long)int.MaxValue + 6, 4, false);
-            Assert.Null(element.FileStream);
-            Assert.Null(element.Buffer);
-            Assert.Throws<OverflowException>(() =>
-            {
-                var ofset = element.Offset;
-            });
-            Assert.Equal(4, element.Count);
-            Assert.Equal((long)int.MaxValue + 6, element.OffsetLong);
-            Assert.False(element.EndOfPacket);
-            Assert.Equal("SomeFileName", element.FilePath);
-        }
-
-        #region FileStream
-
-        [Fact]
-        public void FileStreamCtorNull_Throws()
-        {
-            Assert.Throws<ArgumentNullException>(() =>
-            {
-                new SendPacketsElement((FileStream)null);
-            });
-            Assert.Throws<ArgumentNullException>(() =>
-            {
-                new SendPacketsElement((FileStream)null, 0, 0);
-            });
-            Assert.Throws<ArgumentNullException>(() =>
-            {
-                new SendPacketsElement((FileStream)null, 0, 0, true);
-            });
-        }
-
-        [Fact]
-        public void FileStreamCtorNormal_Success()
-        {
-            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
-            {
-                SendPacketsElement element = new SendPacketsElement(stream);
-                Assert.Null(element.FilePath);
-                Assert.Equal(element.FileStream, stream);
-                Assert.Null(element.Buffer);
-                Assert.Equal(0, element.Offset);
-                Assert.Equal(0, element.Count);
-                Assert.Equal(0, element.OffsetLong);
-                Assert.False(element.EndOfPacket);
-            }
-        }
-
-        [Fact]
-        public void FileStreamCtorZeroCountLength_Success()
-        {
-            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
-            {
-                SendPacketsElement element = new SendPacketsElement(stream, 0, 0); // Send whole file
-                Assert.Null(element.FilePath);
-                Assert.Equal(element.FileStream, stream);
-                Assert.Null(element.Buffer);
-                Assert.Equal(0, element.Offset);
-                Assert.Equal(0, element.Count);
-                Assert.Equal(0, element.OffsetLong);
-                Assert.False(element.EndOfPacket);
-
-                element = new SendPacketsElement(stream, 0L, 0); // Send whole file
-                Assert.Null(element.FilePath);
-                Assert.Equal(element.FileStream, stream);
-                Assert.Null(element.Buffer);
-                Assert.Equal(0, element.Offset);
-                Assert.Equal(0, element.Count);
-                Assert.Equal(0, element.OffsetLong);
-                Assert.False(element.EndOfPacket);
-            }
-        }
-
-        [Fact]
-        public void FileStreamCtorNegOffset_ArgumentOutOfRangeException()
-        {
-            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
-            {
-                Assert.Throws<ArgumentOutOfRangeException>(() =>
-                {
-                    new SendPacketsElement(stream, -1, 11);
-                });
-                Assert.Throws<ArgumentOutOfRangeException>(() =>
-                {
-                    new SendPacketsElement(stream, -1, 11, true);
-                });
-                Assert.Throws<ArgumentOutOfRangeException>(() =>
-                {
-                    new SendPacketsElement(stream, -1L, 11);
-                });
-                Assert.Throws<ArgumentOutOfRangeException>(() =>
-                {
-                    new SendPacketsElement(stream, -1L, 11, true);
-                });
-            }
-        }
-
-        [Fact]
-        public void FileStreamCtorNegCount_ArgumentOutOfRangeException()
-        {
-            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
-            {
-                Assert.Throws<ArgumentOutOfRangeException>(() =>
-                {
-                    new SendPacketsElement(stream, 0, -1);
-                });
-                Assert.Throws<ArgumentOutOfRangeException>(() =>
-                {
-                    new SendPacketsElement(stream, 0, -1, true);
-                });
-                Assert.Throws<ArgumentOutOfRangeException>(() =>
-                {
-                    new SendPacketsElement(stream, 0L, -1);
-                });
-                Assert.Throws<ArgumentOutOfRangeException>(() =>
-                {
-                    new SendPacketsElement(stream, 0L, -1, true);
-                });
-            }
-        }
-
-        [Fact]
-        public void FileStreamCtorSynchronous_ArgumentException()
-        {
-            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose))
-            {
-                Assert.Throws<ArgumentException>(() =>
-                {
-                    new SendPacketsElement(stream, 0, 10);
-                });
-            }
-        }
-
-        // File lengths are validated on send
-
-        [Fact]
-        public void FileStreamCtorEndOfBufferTrue_Success()
-        {
-            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
-            {
-                var element = new SendPacketsElement(stream, 2, 8, true);
-                Assert.Null(element.FilePath);
-                Assert.Equal(element.FileStream, stream);
-                Assert.Null(element.Buffer);
-                Assert.Equal(2, element.Offset);
-                Assert.Equal(8, element.Count);
-                Assert.Equal(2, element.OffsetLong);
-                Assert.True(element.EndOfPacket);
-
-                element = new SendPacketsElement(stream, 2L, 8, true);
-                Assert.Null(element.FilePath);
-                Assert.Equal(element.FileStream, stream);
-                Assert.Null(element.Buffer);
-                Assert.Equal(2, element.Offset);
-                Assert.Equal(8, element.Count);
-                Assert.Equal(2, element.OffsetLong);
-                Assert.True(element.EndOfPacket);
-
-                element = new SendPacketsElement(stream, (long)int.MaxValue + 2, 8, true);
-                Assert.Null(element.FilePath);
-                Assert.Equal(element.FileStream, stream);
-                Assert.Null(element.Buffer);
-                Assert.Throws<OverflowException>(() =>
-                {
-                    var ofset = element.Offset;
-                });
-                Assert.Equal(8, element.Count);
-                Assert.Equal((long)int.MaxValue + 2, element.OffsetLong);
-                Assert.True(element.EndOfPacket);
-            }
-        }
-
-        [Fact]
-        public void FileStreamCtorEndOfBufferFalse_Success()
-        {
-            using (var stream = File.Create(Path.GetTempFileName(), 4096, FileOptions.DeleteOnClose | FileOptions.Asynchronous))
-            {
-                SendPacketsElement element = new SendPacketsElement(stream, 6, 4, false);
-                Assert.Null(element.FilePath);
-                Assert.Equal(element.FileStream, stream);
-                Assert.Null(element.Buffer);
-                Assert.Equal(6, element.Offset);
-                Assert.Equal(4, element.Count);
-                Assert.Equal(6, element.OffsetLong);
-                Assert.False(element.EndOfPacket);
-
-                element = new SendPacketsElement(stream, 6L, 4, false);
-                Assert.Null(element.FilePath);
-                Assert.Equal(element.FileStream, stream);
-                Assert.Null(element.Buffer);
-                Assert.Equal(6, element.Offset);
-                Assert.Equal(4, element.Count);
-                Assert.Equal(6, element.OffsetLong);
-                Assert.False(element.EndOfPacket);
-
-                element = new SendPacketsElement(stream, (long)int.MaxValue + 6, 4, false);
-                Assert.Null(element.FilePath);
-                Assert.Equal(element.FileStream, stream);
-                Assert.Null(element.Buffer);
-                Assert.Throws<OverflowException>(() =>
-                {
-                    var ofset = element.Offset;
-                });
-                Assert.Equal(4, element.Count);
-                Assert.Equal((long)int.MaxValue + 6, element.OffsetLong);
-                Assert.False(element.EndOfPacket);
-            }
-        }
-
-        #endregion FileStream
-
-    }
-}
index 999b0cc..782c5a4 100644 (file)
@@ -1649,4 +1649,132 @@ namespace System.Net.Sockets.Tests
     {
         public SendReceiveEap(ITestOutputHelper output) : base(output) {}
     }
+
+    public sealed class SendReceiveSpanSync : SendReceive<SocketHelperSpanSync>
+    {
+        public SendReceiveSpanSync(ITestOutputHelper output) : base(output) { }
+    }
+
+    public sealed class SendReceiveSpanSyncForceNonBlocking : SendReceive<SocketHelperSpanSyncForceNonBlocking>
+    {
+        public SendReceiveSpanSyncForceNonBlocking(ITestOutputHelper output) : base(output) { }
+    }
+
+    public sealed class SendReceiveMemoryArrayTask : SendReceive<SocketHelperMemoryArrayTask>
+    {
+        public SendReceiveMemoryArrayTask(ITestOutputHelper output) : base(output) { }
+
+        [Fact]
+        public async Task Precanceled_Throws()
+        {
+            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            {
+                listener.BindToAnonymousPort(IPAddress.Loopback);
+                listener.Listen(1);
+
+                await client.ConnectAsync(listener.LocalEndPoint);
+                using (Socket server = await listener.AcceptAsync())
+                {
+                    var cts = new CancellationTokenSource();
+                    cts.Cancel();
+
+                    await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.SendAsync((ReadOnlyMemory<byte>)new byte[0], SocketFlags.None, cts.Token));
+                    await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.ReceiveAsync((Memory<byte>)new byte[0], SocketFlags.None, cts.Token));
+                }
+            }
+        }
+
+        [Fact]
+        public async Task CanceledDuringOperation_Throws()
+        {
+            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            {
+                listener.BindToAnonymousPort(IPAddress.Loopback);
+                listener.Listen(1);
+
+                await client.ConnectAsync(listener.LocalEndPoint);
+                using (Socket server = await listener.AcceptAsync())
+                {
+                    CancellationTokenSource cts;
+
+                    for (int len = 0; len < 2; len++)
+                    {
+                        cts = new CancellationTokenSource();
+                        ValueTask<int> vt = server.ReceiveAsync((Memory<byte>)new byte[len], SocketFlags.None, cts.Token);
+                        Assert.False(vt.IsCompleted);
+                        cts.Cancel();
+                        await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await vt);
+                    }
+
+                    // Make sure subsequent operations aren't canceled.
+                    await server.SendAsync((ReadOnlyMemory<byte>)new byte[1], SocketFlags.None);
+                    Assert.Equal(1, await client.ReceiveAsync((Memory<byte>)new byte[10], SocketFlags.None));
+                }
+            }
+        }
+
+        [Fact]
+        public async Task CanceledOneOfMultipleReceives_Udp_Throws()
+        {
+            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
+            {
+                client.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+
+                var cts = new CancellationTokenSource();
+
+                // Create three UDP receives, only one of which we'll cancel.
+                byte[] buffer1 = new byte[1], buffer2 = new byte[1], buffer3 = new byte[1];
+                ValueTask<int> r1 = client.ReceiveAsync(buffer1.AsMemory(), SocketFlags.None, cts.Token);
+                ValueTask<int> r2 = client.ReceiveAsync(buffer2.AsMemory(), SocketFlags.None);
+                ValueTask<int> r3 = client.ReceiveAsync(buffer3.AsMemory(), SocketFlags.None);
+
+                // Cancel one of them, and validate it's been canceled.
+                cts.Cancel();
+                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await r1);
+                Assert.Equal(0, buffer1[0]);
+
+                // Send data to complete the others, and validate they complete successfully.
+                using (var server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
+                {
+                    server.SendTo(new byte[1] { 42 }, client.LocalEndPoint);
+                    server.SendTo(new byte[1] { 43 }, client.LocalEndPoint);
+                }
+
+                Assert.Equal(1, await r2);
+                Assert.Equal(1, await r3);
+                Assert.True(
+                    (buffer2[0] == 42 && buffer3[0] == 43) ||
+                    (buffer2[0] == 43 && buffer3[0] == 42),
+                    $"buffer2[0]={buffer2[0]}, buffer3[0]={buffer3[0]}");
+            }
+        }
+
+        [Fact]
+        public async Task DisposedSocket_ThrowsOperationCanceledException()
+        {
+            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+            {
+                listener.BindToAnonymousPort(IPAddress.Loopback);
+                listener.Listen(1);
+
+                await client.ConnectAsync(listener.LocalEndPoint);
+                using (Socket server = await listener.AcceptAsync())
+                {
+                    var cts = new CancellationTokenSource();
+                    cts.Cancel();
+
+                    server.Shutdown(SocketShutdown.Both);
+                    await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.SendAsync((ReadOnlyMemory<byte>)new byte[0], SocketFlags.None, cts.Token));
+                    await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.ReceiveAsync((Memory<byte>)new byte[0], SocketFlags.None, cts.Token));
+                }
+            }
+        }
+    }
+    public sealed class SendReceiveMemoryNativeTask : SendReceive<SocketHelperMemoryNativeTask>
+    {
+        public SendReceiveMemoryNativeTask(ITestOutputHelper output) : base(output) { }
+    }
 }
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive.netcoreapp.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SendReceive.netcoreapp.cs
deleted file mode 100644 (file)
index c243558..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-// 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.Threading;
-using System.Threading.Tasks;
-using Xunit;
-using Xunit.Abstractions;
-
-namespace System.Net.Sockets.Tests
-{
-    public sealed class SendReceiveSpanSync : SendReceive<SocketHelperSpanSync>
-    {
-        public SendReceiveSpanSync(ITestOutputHelper output) : base(output) { }
-    }
-
-    public sealed class SendReceiveSpanSyncForceNonBlocking : SendReceive<SocketHelperSpanSyncForceNonBlocking>
-    {
-        public SendReceiveSpanSyncForceNonBlocking(ITestOutputHelper output) : base(output) { }
-    }
-
-    public sealed class SendReceiveMemoryArrayTask : SendReceive<SocketHelperMemoryArrayTask>
-    {
-        public SendReceiveMemoryArrayTask(ITestOutputHelper output) : base(output) { }
-
-        [Fact]
-        public async Task Precanceled_Throws()
-        {
-            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            {
-                listener.BindToAnonymousPort(IPAddress.Loopback);
-                listener.Listen(1);
-
-                await client.ConnectAsync(listener.LocalEndPoint);
-                using (Socket server = await listener.AcceptAsync())
-                {
-                    var cts = new CancellationTokenSource();
-                    cts.Cancel();
-
-                    await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.SendAsync((ReadOnlyMemory<byte>)new byte[0], SocketFlags.None, cts.Token));
-                    await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.ReceiveAsync((Memory<byte>)new byte[0], SocketFlags.None, cts.Token));
-                }
-            }
-        }
-
-        [Fact]
-        public async Task CanceledDuringOperation_Throws()
-        {
-            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            {
-                listener.BindToAnonymousPort(IPAddress.Loopback);
-                listener.Listen(1);
-
-                await client.ConnectAsync(listener.LocalEndPoint);
-                using (Socket server = await listener.AcceptAsync())
-                {
-                    CancellationTokenSource cts;
-
-                    for (int len = 0; len < 2; len++)
-                    {
-                        cts = new CancellationTokenSource();
-                        ValueTask<int> vt = server.ReceiveAsync((Memory<byte>)new byte[len], SocketFlags.None, cts.Token);
-                        Assert.False(vt.IsCompleted);
-                        cts.Cancel();
-                        await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await vt);
-                    }
-
-                    // Make sure subsequent operations aren't canceled.
-                    await server.SendAsync((ReadOnlyMemory<byte>)new byte[1], SocketFlags.None);
-                    Assert.Equal(1, await client.ReceiveAsync((Memory<byte>)new byte[10], SocketFlags.None));
-                }
-            }
-        }
-
-        [Fact]
-        public async Task CanceledOneOfMultipleReceives_Udp_Throws()
-        {
-            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
-            {
-                client.Bind(new IPEndPoint(IPAddress.Loopback, 0));
-
-                var cts = new CancellationTokenSource();
-
-                // Create three UDP receives, only one of which we'll cancel.
-                byte[] buffer1 = new byte[1], buffer2 = new byte[1], buffer3 = new byte[1];
-                ValueTask<int> r1 = client.ReceiveAsync(buffer1.AsMemory(), SocketFlags.None, cts.Token);
-                ValueTask<int> r2 = client.ReceiveAsync(buffer2.AsMemory(), SocketFlags.None);
-                ValueTask<int> r3 = client.ReceiveAsync(buffer3.AsMemory(), SocketFlags.None);
-
-                // Cancel one of them, and validate it's been canceled.
-                cts.Cancel();
-                await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await r1);
-                Assert.Equal(0, buffer1[0]);
-
-                // Send data to complete the others, and validate they complete successfully.
-                using (var server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
-                {
-                    server.SendTo(new byte[1] { 42 }, client.LocalEndPoint);
-                    server.SendTo(new byte[1] { 43 }, client.LocalEndPoint);
-                }
-
-                Assert.Equal(1, await r2);
-                Assert.Equal(1, await r3);
-                Assert.True(
-                    (buffer2[0] == 42 && buffer3[0] == 43) ||
-                    (buffer2[0] == 43 && buffer3[0] == 42),
-                    $"buffer2[0]={buffer2[0]}, buffer3[0]={buffer3[0]}");
-            }
-        }
-
-        [Fact]
-        public async Task DisposedSocket_ThrowsOperationCanceledException()
-        {
-            using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-            {
-                listener.BindToAnonymousPort(IPAddress.Loopback);
-                listener.Listen(1);
-
-                await client.ConnectAsync(listener.LocalEndPoint);
-                using (Socket server = await listener.AcceptAsync())
-                {
-                    var cts = new CancellationTokenSource();
-                    cts.Cancel();
-
-                    server.Shutdown(SocketShutdown.Both);
-                    await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.SendAsync((ReadOnlyMemory<byte>)new byte[0], SocketFlags.None, cts.Token));
-                    await Assert.ThrowsAnyAsync<OperationCanceledException>(async () => await server.ReceiveAsync((Memory<byte>)new byte[0], SocketFlags.None, cts.Token));
-                }
-            }
-        }
-    }
-    public sealed class SendReceiveMemoryNativeTask : SendReceive<SocketHelperMemoryNativeTask>
-    {
-        public SendReceiveMemoryNativeTask(ITestOutputHelper output) : base(output) { }
-    }
-}
index e3cd52d..6377e26 100644 (file)
@@ -2,15 +2,19 @@
 // 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.Buffers;
 using System.Collections.Generic;
+using System.Linq;
 using System.Net.Test.Common;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
 using System.Threading;
 using System.Threading.Tasks;
 using Xunit;
 
 namespace System.Net.Sockets.Tests
 {
-    public partial class SocketAsyncEventArgsTest
+    public class SocketAsyncEventArgsTest
     {
         [Fact]
         public void Usertoken_Roundtrips()
@@ -616,5 +620,236 @@ namespace System.Net.Sockets.Tests
                 (await acceptTask).Dispose();
             }
         }
+
+        [Fact]
+        public void SetBuffer_MemoryBuffer_Roundtrips()
+        {
+            using (var saea = new SocketAsyncEventArgs())
+            {
+                Memory<byte> memory = new byte[42];
+                saea.SetBuffer(memory);
+                Assert.True(memory.Equals(saea.MemoryBuffer));
+                Assert.Equal(0, saea.Offset);
+                Assert.Equal(memory.Length, saea.Count);
+                Assert.Null(saea.Buffer);
+            }
+        }
+
+        [Fact]
+        public void SetBufferMemory_ThenSetBufferIntInt_Throws()
+        {
+            using (var saea = new SocketAsyncEventArgs())
+            {
+                Memory<byte> memory = new byte[42];
+                saea.SetBuffer(memory);
+                Assert.Throws<InvalidOperationException>(() => saea.SetBuffer(0, 42));
+                Assert.Throws<InvalidOperationException>(() => saea.SetBuffer(0, 0));
+                Assert.Throws<InvalidOperationException>(() => saea.SetBuffer(1, 2));
+                Assert.True(memory.Equals(saea.MemoryBuffer));
+                Assert.Equal(0, saea.Offset);
+                Assert.Equal(memory.Length, saea.Count);
+            }
+        }
+
+        [Fact]
+        public void SetBufferArrayIntInt_AvailableFromMemoryBuffer()
+        {
+            using (var saea = new SocketAsyncEventArgs())
+            {
+                byte[] array = new byte[42];
+
+                saea.SetBuffer(array, 0, array.Length);
+                Assert.True(MemoryMarshal.TryGetArray(saea.MemoryBuffer, out ArraySegment<byte> result));
+                Assert.Same(array, result.Array);
+                Assert.Same(saea.Buffer, array);
+                Assert.Equal(0, result.Offset);
+                Assert.Equal(array.Length, result.Count);
+
+                saea.SetBuffer(1, 2);
+                Assert.Same(saea.Buffer, array);
+                Assert.Equal(1, saea.Offset);
+                Assert.Equal(2, saea.Count);
+
+                Assert.True(MemoryMarshal.TryGetArray(saea.MemoryBuffer, out result));
+                Assert.Same(array, result.Array);
+                Assert.Equal(0, result.Offset);
+                Assert.Equal(array.Length, result.Count);
+            }
+        }
+
+        [Fact]
+        public void SetBufferMemory_Default_ResetsCountOffset()
+        {
+            using (var saea = new SocketAsyncEventArgs())
+            {
+                saea.SetBuffer(42, 84);
+                Assert.Equal(0, saea.Offset);
+                Assert.Equal(0, saea.Count);
+
+                saea.SetBuffer(new byte[3], 1, 2);
+                Assert.Equal(1, saea.Offset);
+                Assert.Equal(2, saea.Count);
+
+                saea.SetBuffer(Memory<byte>.Empty);
+                Assert.Null(saea.Buffer);
+                Assert.Equal(0, saea.Offset);
+                Assert.Equal(0, saea.Count);
+            }
+        }
+
+        [Fact]
+        public void SetBufferListWhenMemoryBufferSet_Throws()
+        {
+            using (var saea = new SocketAsyncEventArgs())
+            {
+                var bufferList = new List<ArraySegment<byte>> { new ArraySegment<byte>(new byte[1]) };
+                Memory<byte> buffer = new byte[1];
+
+                saea.SetBuffer(buffer);
+                AssertExtensions.Throws<ArgumentException>(null, () => saea.BufferList = bufferList);
+                Assert.True(buffer.Equals(saea.MemoryBuffer));
+                Assert.Equal(0, saea.Offset);
+                Assert.Equal(buffer.Length, saea.Count);
+                Assert.Null(saea.BufferList);
+
+                saea.SetBuffer(Memory<byte>.Empty);
+                saea.BufferList = bufferList; // works fine when Buffer has been set back to null
+            }
+        }
+
+        [Fact]
+        public void SetBufferMemoryWhenBufferListSet_Throws()
+        {
+            using (var saea = new SocketAsyncEventArgs())
+            {
+                var bufferList = new List<ArraySegment<byte>> { new ArraySegment<byte>(new byte[1]) };
+                saea.BufferList = bufferList;
+
+                saea.SetBuffer(Memory<byte>.Empty); // nop
+
+                Memory<byte> buffer = new byte[2];
+                AssertExtensions.Throws<ArgumentException>(null, () => saea.SetBuffer(buffer));
+                Assert.Same(bufferList, saea.BufferList);
+                Assert.Null(saea.Buffer);
+                Assert.True(saea.MemoryBuffer.Equals(default));
+
+                saea.BufferList = null;
+                saea.SetBuffer(buffer); // works fine when BufferList has been set back to null
+            }
+        }
+
+        [Fact]
+        public void SetBufferMemoryWhenBufferMemorySet_Succeeds()
+        {
+            using (var saea = new SocketAsyncEventArgs())
+            {
+                Memory<byte> buffer1 = new byte[1];
+                Memory<byte> buffer2 = new byte[2];
+
+                for (int i = 0; i < 2; i++)
+                {
+                    saea.SetBuffer(buffer1);
+                    Assert.Null(saea.Buffer);
+                    Assert.True(saea.MemoryBuffer.Equals(buffer1));
+                    Assert.Equal(0, saea.Offset);
+                    Assert.Equal(buffer1.Length, saea.Count);
+                }
+
+                saea.SetBuffer(buffer2);
+                Assert.Null(saea.Buffer);
+                Assert.True(saea.MemoryBuffer.Equals(buffer2));
+                Assert.Equal(0, saea.Offset);
+                Assert.Equal(buffer2.Length, saea.Count);
+            }
+        }
+
+        [Fact]
+        public void SetBufferMemoryWhenBufferSet_Succeeds()
+        {
+            using (var saea = new SocketAsyncEventArgs())
+            {
+                byte[] buffer1 = new byte[3];
+                Memory<byte> buffer2 = new byte[4];
+
+                saea.SetBuffer(buffer1, 0, buffer1.Length);
+                Assert.Same(buffer1, saea.Buffer);
+                Assert.Equal(0, saea.Offset);
+                Assert.Equal(buffer1.Length, saea.Count);
+
+                saea.SetBuffer(1, 2);
+                Assert.Same(buffer1, saea.Buffer);
+                Assert.Equal(1, saea.Offset);
+                Assert.Equal(2, saea.Count);
+
+                saea.SetBuffer(buffer2);
+                Assert.Null(saea.Buffer);
+                Assert.True(saea.MemoryBuffer.Equals(buffer2));
+                Assert.Equal(0, saea.Offset);
+                Assert.Equal(buffer2.Length, saea.Count);
+            }
+        }
+
+        [Fact]
+        public void SetBufferMemory_NonArray_BufferReturnsNull()
+        {
+            using (var m = new NativeMemoryManager(42))
+            using (var saea = new SocketAsyncEventArgs())
+            {
+                saea.SetBuffer(m.Memory);
+                Assert.True(saea.MemoryBuffer.Equals(m.Memory));
+                Assert.Equal(0, saea.Offset);
+                Assert.Equal(m.Memory.Length, saea.Count);
+                Assert.Null(saea.Buffer);
+            }
+        }
+
+        [OuterLoop("Involves GC and finalization")]
+        [Theory]
+        [InlineData(false)]
+        [InlineData(true)]
+        public void Finalizer_InvokedWhenNoLongerReferenced(bool afterAsyncOperation)
+        {
+            var cwt = new ConditionalWeakTable<object, object>();
+
+            for (int i = 0; i < 5; i++) // create several SAEA instances, stored into cwt
+            {
+                CreateSocketAsyncEventArgs();
+
+                void CreateSocketAsyncEventArgs() // separated out so that JIT doesn't extend lifetime of SAEA instances
+                {
+                    var saea = new SocketAsyncEventArgs();
+                    cwt.Add(saea, saea);
+
+                    if (afterAsyncOperation)
+                    {
+                        using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+                        {
+                            listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
+                            listener.Listen(1);
+
+                            using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
+                            {
+                                saea.RemoteEndPoint = listener.LocalEndPoint;
+                                using (var mres = new ManualResetEventSlim())
+                                {
+                                    saea.Completed += (s, e) => mres.Set();
+                                    if (client.ConnectAsync(saea))
+                                    {
+                                        mres.Wait();
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            Assert.True(SpinWait.SpinUntil(() =>
+            {
+                GC.Collect();
+                GC.WaitForPendingFinalizers();
+                return cwt.Count() == 0; // validate that the cwt becomes empty
+            }, 30_000));
+        }
     }
 }
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.netcoreapp.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.netcoreapp.cs
deleted file mode 100644 (file)
index c0819e9..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-// 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.Buffers;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading;
-using Xunit;
-
-namespace System.Net.Sockets.Tests
-{
-    public partial class SocketAsyncEventArgsTest
-    {
-        [Fact]
-        public void SetBuffer_MemoryBuffer_Roundtrips()
-        {
-            using (var saea = new SocketAsyncEventArgs())
-            {
-                Memory<byte> memory = new byte[42];
-                saea.SetBuffer(memory);
-                Assert.True(memory.Equals(saea.MemoryBuffer));
-                Assert.Equal(0, saea.Offset);
-                Assert.Equal(memory.Length, saea.Count);
-                Assert.Null(saea.Buffer);
-            }
-        }
-
-        [Fact]
-        public void SetBufferMemory_ThenSetBufferIntInt_Throws()
-        {
-            using (var saea = new SocketAsyncEventArgs())
-            {
-                Memory<byte> memory = new byte[42];
-                saea.SetBuffer(memory);
-                Assert.Throws<InvalidOperationException>(() => saea.SetBuffer(0, 42));
-                Assert.Throws<InvalidOperationException>(() => saea.SetBuffer(0, 0));
-                Assert.Throws<InvalidOperationException>(() => saea.SetBuffer(1, 2));
-                Assert.True(memory.Equals(saea.MemoryBuffer));
-                Assert.Equal(0, saea.Offset);
-                Assert.Equal(memory.Length, saea.Count);
-            }
-        }
-
-        [Fact]
-        public void SetBufferArrayIntInt_AvailableFromMemoryBuffer()
-        {
-            using (var saea = new SocketAsyncEventArgs())
-            {
-                byte[] array = new byte[42];
-
-                saea.SetBuffer(array, 0, array.Length);
-                Assert.True(MemoryMarshal.TryGetArray(saea.MemoryBuffer, out ArraySegment<byte> result));
-                Assert.Same(array, result.Array);
-                Assert.Same(saea.Buffer, array);
-                Assert.Equal(0, result.Offset);
-                Assert.Equal(array.Length, result.Count);
-
-                saea.SetBuffer(1, 2);
-                Assert.Same(saea.Buffer, array);
-                Assert.Equal(1, saea.Offset);
-                Assert.Equal(2, saea.Count);
-
-                Assert.True(MemoryMarshal.TryGetArray(saea.MemoryBuffer, out result));
-                Assert.Same(array, result.Array);
-                Assert.Equal(0, result.Offset);
-                Assert.Equal(array.Length, result.Count);
-            }
-        }
-
-        [Fact]
-        public void SetBufferMemory_Default_ResetsCountOffset()
-        {
-            using (var saea = new SocketAsyncEventArgs())
-            {
-                saea.SetBuffer(42, 84);
-                Assert.Equal(0, saea.Offset);
-                Assert.Equal(0, saea.Count);
-
-                saea.SetBuffer(new byte[3], 1, 2);
-                Assert.Equal(1, saea.Offset);
-                Assert.Equal(2, saea.Count);
-
-                saea.SetBuffer(Memory<byte>.Empty);
-                Assert.Null(saea.Buffer);
-                Assert.Equal(0, saea.Offset);
-                Assert.Equal(0, saea.Count);
-            }
-        }
-
-        [Fact]
-        public void SetBufferListWhenMemoryBufferSet_Throws()
-        {
-            using (var saea = new SocketAsyncEventArgs())
-            {
-                var bufferList = new List<ArraySegment<byte>> { new ArraySegment<byte>(new byte[1]) };
-                Memory<byte> buffer = new byte[1];
-
-                saea.SetBuffer(buffer);
-                AssertExtensions.Throws<ArgumentException>(null, () => saea.BufferList = bufferList);
-                Assert.True(buffer.Equals(saea.MemoryBuffer));
-                Assert.Equal(0, saea.Offset);
-                Assert.Equal(buffer.Length, saea.Count);
-                Assert.Null(saea.BufferList);
-
-                saea.SetBuffer(Memory<byte>.Empty);
-                saea.BufferList = bufferList; // works fine when Buffer has been set back to null
-            }
-        }
-
-        [Fact]
-        public void SetBufferMemoryWhenBufferListSet_Throws()
-        {
-            using (var saea = new SocketAsyncEventArgs())
-            {
-                var bufferList = new List<ArraySegment<byte>> { new ArraySegment<byte>(new byte[1]) };
-                saea.BufferList = bufferList;
-
-                saea.SetBuffer(Memory<byte>.Empty); // nop
-
-                Memory<byte> buffer = new byte[2];
-                AssertExtensions.Throws<ArgumentException>(null, () => saea.SetBuffer(buffer));
-                Assert.Same(bufferList, saea.BufferList);
-                Assert.Null(saea.Buffer);
-                Assert.True(saea.MemoryBuffer.Equals(default));
-
-                saea.BufferList = null;
-                saea.SetBuffer(buffer); // works fine when BufferList has been set back to null
-            }
-        }
-
-        [Fact]
-        public void SetBufferMemoryWhenBufferMemorySet_Succeeds()
-        {
-            using (var saea = new SocketAsyncEventArgs())
-            {
-                Memory<byte> buffer1 = new byte[1];
-                Memory<byte> buffer2 = new byte[2];
-
-                for (int i = 0; i < 2; i++)
-                {
-                    saea.SetBuffer(buffer1);
-                    Assert.Null(saea.Buffer);
-                    Assert.True(saea.MemoryBuffer.Equals(buffer1));
-                    Assert.Equal(0, saea.Offset);
-                    Assert.Equal(buffer1.Length, saea.Count);
-                }
-
-                saea.SetBuffer(buffer2);
-                Assert.Null(saea.Buffer);
-                Assert.True(saea.MemoryBuffer.Equals(buffer2));
-                Assert.Equal(0, saea.Offset);
-                Assert.Equal(buffer2.Length, saea.Count);
-            }
-        }
-
-        [Fact]
-        public void SetBufferMemoryWhenBufferSet_Succeeds()
-        {
-            using (var saea = new SocketAsyncEventArgs())
-            {
-                byte[] buffer1 = new byte[3];
-                Memory<byte> buffer2 = new byte[4];
-
-                saea.SetBuffer(buffer1, 0, buffer1.Length);
-                Assert.Same(buffer1, saea.Buffer);
-                Assert.Equal(0, saea.Offset);
-                Assert.Equal(buffer1.Length, saea.Count);
-
-                saea.SetBuffer(1, 2);
-                Assert.Same(buffer1, saea.Buffer);
-                Assert.Equal(1, saea.Offset);
-                Assert.Equal(2, saea.Count);
-
-                saea.SetBuffer(buffer2);
-                Assert.Null(saea.Buffer);
-                Assert.True(saea.MemoryBuffer.Equals(buffer2));
-                Assert.Equal(0, saea.Offset);
-                Assert.Equal(buffer2.Length, saea.Count);
-            }
-        }
-
-        [Fact]
-        public void SetBufferMemory_NonArray_BufferReturnsNull()
-        {
-            using (var m = new NativeMemoryManager(42))
-            using (var saea = new SocketAsyncEventArgs())
-            {
-                saea.SetBuffer(m.Memory);
-                Assert.True(saea.MemoryBuffer.Equals(m.Memory));
-                Assert.Equal(0, saea.Offset);
-                Assert.Equal(m.Memory.Length, saea.Count);
-                Assert.Null(saea.Buffer);
-            }
-        }
-
-        [OuterLoop("Involves GC and finalization")]
-        [Theory]
-        [InlineData(false)]
-        [InlineData(true)]
-        public void Finalizer_InvokedWhenNoLongerReferenced(bool afterAsyncOperation)
-        {
-            var cwt = new ConditionalWeakTable<object, object>();
-
-            for (int i = 0; i < 5; i++) // create several SAEA instances, stored into cwt
-            {
-                CreateSocketAsyncEventArgs();
-
-                void CreateSocketAsyncEventArgs() // separated out so that JIT doesn't extend lifetime of SAEA instances
-                {
-                    var saea = new SocketAsyncEventArgs();
-                    cwt.Add(saea, saea);
-
-                    if (afterAsyncOperation)
-                    {
-                        using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-                        {
-                            listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
-                            listener.Listen(1);
-
-                            using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
-                            {
-                                saea.RemoteEndPoint = listener.LocalEndPoint;
-                                using (var mres = new ManualResetEventSlim())
-                                {
-                                    saea.Completed += (s, e) => mres.Set();
-                                    if (client.ConnectAsync(saea))
-                                    {
-                                        mres.Wait();
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            Assert.True(SpinWait.SpinUntil(() =>
-            {
-                GC.Collect();
-                GC.WaitForPendingFinalizers();
-                return cwt.Count() == 0; // validate that the cwt becomes empty
-            }, 30_000));
-        }
-    }
-}
index c090aa8..56f7716 100644 (file)
@@ -2,8 +2,8 @@
 // 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.Buffers;
 using System.Collections.Generic;
-using System.Diagnostics;
 using System.Runtime.InteropServices;
 using System.Threading.Tasks;
 using Xunit;
@@ -11,7 +11,6 @@ using Xunit.Abstractions;
 
 namespace System.Net.Sockets.Tests
 {
-
     // Define test collection for tests to avoid all other tests.
     [CollectionDefinition("NoParallelTests", DisableParallelization = true)]
     public partial class NoParallelTests { }
@@ -284,6 +283,55 @@ namespace System.Net.Sockets.Tests
         public void Listen(Socket s, int backlog) => _socketHelper.Listen(s, backlog);
     }
 
+    public class SocketHelperSpanSync : SocketHelperArraySync
+    {
+        public override bool ValidatesArrayArguments => false;
+        public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
+            Task.Run(() => s.Receive((Span<byte>)buffer, SocketFlags.None));
+        public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
+            Task.Run(() => s.Send((ReadOnlySpan<byte>)buffer, SocketFlags.None));
+    }
+
+    public sealed class SocketHelperSpanSyncForceNonBlocking : SocketHelperSpanSync
+    {
+        public override bool ValidatesArrayArguments => false;
+        public override Task<Socket> AcceptAsync(Socket s) =>
+            Task.Run(() => { s.ForceNonBlocking(true); Socket accepted = s.Accept(); accepted.ForceNonBlocking(true); return accepted; });
+        public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
+            Task.Run(() => { s.ForceNonBlocking(true); s.Connect(endPoint); });
+    }
+
+    public sealed class SocketHelperMemoryArrayTask : SocketHelperTask
+    {
+        public override bool ValidatesArrayArguments => false;
+        public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
+            s.ReceiveAsync((Memory<byte>)buffer, SocketFlags.None).AsTask();
+        public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
+            s.SendAsync((ReadOnlyMemory<byte>)buffer, SocketFlags.None).AsTask();
+    }
+
+    public sealed class SocketHelperMemoryNativeTask : SocketHelperTask
+    {
+        public override bool ValidatesArrayArguments => false;
+        public override async Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer)
+        {
+            using (var m = new NativeMemoryManager(buffer.Count))
+            {
+                int bytesReceived = await s.ReceiveAsync(m.Memory, SocketFlags.None).ConfigureAwait(false);
+                m.Memory.Span.Slice(0, bytesReceived).CopyTo(buffer.AsSpan());
+                return bytesReceived;
+            }
+        }
+        public override async Task<int> SendAsync(Socket s, ArraySegment<byte> buffer)
+        {
+            using (var m = new NativeMemoryManager(buffer.Count))
+            {
+                buffer.AsSpan().CopyTo(m.Memory.Span);
+                return await s.SendAsync(m.Memory, SocketFlags.None).ConfigureAwait(false);
+            }
+        }
+    }
+
     //
     // MemberDatas that are generally useful
     //
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.netcoreapp.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketTestHelper.netcoreapp.cs
deleted file mode 100644 (file)
index 945e905..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// 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.Buffers;
-using System.Threading.Tasks;
-
-namespace System.Net.Sockets.Tests
-{
-    public class SocketHelperSpanSync : SocketHelperArraySync
-    {
-        public override bool ValidatesArrayArguments => false;
-        public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
-            Task.Run(() => s.Receive((Span<byte>)buffer, SocketFlags.None));
-        public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
-            Task.Run(() => s.Send((ReadOnlySpan<byte>)buffer, SocketFlags.None));
-    }
-
-    public sealed class SocketHelperSpanSyncForceNonBlocking : SocketHelperSpanSync
-    {
-        public override bool ValidatesArrayArguments => false;
-        public override Task<Socket> AcceptAsync(Socket s) =>
-            Task.Run(() => { s.ForceNonBlocking(true); Socket accepted = s.Accept(); accepted.ForceNonBlocking(true); return accepted; });
-        public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
-            Task.Run(() => { s.ForceNonBlocking(true); s.Connect(endPoint); });
-    }
-
-    public sealed class SocketHelperMemoryArrayTask : SocketHelperTask
-    {
-        public override bool ValidatesArrayArguments => false;
-        public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
-            s.ReceiveAsync((Memory<byte>)buffer, SocketFlags.None).AsTask();
-        public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
-            s.SendAsync((ReadOnlyMemory<byte>)buffer, SocketFlags.None).AsTask();
-    }
-
-    public sealed class SocketHelperMemoryNativeTask : SocketHelperTask
-    {
-        public override bool ValidatesArrayArguments => false;
-        public override async Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer)
-        {
-            using (var m = new NativeMemoryManager(buffer.Count))
-            {
-                int bytesReceived = await s.ReceiveAsync(m.Memory, SocketFlags.None).ConfigureAwait(false);
-                m.Memory.Span.Slice(0, bytesReceived).CopyTo(buffer.AsSpan());
-                return bytesReceived;
-            }
-        }
-        public override async Task<int> SendAsync(Socket s, ArraySegment<byte> buffer)
-        {
-            using (var m = new NativeMemoryManager(buffer.Count))
-            {
-                buffer.AsSpan().CopyTo(m.Memory.Span);
-                return await s.SendAsync(m.Memory, SocketFlags.None).ConfigureAwait(false);
-            }
-        }
-    }
-}
index 2d90539..68f4a3c 100644 (file)
     <Compile Include="Connect.cs" />
     <Compile Include="Close.cs" />
     <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" />
-    <Compile Include="ExecutionContextFlowTest.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="IPPacketInformationTest.cs" />
-    <Compile Include="KeepAliveTest.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
+    <Compile Include="KeepAliveTest.cs" />
     <Compile Include="LingerStateTest.cs" />
     <Compile Include="LoggingTest.cs" />
     <Compile Include="NetworkStreamTest.cs" />
-    <Compile Include="NetworkStreamTest.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="ReceiveMessageFrom.cs" />
     <Compile Include="ReceiveMessageFromAsync.cs" />
     <Compile Include="SafeHandleTest.cs" />
     <Compile Include="SelectTest.cs" />
     <Compile Include="SendPacketsAsync.cs" />
-    <Compile Include="SendPacketsAsync.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="SendPacketsElementTest.cs" />
     <Compile Include="SendFile.cs" />
     <Compile Include="OSSupport.cs" />
-    <Compile Include="SendPacketsElementTest.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="SendReceive.cs" />
-    <Compile Include="SendReceive.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="SocketTestHelper.cs" />
-    <Compile Include="SocketTestHelper.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="SelectAndPollTests.cs" />
     <Compile Include="SocketInformationTest.cs" />
     <Compile Include="TcpListenerTest.cs" />
     <Compile Include="TcpClientTest.cs" />
     <Compile Include="Shutdown.cs" />
     <Compile Include="SocketAsyncEventArgsTest.cs" />
-    <Compile Include="SocketAsyncEventArgsTest.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="SocketOptionNameTest.cs" />
     <Compile Include="SocketOptionNameTest.Unix.cs" Condition="'$(TargetsUnix)' == 'true'" />
     <Compile Include="SocketOptionNameTest.Windows.cs" Condition="'$(TargetsWindows)' == 'true'" />
     <Compile Include="MulticastOptionTest.cs" />
     <Compile Include="UdpClientTest.cs" />
-    <Compile Include="UnixDomainSocketTest.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
+    <Compile Include="UnixDomainSocketTest.cs" />
     <!-- Common Sockets files -->
     <Compile Include="$(CommonTestPath)System\Net\Configuration.cs">
       <Link>SocketCommon\Configuration.cs</Link>
@@ -13,7 +13,7 @@ using Xunit;
 
 namespace System.Net.Sockets.Tests
 {
-    public partial class UnixDomainSocketTest
+    public class UnixDomainSocketTest
     {
         [PlatformSpecific(~TestPlatforms.Windows)] // Windows doesn't currently support ConnectEx with domain sockets
         [ConditionalFact(nameof(PlatformSupportsUnixDomainSockets))]
index 548e0f6..bded104 100644 (file)
@@ -4,7 +4,6 @@
 
 using System.Net.Security;
 using System.Net.Test.Common;
-using System.Reflection;
 using System.Security.Cryptography.X509Certificates;
 using System.Threading;
 using System.Threading.Tasks;
@@ -14,7 +13,7 @@ using Xunit.Abstractions;
 
 namespace System.Net.WebSockets.Client.Tests
 {
-    public partial class ClientWebSocketOptionsTests : ClientWebSocketTestBase
+    public class ClientWebSocketOptionsTests : ClientWebSocketTestBase
     {
         public ClientWebSocketOptionsTests(ITestOutputHelper output) : base(output) { }
 
@@ -138,5 +137,122 @@ namespace System.Net.WebSockets.Client.Tests
 
             AssertExtensions.Throws<ArgumentOutOfRangeException>("value", () => cws.Options.KeepAliveInterval = TimeSpan.MinValue);
         }
+
+        [ConditionalFact(nameof(WebSocketsSupported))]
+        public void RemoteCertificateValidationCallback_Roundtrips()
+        {
+            using (var cws = new ClientWebSocket())
+            {
+                Assert.Null(cws.Options.RemoteCertificateValidationCallback);
+
+                RemoteCertificateValidationCallback callback = delegate { return true; };
+                cws.Options.RemoteCertificateValidationCallback = callback;
+                Assert.Same(callback, cws.Options.RemoteCertificateValidationCallback);
+
+                cws.Options.RemoteCertificateValidationCallback = null;
+                Assert.Null(cws.Options.RemoteCertificateValidationCallback);
+            }
+        }
+
+        [OuterLoop("Connects to remote service")]
+        [ConditionalTheory(nameof(WebSocketsSupported))]
+        [InlineData(false)]
+        [InlineData(true)]
+        public async Task RemoteCertificateValidationCallback_PassedRemoteCertificateInfo(bool secure)
+        {
+            if (PlatformDetection.IsWindows7)
+            {
+                return; // [ActiveIssue(27846)]
+            }
+
+            bool callbackInvoked = false;
+
+            await LoopbackServer.CreateClientAndServerAsync(async uri =>
+            {
+                using (var cws = new ClientWebSocket())
+                using (var cts = new CancellationTokenSource(TimeOutMilliseconds))
+                {
+                    cws.Options.RemoteCertificateValidationCallback = (source, cert, chain, errors) =>
+                    {
+                        Assert.NotNull(source);
+                        Assert.NotNull(cert);
+                        Assert.NotNull(chain);
+                        Assert.NotEqual(SslPolicyErrors.None, errors);
+                        callbackInvoked = true;
+                        return true;
+                    };
+                    await cws.ConnectAsync(uri, cts.Token);
+                }
+            }, server => server.AcceptConnectionAsync(async connection =>
+            {
+                Assert.NotNull(await LoopbackHelper.WebSocketHandshakeAsync(connection));
+            }),
+            new LoopbackServer.Options { UseSsl = secure, WebSocketEndpoint = true });
+
+            Assert.Equal(secure, callbackInvoked);
+        }
+
+        [OuterLoop("Connects to remote service")]
+        [ConditionalFact(nameof(WebSocketsSupported))]
+        public async Task ClientCertificates_ValidCertificate_ServerReceivesCertificateAndConnectAsyncSucceeds()
+        {
+            if (PlatformDetection.IsWindows7)
+            {
+                return; // [ActiveIssue(27846)]
+            }
+
+            using (X509Certificate2 clientCert = Test.Common.Configuration.Certificates.GetClientCertificate())
+            {
+                await LoopbackServer.CreateClientAndServerAsync(async uri =>
+                {
+                    using (var clientSocket = new ClientWebSocket())
+                    using (var cts = new CancellationTokenSource(TimeOutMilliseconds))
+                    {
+                        clientSocket.Options.ClientCertificates.Add(clientCert);
+                        clientSocket.Options.RemoteCertificateValidationCallback = delegate { return true; };
+                        await clientSocket.ConnectAsync(uri, cts.Token);
+                    }
+                }, server => server.AcceptConnectionAsync(async connection =>
+                {
+                    // Validate that the client certificate received by the server matches the one configured on
+                    // the client-side socket.
+                    SslStream sslStream = Assert.IsType<SslStream>(connection.Stream);
+                    Assert.NotNull(sslStream.RemoteCertificate);
+                    Assert.Equal(clientCert, new X509Certificate2(sslStream.RemoteCertificate));
+
+                    // Complete the WebSocket upgrade over the secure channel. After this is done, the client-side
+                    // ConnectAsync should complete.
+                    Assert.NotNull(await LoopbackHelper.WebSocketHandshakeAsync(connection));
+                }), new LoopbackServer.Options { UseSsl = true, WebSocketEndpoint = true });
+            }
+        }
+
+        [ConditionalTheory(nameof(WebSocketsSupported))]
+        [InlineData("ws://")]
+        [InlineData("wss://")]
+        public async Task NonSecureConnect_ConnectThruProxy_CONNECTisUsed(string connectionType)
+        {
+            if (PlatformDetection.IsWindows7)
+            {
+                return; // [ActiveIssue(27846)]
+            }
+
+            bool connectionAccepted = false;
+
+            await LoopbackServer.CreateClientAndServerAsync(async proxyUri =>
+            {
+                using (var cws = new ClientWebSocket())
+                {
+                    cws.Options.Proxy = new WebProxy(proxyUri);
+                    try { await cws.ConnectAsync(new Uri(connectionType + Guid.NewGuid().ToString("N")), default); } catch { }
+                }
+            }, server => server.AcceptConnectionAsync(async connection =>
+            {
+                Assert.Contains("CONNECT", await connection.ReadLineAsync());
+                connectionAccepted = true;
+            }));
+
+            Assert.True(connectionAccepted);
+        }
     }
 }
diff --git a/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketOptionsTests.netcoreapp.cs b/src/libraries/System.Net.WebSockets.Client/tests/ClientWebSocketOptionsTests.netcoreapp.cs
deleted file mode 100644 (file)
index b8ae1e6..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-// 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.Net.Security;
-using System.Net.Test.Common;
-using System.Reflection;
-using System.Security.Cryptography.X509Certificates;
-using System.Threading;
-using System.Threading.Tasks;
-
-using Xunit;
-using Xunit.Abstractions;
-
-namespace System.Net.WebSockets.Client.Tests
-{
-    public partial class ClientWebSocketOptionsTests : ClientWebSocketTestBase
-    {
-        [ConditionalFact(nameof(WebSocketsSupported))]
-        public void RemoteCertificateValidationCallback_Roundtrips()
-        {
-            using (var cws = new ClientWebSocket())
-            {
-                Assert.Null(cws.Options.RemoteCertificateValidationCallback);
-
-                RemoteCertificateValidationCallback callback = delegate { return true; };
-                cws.Options.RemoteCertificateValidationCallback = callback;
-                Assert.Same(callback, cws.Options.RemoteCertificateValidationCallback);
-
-                cws.Options.RemoteCertificateValidationCallback = null;
-                Assert.Null(cws.Options.RemoteCertificateValidationCallback);
-            }
-        }
-
-        [OuterLoop("Connects to remote service")]
-        [ConditionalTheory(nameof(WebSocketsSupported))]
-        [InlineData(false)]
-        [InlineData(true)]
-        public async Task RemoteCertificateValidationCallback_PassedRemoteCertificateInfo(bool secure)
-        {
-            if (PlatformDetection.IsWindows7)
-            {
-                return; // [ActiveIssue(27846)]
-            }
-
-            bool callbackInvoked = false;
-
-            await LoopbackServer.CreateClientAndServerAsync(async uri =>
-            {
-                using (var cws = new ClientWebSocket())
-                using (var cts = new CancellationTokenSource(TimeOutMilliseconds))
-                {
-                    cws.Options.RemoteCertificateValidationCallback = (source, cert, chain, errors) =>
-                    {
-                        Assert.NotNull(source);
-                        Assert.NotNull(cert);
-                        Assert.NotNull(chain);
-                        Assert.NotEqual(SslPolicyErrors.None, errors);
-                        callbackInvoked = true;
-                        return true;
-                    };
-                    await cws.ConnectAsync(uri, cts.Token);
-                }
-            }, server => server.AcceptConnectionAsync(async connection =>
-            {
-                Assert.NotNull(await LoopbackHelper.WebSocketHandshakeAsync(connection));
-            }),
-            new LoopbackServer.Options { UseSsl = secure, WebSocketEndpoint = true });
-
-            Assert.Equal(secure, callbackInvoked);
-        }
-
-        [OuterLoop("Connects to remote service")]
-        [ConditionalFact(nameof(WebSocketsSupported))]
-        public async Task ClientCertificates_ValidCertificate_ServerReceivesCertificateAndConnectAsyncSucceeds()
-        {
-            if (PlatformDetection.IsWindows7)
-            {
-                return; // [ActiveIssue(27846)]
-            }
-
-            using (X509Certificate2 clientCert = Test.Common.Configuration.Certificates.GetClientCertificate())
-            {
-                await LoopbackServer.CreateClientAndServerAsync(async uri =>
-                {
-                    using (var clientSocket = new ClientWebSocket())
-                    using (var cts = new CancellationTokenSource(TimeOutMilliseconds))
-                    {
-                        clientSocket.Options.ClientCertificates.Add(clientCert);
-                        clientSocket.Options.RemoteCertificateValidationCallback = delegate { return true; };
-                        await clientSocket.ConnectAsync(uri, cts.Token);
-                    }
-                }, server => server.AcceptConnectionAsync(async connection =>
-                {
-                    // Validate that the client certificate received by the server matches the one configured on
-                    // the client-side socket.
-                    SslStream sslStream = Assert.IsType<SslStream>(connection.Stream);
-                    Assert.NotNull(sslStream.RemoteCertificate);
-                    Assert.Equal(clientCert, new X509Certificate2(sslStream.RemoteCertificate));
-
-                    // Complete the WebSocket upgrade over the secure channel. After this is done, the client-side
-                    // ConnectAsync should complete.
-                    Assert.NotNull(await LoopbackHelper.WebSocketHandshakeAsync(connection));
-                }), new LoopbackServer.Options { UseSsl = true, WebSocketEndpoint = true });
-            }
-        }
-
-        [ConditionalTheory(nameof(WebSocketsSupported))]
-        [InlineData("ws://")]
-        [InlineData("wss://")]
-        public async Task NonSecureConnect_ConnectThruProxy_CONNECTisUsed(string connectionType)
-        {
-            if (PlatformDetection.IsWindows7)
-            {
-                return; // [ActiveIssue(27846)]
-            }
-
-            bool connectionAccepted = false;
-
-            await LoopbackServer.CreateClientAndServerAsync(async proxyUri =>
-            {
-                using (var cws = new ClientWebSocket())
-                {
-                    cws.Options.Proxy = new WebProxy(proxyUri);
-                    try { await cws.ConnectAsync(new Uri(connectionType + Guid.NewGuid().ToString("N")), default); } catch { }
-                }
-            }, server => server.AcceptConnectionAsync(async connection =>
-            {
-                Assert.Contains("CONNECT", await connection.ReadLineAsync());
-                connectionAccepted = true;
-            }));
-
-            Assert.True(connectionAccepted);
-        }
-    }
-}
index d3ac7c0..1a8537c 100644 (file)
@@ -12,6 +12,26 @@ using Xunit.Abstractions;
 
 namespace System.Net.WebSockets.Client.Tests
 {
+    public sealed class MemorySendReceiveTest : SendReceiveTest
+    {
+        public MemorySendReceiveTest(ITestOutputHelper output) : base(output) { }
+
+        protected override async Task<WebSocketReceiveResult> ReceiveAsync(WebSocket ws, ArraySegment<byte> arraySegment, CancellationToken cancellationToken)
+        {
+            ValueWebSocketReceiveResult r = await ws.ReceiveAsync(
+                (Memory<byte>)arraySegment,
+                cancellationToken).ConfigureAwait(false);
+            return new WebSocketReceiveResult(r.Count, r.MessageType, r.EndOfMessage, ws.CloseStatus, ws.CloseStatusDescription);
+        }
+
+        protected override Task SendAsync(WebSocket ws, ArraySegment<byte> arraySegment, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) =>
+            ws.SendAsync(
+                (ReadOnlyMemory<byte>)arraySegment,
+                messageType,
+                endOfMessage,
+                cancellationToken).AsTask();
+    }
+
     public sealed class ArraySegmentSendReceiveTest : SendReceiveTest
     {
         public ArraySegmentSendReceiveTest(ITestOutputHelper output) : base(output) { }
diff --git a/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.netcoreapp.cs b/src/libraries/System.Net.WebSockets.Client/tests/SendReceiveTest.netcoreapp.cs
deleted file mode 100644 (file)
index e8a839a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.Threading;
-using System.Threading.Tasks;
-using Xunit.Abstractions;
-
-namespace System.Net.WebSockets.Client.Tests
-{
-    public sealed class MemorySendReceiveTest : SendReceiveTest
-    {
-        public MemorySendReceiveTest(ITestOutputHelper output) : base(output) { }
-
-        protected override async Task<WebSocketReceiveResult> ReceiveAsync(WebSocket ws, ArraySegment<byte> arraySegment, CancellationToken cancellationToken)
-        {
-            ValueWebSocketReceiveResult r = await ws.ReceiveAsync(
-                (Memory<byte>)arraySegment,
-                cancellationToken).ConfigureAwait(false);
-            return new WebSocketReceiveResult(r.Count, r.MessageType, r.EndOfMessage, ws.CloseStatus, ws.CloseStatusDescription);
-        }
-
-        protected override Task SendAsync(WebSocket ws, ArraySegment<byte> arraySegment, WebSocketMessageType messageType, bool endOfMessage, CancellationToken cancellationToken) =>
-            ws.SendAsync(
-                (ReadOnlyMemory<byte>)arraySegment,
-                messageType,
-                endOfMessage,
-                cancellationToken).AsTask();
-    }
-}
index 5e1ee86..d32a462 100644 (file)
@@ -45,7 +45,6 @@
     <Compile Include="AbortTest.cs" />
     <Compile Include="CancelTest.cs" />
     <Compile Include="ClientWebSocketOptionsTests.cs" />
-    <Compile Include="ClientWebSocketOptionsTests.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="ClientWebSocketTestBase.cs" />
     <Compile Include="ClientWebSocketUnitTest.cs" />
     <Compile Include="CloseTest.cs" />
@@ -54,7 +53,6 @@
     <Compile Include="KeepAliveTest.cs" />
     <Compile Include="LoopbackHelper.cs" />
     <Compile Include="ResourceHelper.cs" />
-    <Compile Include="SendReceiveTest.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="SendReceiveTest.cs" />
     <Compile Include="WebSocketData.cs" />
     <Compile Include="WebSocketHelper.cs" />
index 7732b66..0ca4881 100644 (file)
@@ -4,7 +4,6 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="WebSocketTests.cs" />
-    <Compile Include="WebSocketTests.netcoreapp.cs" Condition="'$(TargetsNetCoreApp)' == 'true'" />
     <Compile Include="WebSocketExceptionTests.cs" />
     <Compile Include="WebSocketReceiveResultTests.cs" />
     <Compile Include="$(CommonTestPath)System\Net\WebSockets\WebSocketCreateTest.cs">
index 19b7eb0..2ca3968 100644 (file)
@@ -7,8 +7,11 @@ using Xunit;
 
 namespace System.Net.WebSockets.Tests
 {
-    public sealed partial class WebSocketTests
+    public sealed class WebSocketTests : WebSocketCreateTest
     {
+        protected override WebSocket CreateFromStream(Stream stream, bool isServer, string subProtocol, TimeSpan keepAliveInterval) =>
+            WebSocket.CreateFromStream(stream, isServer, subProtocol, keepAliveInterval);
+
         [Fact]
         public static void DefaultKeepAliveInterval_ValidValue()
         {
@@ -91,7 +94,6 @@ namespace System.Net.WebSockets.Tests
             Assert.Throws<PlatformNotSupportedException>(() => WebSocket.RegisterPrefixes());
         }
 
-#if NETCOREAPP
         [Fact]
         public static void IsApplicationTargeting45_AlwaysTrue()
         {
@@ -99,7 +101,6 @@ namespace System.Net.WebSockets.Tests
             Assert.True(WebSocket.IsApplicationTargeting45());
 #pragma warning restore 0618
         }
-#endif
 
         [Theory]
         [InlineData(WebSocketState.None)]
@@ -145,6 +146,32 @@ namespace System.Net.WebSockets.Tests
             ExposeProtectedWebSocket.ThrowOnInvalidState(state, validStates);
         }
 
+        [Fact]
+        public void ValueWebSocketReceiveResult_Ctor_InvalidArguments_Throws()
+        {
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("count", () => new ValueWebSocketReceiveResult(-1, WebSocketMessageType.Text, true));
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("count", () => new ValueWebSocketReceiveResult(int.MinValue, WebSocketMessageType.Text, true));
+
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("messageType", () => new ValueWebSocketReceiveResult(0, (WebSocketMessageType)(-1), true));
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("messageType", () => new ValueWebSocketReceiveResult(0, (WebSocketMessageType)(3), true));
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("messageType", () => new ValueWebSocketReceiveResult(0, (WebSocketMessageType)(int.MinValue), true));
+            AssertExtensions.Throws<ArgumentOutOfRangeException>("messageType", () => new ValueWebSocketReceiveResult(0, (WebSocketMessageType)(int.MaxValue), true));
+        }
+
+        [Theory]
+        [InlineData(0, WebSocketMessageType.Text, true)]
+        [InlineData(0, WebSocketMessageType.Text, false)]
+        [InlineData(42, WebSocketMessageType.Binary, false)]
+        [InlineData(int.MaxValue, WebSocketMessageType.Close, false)]
+        [InlineData(int.MaxValue, WebSocketMessageType.Close, true)]
+        public void ValueWebSocketReceiveResult_Ctor_ValidArguments_Roundtrip(int count, WebSocketMessageType messageType, bool endOfMessage)
+        {
+            ValueWebSocketReceiveResult r = new ValueWebSocketReceiveResult(count, messageType, endOfMessage);
+            Assert.Equal(count, r.Count);
+            Assert.Equal(messageType, r.MessageType);
+            Assert.Equal(endOfMessage, r.EndOfMessage);
+        }
+
         public abstract class ExposeProtectedWebSocket : WebSocket
         {
             public static new bool IsStateTerminal(WebSocketState state) =>
diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketTests.netcoreapp.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketTests.netcoreapp.cs
deleted file mode 100644 (file)
index 0857a1d..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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.IO;
-using Xunit;
-
-namespace System.Net.WebSockets.Tests
-{
-    public sealed partial class WebSocketTests : WebSocketCreateTest
-    {
-        protected override WebSocket CreateFromStream(Stream stream, bool isServer, string subProtocol, TimeSpan keepAliveInterval) =>
-            WebSocket.CreateFromStream(stream, isServer, subProtocol, keepAliveInterval);
-
-        [Fact]
-        public void ValueWebSocketReceiveResult_Ctor_InvalidArguments_Throws()
-        {
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("count", () => new ValueWebSocketReceiveResult(-1, WebSocketMessageType.Text, true));
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("count", () => new ValueWebSocketReceiveResult(int.MinValue, WebSocketMessageType.Text, true));
-
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("messageType", () => new ValueWebSocketReceiveResult(0, (WebSocketMessageType)(-1), true));
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("messageType", () => new ValueWebSocketReceiveResult(0, (WebSocketMessageType)(3), true));
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("messageType", () => new ValueWebSocketReceiveResult(0, (WebSocketMessageType)(int.MinValue), true));
-            AssertExtensions.Throws<ArgumentOutOfRangeException>("messageType", () => new ValueWebSocketReceiveResult(0, (WebSocketMessageType)(int.MaxValue), true));
-        }
-
-        [Theory]
-        [InlineData(0, WebSocketMessageType.Text, true)]
-        [InlineData(0, WebSocketMessageType.Text, false)]
-        [InlineData(42, WebSocketMessageType.Binary, false)]
-        [InlineData(int.MaxValue, WebSocketMessageType.Close, false)]
-        [InlineData(int.MaxValue, WebSocketMessageType.Close, true)]
-        public void ValueWebSocketReceiveResult_Ctor_ValidArguments_Roundtrip(int count, WebSocketMessageType messageType, bool endOfMessage)
-        {
-            ValueWebSocketReceiveResult r = new ValueWebSocketReceiveResult(count, messageType, endOfMessage);
-            Assert.Equal(count, r.Count);
-            Assert.Equal(messageType, r.MessageType);
-            Assert.Equal(endOfMessage, r.EndOfMessage);
-        }
-    }
-}