* Consolidate .netcoreapp.cs files because System.Net.* projects is no longer cross-compiled
* Fix build
* Add end-of-line
<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" />
// 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;
_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;
+ }
}
}
+++ /dev/null
-// 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;
- }
- }
-}
// 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;
namespace System.Net.Http.Functional.Tests
{
- public sealed partial class HttpClientTest
+ public sealed class HttpClientTest
{
[Fact]
public void Dispose_MultipleTimes_Success()
}
}
+ [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)
+++ /dev/null
-// 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());
- }
- }
- }
-}
// 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; }
StaticHttpMethods = staticHttpMethods;
}
- static partial void AddStaticHttpMethods(List<object[]> staticHttpMethods);
-
[Fact]
public void StaticProperties_VerifyValues_PropertyNameMatchesHttpMethodName()
{
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 });
+ }
}
}
+++ /dev/null
-// 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 });
- }
- }
-}
<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" />
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");
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);
+ }
}
}
+++ /dev/null
-// 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);
- }
- }
-}
<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>
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;
}
}
}
+
+ 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);
+ }
+ }
+ }
+ }
}
+++ /dev/null
-// 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);
- }
- }
- }
- }
-}
<Compile Include="SslStreamSchSendAuxRecordTest.cs" />
<Compile Include="SslStreamCredentialCacheTest.cs" />
<Compile Include="SslStreamSystemDefaultsTest.cs" />
- <Compile Include="SslStreamStreamToStreamTest.netcoreapp.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="LoggingTest.cs" />
// 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;
namespace System.Net.Sockets.Tests
{
- public partial class CreateSocket
+ public class CreateSocket
{
public static object[][] DualModeSuccessInputs = {
new object[] { SocketType.Stream, ProtocolType.Tcp },
}
}, 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();
+ }
}
}
+++ /dev/null
-// 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();
- }
- }
-}
// 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) };
{
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;
+ }
}
}
+++ /dev/null
-// 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;
- }
- }
-}
// 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)]
}
}
}
+
+ [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();
+ }
+ }
}
}
+++ /dev/null
-// 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();
- }
- }
- }
-}
// 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()
}, 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.
+++ /dev/null
-// 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;
- }
- }
-}
namespace System.Net.Sockets.Tests
{
- public partial class SendPacketsAsync
+ public class SendPacketsAsync
{
private readonly ITestOutputHelper _log;
#endregion Additional test attributes
-
#region Basic Arguments
[OuterLoop] // TODO: Issue #11345
}
}
+ [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)
{
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
}
}
+++ /dev/null
-// 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
- }
-}
namespace System.Net.Sockets.Tests
{
- public partial class SendPacketsElementTest
+ public class SendPacketsElementTest
{
#region Buffer
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
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
}
}
+++ /dev/null
-// 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
-
- }
-}
{
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) { }
+ }
}
+++ /dev/null
-// 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) { }
- }
-}
// 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()
(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));
+ }
}
}
+++ /dev/null
-// 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));
- }
- }
-}
// 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;
namespace System.Net.Sockets.Tests
{
-
// Define test collection for tests to avoid all other tests.
[CollectionDefinition("NoParallelTests", DisableParallelization = true)]
public partial class NoParallelTests { }
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
//
+++ /dev/null
-// 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);
- }
- }
- }
-}
<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>
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))]
using System.Net.Security;
using System.Net.Test.Common;
-using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
namespace System.Net.WebSockets.Client.Tests
{
- public partial class ClientWebSocketOptionsTests : ClientWebSocketTestBase
+ public class ClientWebSocketOptionsTests : ClientWebSocketTestBase
{
public ClientWebSocketOptionsTests(ITestOutputHelper output) : base(output) { }
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);
+ }
}
}
+++ /dev/null
-// 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);
- }
- }
-}
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) { }
+++ /dev/null
-// 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();
- }
-}
<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" />
<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" />
</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">
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()
{
Assert.Throws<PlatformNotSupportedException>(() => WebSocket.RegisterPrefixes());
}
-#if NETCOREAPP
[Fact]
public static void IsApplicationTargeting45_AlwaysTrue()
{
Assert.True(WebSocket.IsApplicationTargeting45());
#pragma warning restore 0618
}
-#endif
[Theory]
[InlineData(WebSocketState.None)]
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) =>
+++ /dev/null
-// 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);
- }
- }
-}