Imported Upstream version 5.10.0.47

Former-commit-id: d0813289fa2d35e1f8ed77530acb4fb1df441bc0
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-01-24 17:04:36 +00:00
parent 88ff76fe28
commit e46a49ecf1
5927 changed files with 226314 additions and 129848 deletions

View File

@@ -0,0 +1,286 @@
// 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.Tasks;
using Xunit;
namespace System.Net.Sockets.Tests
{
public abstract class Accept<T> : SocketTestHelperBase<T> where T : SocketHelperBase, new()
{
[OuterLoop] // TODO: Issue #11345
[Theory]
[MemberData(nameof(Loopbacks))]
public async Task Accept_Success(IPAddress listenAt)
{
using (Socket listen = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
int port = listen.BindToAnonymousPort(listenAt);
listen.Listen(1);
Task<Socket> acceptTask = AcceptAsync(listen);
Assert.False(acceptTask.IsCompleted);
using (Socket client = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
await ConnectAsync(client, new IPEndPoint(listenAt, port));
Socket accept = await acceptTask;
Assert.NotNull(accept);
Assert.True(accept.Connected);
Assert.Equal(client.LocalEndPoint, accept.RemoteEndPoint);
Assert.Equal(accept.LocalEndPoint, client.RemoteEndPoint);
}
}
}
[OuterLoop] // TODO: Issue #11345
[Theory]
[InlineData(2)]
[InlineData(5)]
public async Task Accept_ConcurrentAcceptsBeforeConnects_Success(int numberAccepts)
{
// The SyncForceNonBlocking implementation currently toggles the listener's Blocking setting
// back and force on every Accept, which causes pending sync Accepts to return EWOULDBLOCK.
// For now, just skip the test for SyncForceNonBlocking.
// TODO: Issue #22885
if (typeof(T) == typeof(SocketHelperSyncForceNonBlocking))
return;
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
listener.Listen(numberAccepts);
var clients = new Socket[numberAccepts];
var servers = new Task<Socket>[numberAccepts];
try
{
for (int i = 0; i < numberAccepts; i++)
{
clients[i] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
servers[i] = AcceptAsync(listener);
}
foreach (Socket client in clients)
{
await ConnectAsync(client, listener.LocalEndPoint);
}
await Task.WhenAll(servers);
Assert.All(servers, s => Assert.Equal(TaskStatus.RanToCompletion, s.Status));
Assert.All(servers, s => Assert.NotNull(s.Result));
Assert.All(servers, s => Assert.True(s.Result.Connected));
}
finally
{
foreach (Socket client in clients)
{
client?.Dispose();
}
foreach (Task<Socket> server in servers)
{
if (server?.Status == TaskStatus.RanToCompletion)
{
server.Result.Dispose();
}
}
}
}
}
[OuterLoop] // TODO: Issue #11345
[Theory]
[InlineData(2)]
[InlineData(5)]
public async Task Accept_ConcurrentAcceptsAfterConnects_Success(int numberAccepts)
{
// The SyncForceNonBlocking implementation currently toggles the listener's Blocking setting
// back and force on every Accept, which causes pending sync Accepts to return EWOULDBLOCK.
// For now, just skip the test for SyncForceNonBlocking.
// TODO: Issue #22885
if (typeof(T) == typeof(SocketHelperSyncForceNonBlocking))
return;
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
listener.Listen(numberAccepts);
var clients = new Socket[numberAccepts];
var clientConnects = new Task[numberAccepts];
var servers = new Task<Socket>[numberAccepts];
try
{
for (int i = 0; i < numberAccepts; i++)
{
clients[i] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientConnects[i] = ConnectAsync(clients[i], listener.LocalEndPoint);
}
for (int i = 0; i < numberAccepts; i++)
{
servers[i] = AcceptAsync(listener);
}
await Task.WhenAll(clientConnects);
Assert.All(clientConnects, c => Assert.Equal(TaskStatus.RanToCompletion, c.Status));
await Task.WhenAll(servers);
Assert.All(servers, s => Assert.Equal(TaskStatus.RanToCompletion, s.Status));
Assert.All(servers, s => Assert.NotNull(s.Result));
Assert.All(servers, s => Assert.True(s.Result.Connected));
}
finally
{
foreach (Socket client in clients)
{
client?.Dispose();
}
foreach (Task<Socket> server in servers)
{
if (server?.Status == TaskStatus.RanToCompletion)
{
server.Result.Dispose();
}
}
}
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[ActiveIssue(17209, TestPlatforms.AnyUnix)]
public async Task Accept_WithTargetSocket_Success()
{
if (!SupportsAcceptIntoExistingSocket)
return;
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = listener.BindToAnonymousPort(IPAddress.Loopback);
listener.Listen(1);
Task<Socket> acceptTask = AcceptAsync(listener, server);
client.Connect(IPAddress.Loopback, port);
Socket accepted = await acceptTask;
Assert.Same(server, accepted);
Assert.True(accepted.Connected);
}
}
[ActiveIssue(22808, TargetFrameworkMonikers.NetFramework)]
[ActiveIssue(17209, TestPlatforms.AnyUnix)]
[OuterLoop] // TODO: Issue #11345
[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task Accept_WithTargetSocket_ReuseAfterDisconnect_Success(bool reuseSocket)
{
if (!SupportsAcceptIntoExistingSocket)
return;
// APM mode fails currently. Issue: #22764
if (typeof(T) == typeof(SocketHelperApm))
return;
using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (var server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = listener.BindToAnonymousPort(IPAddress.Loopback);
listener.Listen(1);
using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
Task<Socket> acceptTask = AcceptAsync(listener, server);
client.Connect(IPAddress.Loopback, port);
Socket accepted = await acceptTask;
Assert.Same(server, accepted);
Assert.True(accepted.Connected);
}
server.Disconnect(reuseSocket);
Assert.False(server.Connected);
if (reuseSocket)
{
using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
Task<Socket> acceptTask = AcceptAsync(listener, server);
client.Connect(IPAddress.Loopback, port);
Socket accepted = await acceptTask;
Assert.Same(server, accepted);
Assert.True(accepted.Connected);
}
}
else
{
SocketException se = await Assert.ThrowsAsync<SocketException>(() => AcceptAsync(listener, server));
Assert.Equal(SocketError.InvalidArgument, se.SocketErrorCode);
}
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[ActiveIssue(17209, TestPlatforms.AnyUnix)]
public void Accept_WithAlreadyBoundTargetSocket_Fails()
{
if (!SupportsAcceptIntoExistingSocket)
return;
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = listener.BindToAnonymousPort(IPAddress.Loopback);
listener.Listen(1);
server.BindToAnonymousPort(IPAddress.Loopback);
Assert.Throws<InvalidOperationException>(() => { AcceptAsync(listener, server); });
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[ActiveIssue(17209, TestPlatforms.AnyUnix)]
public async Task Accept_WithInUseTargetSocket_Fails()
{
if (!SupportsAcceptIntoExistingSocket)
return;
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = listener.BindToAnonymousPort(IPAddress.Loopback);
listener.Listen(1);
Task<Socket> acceptTask = AcceptAsync(listener, server);
client.Connect(IPAddress.Loopback, port);
Socket accepted = await acceptTask;
Assert.Same(server, accepted);
Assert.True(accepted.Connected);
Assert.Throws<InvalidOperationException>(() => { AcceptAsync(listener, server); });
}
}
}
public sealed class AcceptSync : Accept<SocketHelperArraySync> { }
public sealed class AcceptSyncForceNonBlocking : Accept<SocketHelperSyncForceNonBlocking> { }
public sealed class AcceptApm : Accept<SocketHelperApm> { }
public sealed class AcceptTask : Accept<SocketHelperTask> { }
public sealed class AcceptEap : Accept<SocketHelperEap> { }
}

View File

@@ -1,410 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Net.Test.Common;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
namespace System.Net.Sockets.Tests
{
public class AcceptAsync
{
private readonly ITestOutputHelper _log;
public AcceptAsync(ITestOutputHelper output)
{
_log = TestLogging.GetInstance();
}
public void OnAcceptCompleted(object sender, SocketAsyncEventArgs args)
{
_log.WriteLine("OnAcceptCompleted event handler");
EventWaitHandle handle = (EventWaitHandle)args.UserToken;
handle.Set();
}
public void OnConnectCompleted(object sender, SocketAsyncEventArgs args)
{
_log.WriteLine("OnConnectCompleted event handler");
EventWaitHandle handle = (EventWaitHandle)args.UserToken;
handle.Set();
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[Trait("IPv4", "true")]
public void AcceptAsync_IpV4_Success()
{
Assert.True(Capability.IPv4Support());
AutoResetEvent completed = new AutoResetEvent(false);
AutoResetEvent completedClient = new AutoResetEvent(false);
using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = sock.BindToAnonymousPort(IPAddress.Loopback);
sock.Listen(1);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.Completed += OnAcceptCompleted;
args.UserToken = completed;
Assert.True(sock.AcceptAsync(args));
_log.WriteLine("IPv4 Server: Waiting for clients.");
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
SocketAsyncEventArgs argsClient = new SocketAsyncEventArgs();
argsClient.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, port);
argsClient.Completed += OnConnectCompleted;
argsClient.UserToken = completedClient;
client.ConnectAsync(argsClient);
_log.WriteLine("IPv4 Client: Connecting.");
Assert.True(completed.WaitOne(5000), "IPv4: Timed out while waiting for connection");
Assert.Equal<SocketError>(SocketError.Success, args.SocketError);
Assert.NotNull(args.AcceptSocket);
Assert.True(args.AcceptSocket.Connected, "IPv4 Accept Socket was not connected");
Assert.NotNull(args.AcceptSocket.RemoteEndPoint);
Assert.Equal(client.LocalEndPoint, args.AcceptSocket.RemoteEndPoint);
}
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[Trait("IPv6", "true")]
public void AcceptAsync_IPv6_Success()
{
Assert.True(Capability.IPv6Support());
AutoResetEvent completed = new AutoResetEvent(false);
AutoResetEvent completedClient = new AutoResetEvent(false);
using (Socket sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp))
{
int port = sock.BindToAnonymousPort(IPAddress.IPv6Loopback);
sock.Listen(1);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.Completed += OnAcceptCompleted;
args.UserToken = completed;
Assert.True(sock.AcceptAsync(args));
_log.WriteLine("IPv6 Server: Waiting for clients.");
using (Socket client = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp))
{
SocketAsyncEventArgs argsClient = new SocketAsyncEventArgs();
argsClient.RemoteEndPoint = new IPEndPoint(IPAddress.IPv6Loopback, port);
argsClient.Completed += OnConnectCompleted;
argsClient.UserToken = completedClient;
client.ConnectAsync(argsClient);
_log.WriteLine("IPv6 Client: Connecting.");
Assert.True(completed.WaitOne(5000), "IPv6: Timed out while waiting for connection");
Assert.Equal<SocketError>(SocketError.Success, args.SocketError);
Assert.NotNull(args.AcceptSocket);
Assert.True(args.AcceptSocket.Connected, "IPv6 Accept Socket was not connected");
Assert.NotNull(args.AcceptSocket.RemoteEndPoint);
Assert.Equal(client.LocalEndPoint, args.AcceptSocket.RemoteEndPoint);
}
}
}
[OuterLoop] // TODO: Issue #11345
[Theory]
[InlineData(2)]
[InlineData(5)]
public async Task AcceptAsync_ConcurrentAcceptsBeforeConnects_Success(int numberAccepts)
{
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
listener.Listen(numberAccepts);
var clients = new Socket[numberAccepts];
var servers = new Task<Socket>[numberAccepts];
try
{
for (int i = 0; i < numberAccepts; i++)
{
clients[i] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
servers[i] = listener.AcceptAsync();
}
foreach (Socket client in clients)
{
client.Connect(listener.LocalEndPoint);
}
await Task.WhenAll(servers);
Assert.All(servers, s => Assert.Equal(TaskStatus.RanToCompletion, s.Status));
Assert.All(servers, s => Assert.NotNull(s.Result));
Assert.All(servers, s => Assert.True(s.Result.Connected));
}
finally
{
foreach (Socket client in clients)
{
client?.Dispose();
}
foreach (Task<Socket> server in servers)
{
if (server?.Status == TaskStatus.RanToCompletion)
{
server.Result.Dispose();
}
}
}
}
}
[OuterLoop] // TODO: Issue #11345
[Theory]
[InlineData(2)]
[InlineData(5)]
public async Task AcceptAsync_ConcurrentAcceptsAfterConnects_Success(int numberAccepts)
{
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
listener.Bind(new IPEndPoint(IPAddress.Loopback, 0));
listener.Listen(numberAccepts);
var clients = new Socket[numberAccepts];
var clientConnects = new Task[numberAccepts];
var servers = new Task<Socket>[numberAccepts];
try
{
for (int i = 0; i < numberAccepts; i++)
{
clients[i] = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientConnects[i] = clients[i].ConnectAsync(listener.LocalEndPoint);
}
for (int i = 0; i < numberAccepts; i++)
{
servers[i] = listener.AcceptAsync();
}
await Task.WhenAll(clientConnects);
Assert.All(clientConnects, c => Assert.Equal(TaskStatus.RanToCompletion, c.Status));
await Task.WhenAll(servers);
Assert.All(servers, s => Assert.Equal(TaskStatus.RanToCompletion, s.Status));
Assert.All(servers, s => Assert.NotNull(s.Result));
Assert.All(servers, s => Assert.True(s.Result.Connected));
}
finally
{
foreach (Socket client in clients)
{
client?.Dispose();
}
foreach (Task<Socket> server in servers)
{
if (server?.Status == TaskStatus.RanToCompletion)
{
server.Result.Dispose();
}
}
}
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // Unix platforms don't yet support receiving data with AcceptAsync.
public void AcceptAsync_WithReceiveBuffer_Success()
{
Assert.True(Capability.IPv4Support());
AutoResetEvent accepted = new AutoResetEvent(false);
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = server.BindToAnonymousPort(IPAddress.Loopback);
server.Listen(1);
const int acceptBufferOverheadSize = 288; // see https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.acceptasync(v=vs.110).aspx
const int acceptBufferDataSize = 256;
const int acceptBufferSize = acceptBufferOverheadSize + acceptBufferDataSize;
byte[] sendBuffer = new byte[acceptBufferDataSize];
new Random().NextBytes(sendBuffer);
SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs();
acceptArgs.Completed += OnAcceptCompleted;
acceptArgs.UserToken = accepted;
acceptArgs.SetBuffer(new byte[acceptBufferSize], 0, acceptBufferSize);
Assert.True(server.AcceptAsync(acceptArgs));
_log.WriteLine("IPv4 Server: Waiting for clients.");
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
client.Connect(IPAddress.Loopback, port);
client.Send(sendBuffer);
client.Shutdown(SocketShutdown.Both);
}
Assert.True(
accepted.WaitOne(TestSettings.PassingTestTimeout), "Test completed in alotted time");
Assert.Equal(
SocketError.Success, acceptArgs.SocketError);
Assert.Equal(
acceptBufferDataSize, acceptArgs.BytesTransferred);
Assert.Equal(
new ArraySegment<byte>(sendBuffer),
new ArraySegment<byte>(acceptArgs.Buffer, 0, acceptArgs.BytesTransferred));
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // Unix platforms don't yet support receiving data with AcceptAsync.
public void AcceptAsync_WithTooSmallReceiveBuffer_Failure()
{
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = server.BindToAnonymousPort(IPAddress.Loopback);
server.Listen(1);
SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs();
acceptArgs.Completed += OnAcceptCompleted;
acceptArgs.UserToken = new ManualResetEvent(false);
byte[] buffer = new byte[1];
acceptArgs.SetBuffer(buffer, 0, buffer.Length);
AssertExtensions.Throws<ArgumentException>(null, () => server.AcceptAsync(acceptArgs));
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[ActiveIssue(17209, TestPlatforms.AnyUnix)]
public void AcceptAsync_WithTargetSocket_Success()
{
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = listener.BindToAnonymousPort(IPAddress.Loopback);
listener.Listen(1);
Task<Socket> acceptTask = listener.AcceptAsync(server);
client.Connect(IPAddress.Loopback, port);
Assert.Same(server, acceptTask.Result);
}
}
[ActiveIssue(17209, TestPlatforms.AnyUnix)]
[OuterLoop] // TODO: Issue #11345
[Theory]
[InlineData(false)]
[InlineData(true)]
public void AcceptAsync_WithTargetSocket_ReuseAfterDisconnect_Success(bool reuseSocket)
{
using (var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (var server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (var saea = new SocketAsyncEventArgs())
{
int port = listener.BindToAnonymousPort(IPAddress.Loopback);
listener.Listen(1);
var are = new AutoResetEvent(false);
saea.Completed += delegate { are.Set(); };
saea.AcceptSocket = server;
using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
Assert.True(listener.AcceptAsync(saea));
client.Connect(IPAddress.Loopback, port);
are.WaitOne();
Assert.Same(server, saea.AcceptSocket);
Assert.True(server.Connected);
}
server.Disconnect(reuseSocket);
Assert.False(server.Connected);
if (reuseSocket)
{
using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
Assert.True(listener.AcceptAsync(saea));
client.Connect(IPAddress.Loopback, port);
are.WaitOne();
Assert.Same(server, saea.AcceptSocket);
Assert.True(server.Connected);
}
}
else
{
if (listener.AcceptAsync(saea))
{
are.WaitOne();
}
Assert.Equal(SocketError.InvalidArgument, saea.SocketError);
}
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[ActiveIssue(17209, TestPlatforms.AnyUnix)]
public void AcceptAsync_WithAlreadyBoundTargetSocket_Failed()
{
using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = listener.BindToAnonymousPort(IPAddress.Loopback);
listener.Listen(1);
server.BindToAnonymousPort(IPAddress.Loopback);
Assert.Throws<InvalidOperationException>(() => { listener.AcceptAsync(server); });
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[PlatformSpecific(TestPlatforms.AnyUnix)] // Unix platforms don't yet support receiving data with AcceptAsync.
public void AcceptAsync_WithReceiveBuffer_Failure()
{
//
// Unix platforms don't yet support receiving data with AcceptAsync.
//
Assert.True(Capability.IPv4Support());
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = server.BindToAnonymousPort(IPAddress.Loopback);
server.Listen(1);
SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs();
acceptArgs.Completed += OnAcceptCompleted;
acceptArgs.UserToken = new ManualResetEvent(false);
byte[] buffer = new byte[1024];
acceptArgs.SetBuffer(buffer, 0, buffer.Length);
Assert.Throws<PlatformNotSupportedException>(() => server.AcceptAsync(acceptArgs));
}
}
}
}

View File

@@ -254,7 +254,7 @@ namespace System.Net.Sockets.Tests
public void Send_Buffers_NullBuffers_Throws_ArgumentNull()
{
SocketError errorCode;
Assert.Throws<ArgumentNullException>(() => GetSocket().Send(null, SocketFlags.None, out errorCode));
Assert.Throws<ArgumentNullException>(() => GetSocket().Send((IList<ArraySegment<byte>>)null, SocketFlags.None, out errorCode));
}
[Fact]
@@ -321,7 +321,7 @@ namespace System.Net.Sockets.Tests
public void Receive_Buffers_NullBuffers_Throws_ArgumentNull()
{
SocketError errorCode;
Assert.Throws<ArgumentNullException>(() => GetSocket().Receive(null, SocketFlags.None, out errorCode));
Assert.Throws<ArgumentNullException>(() => GetSocket().Receive((IList<ArraySegment<byte>>)null, SocketFlags.None, out errorCode));
}
[Fact]

View File

@@ -3,6 +3,7 @@
<PropertyGroup>
<BuildConfigurations>
netstandard;
netcoreapp;
</BuildConfigurations>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,94 @@
// 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.Tasks;
using Xunit;
namespace System.Net.Sockets.Tests
{
public abstract class Connect<T> : SocketTestHelperBase<T> where T : SocketHelperBase, new()
{
[OuterLoop] // TODO: Issue #11345
[Theory]
[MemberData(nameof(Loopbacks))]
public void Connect_Success(IPAddress listenAt)
{
int port;
using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, listenAt, out port))
{
using (Socket client = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
Task connectTask = ConnectAsync(client, new IPEndPoint(listenAt, port));
Assert.True(connectTask.Wait(TestSettings.PassingTestTimeout), "IPv4: Timed out while waiting for connection");
Assert.True(client.Connected);
}
}
}
[OuterLoop] // TODO: Issue #11345
[Theory]
[MemberData(nameof(Loopbacks))]
public void Connect_MultipleIPAddresses_Success(IPAddress listenAt)
{
if (!SupportsMultiConnect)
return;
int port;
using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, listenAt, out port))
using (Socket client = new Socket(listenAt.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
Task connectTask = MultiConnectAsync(client, new IPAddress[] { IPAddress.Loopback, IPAddress.IPv6Loopback }, port);
Assert.True(connectTask.Wait(TestSettings.PassingTestTimeout), "Timed out while waiting for connection");
Assert.True(client.Connected);
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[ActiveIssue(22765, TestPlatforms.AnyUnix)]
public async Task Connect_OnConnectedSocket_Fails()
{
int port;
using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, IPAddress.Loopback, out port))
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
await ConnectAsync(client, new IPEndPoint(IPAddress.Loopback, port));
// In the sync case, we throw a derived exception here, so need to use ThrowsAnyAsync
SocketException se = await Assert.ThrowsAnyAsync<SocketException>(() => ConnectAsync(client, new IPEndPoint(IPAddress.Loopback, port)));
Assert.Equal(SocketError.IsConnected, se.SocketErrorCode);
}
}
[PlatformSpecific(TestPlatforms.Windows)] // Unix currently does not support Disconnect
[OuterLoop] // TODO: Issue #11345
[Fact]
public async Task Connect_AfterDisconnect_Fails()
{
int port;
using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, IPAddress.Loopback, out port))
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
await ConnectAsync(client, new IPEndPoint(IPAddress.Loopback, port));
client.Disconnect(reuseSocket: false);
if (ConnectAfterDisconnectResultsInInvalidOperationException)
{
await Assert.ThrowsAsync<InvalidOperationException>(() => ConnectAsync(client, new IPEndPoint(IPAddress.Loopback, port)));
}
else
{
SocketException se = await Assert.ThrowsAsync<SocketException>(() => ConnectAsync(client, new IPEndPoint(IPAddress.Loopback, port)));
Assert.Equal(SocketError.IsConnected, se.SocketErrorCode);
}
}
}
}
public sealed class ConnectSync : Connect<SocketHelperArraySync> { }
public sealed class ConnectSyncForceNonBlocking : Connect<SocketHelperSyncForceNonBlocking> { }
public sealed class ConnectApm : Connect<SocketHelperApm> { }
public sealed class ConnectTask : Connect<SocketHelperTask> { }
public sealed class ConnectEap : Connect<SocketHelperEap> { }
}

View File

@@ -1,116 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Net.Test.Common;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
namespace System.Net.Sockets.Tests
{
public class ConnectAsync
{
private readonly ITestOutputHelper _log;
public ConnectAsync(ITestOutputHelper output)
{
_log = TestLogging.GetInstance();
Assert.True(Capability.IPv4Support() || Capability.IPv6Support());
}
public void OnConnectCompleted(object sender, SocketAsyncEventArgs args)
{
EventWaitHandle handle = (EventWaitHandle)args.UserToken;
handle.Set();
}
[OuterLoop] // TODO: Issue #11345
[Theory]
[InlineData(SocketImplementationType.APM)]
[InlineData(SocketImplementationType.Async)]
[Trait("IPv4", "true")]
public void ConnectAsync_IPv4_Success(SocketImplementationType type)
{
Assert.True(Capability.IPv4Support());
AutoResetEvent completed = new AutoResetEvent(false);
int port;
using (SocketTestServer.SocketTestServerFactory(type, IPAddress.Loopback, out port))
{
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, port);
args.Completed += OnConnectCompleted;
args.UserToken = completed;
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
Assert.True(client.ConnectAsync(args));
Assert.True(completed.WaitOne(TestSettings.PassingTestTimeout), "IPv4: Timed out while waiting for connection");
Assert.Equal<SocketError>(SocketError.Success, args.SocketError);
}
}
}
[OuterLoop] // TODO: Issue #11345
[Theory]
[InlineData(SocketImplementationType.APM)]
[InlineData(SocketImplementationType.Async)]
[Trait("IPv6", "true")]
public void ConnectAsync_IPv6_Success(SocketImplementationType type)
{
Assert.True(Capability.IPv6Support());
AutoResetEvent completed = new AutoResetEvent(false);
int port;
using (SocketTestServer.SocketTestServerFactory(type, IPAddress.IPv6Loopback, out port))
{
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.RemoteEndPoint = new IPEndPoint(IPAddress.IPv6Loopback, port);
args.Completed += OnConnectCompleted;
args.UserToken = completed;
using (Socket client = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp))
{
Assert.True(client.ConnectAsync(args));
Assert.True(completed.WaitOne(TestSettings.PassingTestTimeout), "IPv6: Timed out while waiting for connection");
Assert.Equal<SocketError>(SocketError.Success, args.SocketError);
}
}
}
[OuterLoop] // TODO: Issue #11345
[Theory]
[InlineData(AddressFamily.InterNetwork)]
[InlineData(AddressFamily.InterNetworkV6)]
public async Task ConnectTaskAsync_IPAddresss_Success(AddressFamily family)
{
int port;
using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, family == AddressFamily.InterNetwork ? IPAddress.Loopback : IPAddress.IPv6Loopback, out port))
using (Socket client = new Socket(family, SocketType.Stream, ProtocolType.Tcp))
{
await client.ConnectAsync(new IPAddress[] { IPAddress.Loopback, IPAddress.IPv6Loopback }, port);
Assert.True(client.Connected);
}
}
[PlatformSpecific(TestPlatforms.Windows)] // Unix currently does not support Disconnect
[OuterLoop] // TODO: Issue #11345
[Fact]
public async Task Connect_AfterDisconnect_Fails()
{
int port;
using (SocketTestServer.SocketTestServerFactory(SocketImplementationType.Async, IPAddress.Loopback, out port))
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
await client.ConnectAsync(IPAddress.Loopback, port);
client.Disconnect(reuseSocket: false);
Assert.Throws<InvalidOperationException>(() => client.Connect(IPAddress.Loopback, port));
Assert.Throws<InvalidOperationException>(() => client.Connect(new IPEndPoint(IPAddress.Loopback, port)));
}
}
}
}

View File

@@ -1,78 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Net.Test.Common;
using System.Threading;
using Xunit;
using Xunit.Abstractions;
namespace System.Net.Sockets.Tests
{
public class ConnectExTest
{
private readonly ITestOutputHelper _log;
public ConnectExTest(ITestOutputHelper output)
{
_log = TestLogging.GetInstance();
}
private static void OnConnectAsyncCompleted(object sender, SocketAsyncEventArgs args)
{
ManualResetEvent complete = (ManualResetEvent)args.UserToken;
complete.Set();
}
[OuterLoop] // TODO: Issue #11345
[Theory]
[InlineData(SocketImplementationType.APM)]
[InlineData(SocketImplementationType.Async)]
[Trait("IPv4", "true")]
[Trait("IPv6", "true")]
public void ConnectEx_Success(SocketImplementationType type)
{
Assert.True(Capability.IPv4Support() && Capability.IPv6Support());
int port;
SocketTestServer server = SocketTestServer.SocketTestServerFactory(type, IPAddress.Loopback, out port);
int port6;
SocketTestServer server6 = SocketTestServer.SocketTestServerFactory(type, IPAddress.IPv6Loopback, out port6);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, port);
args.Completed += OnConnectAsyncCompleted;
ManualResetEvent complete = new ManualResetEvent(false);
args.UserToken = complete;
Assert.True(sock.ConnectAsync(args));
Assert.True(complete.WaitOne(TestSettings.PassingTestTimeout), "IPv4: Timed out while waiting for connection");
Assert.True(args.SocketError == SocketError.Success);
sock.Dispose();
sock = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp);
args.RemoteEndPoint = new IPEndPoint(IPAddress.IPv6Loopback, port6);
complete.Reset();
Assert.True(sock.ConnectAsync(args));
Assert.True(complete.WaitOne(TestSettings.PassingTestTimeout), "IPv6: Timed out while waiting for connection");
Assert.True(args.SocketError == SocketError.Success);
}
finally
{
sock.Dispose();
server.Dispose();
server6.Dispose();
}
}
}
}

View File

@@ -1 +1 @@
ef120ada456f292695655c3e53e9b882ec68bd5d
fba1acd2981dbca4cd81d47d3c20272000a172bb

View File

@@ -6,7 +6,6 @@ using System.Collections.Concurrent;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using Xunit;
using Xunit.Abstractions;
namespace System.Net.Sockets.Tests
{
@@ -41,17 +40,17 @@ namespace System.Net.Sockets.Tests
{
// Invoke several tests to execute code paths while tracing is enabled
new SendReceiveSync(new NullTestOutputHelper()).SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter();
new SendReceiveSync(new NullTestOutputHelper()).SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter();
new SendReceiveSync().SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter();
new SendReceiveSync().SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter();
new SendReceiveTask(new NullTestOutputHelper()).SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter();
new SendReceiveTask(new NullTestOutputHelper()).SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter();
new SendReceiveTask().SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter();
new SendReceiveTask().SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter();
new SendReceiveEap(new NullTestOutputHelper()).SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter();
new SendReceiveEap(new NullTestOutputHelper()).SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter();
new SendReceiveEap().SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter();
new SendReceiveEap().SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter();
new SendReceiveApm(new NullTestOutputHelper()).SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter();
new SendReceiveApm(new NullTestOutputHelper()).SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter();
new SendReceiveApm().SendRecv_Stream_TCP(IPAddress.Loopback, false).GetAwaiter();
new SendReceiveApm().SendRecv_Stream_TCP(IPAddress.Loopback, true).GetAwaiter();
new NetworkStreamTest().CopyToAsync_AllDataCopied(4096).GetAwaiter().GetResult();
new NetworkStreamTest().Timeout_ValidData_Roundtrips().GetAwaiter().GetResult();
@@ -62,11 +61,5 @@ namespace System.Net.Sockets.Tests
return SuccessExitCode;
}).Dispose();
}
private sealed class NullTestOutputHelper : ITestOutputHelper
{
public void WriteLine(string message) { }
public void WriteLine(string format, params object[] args) { }
}
}
}

View File

@@ -10,7 +10,7 @@ using Xunit;
namespace System.Net.Sockets.Tests
{
public class NetworkStreamTest
public partial class NetworkStreamTest
{
[Fact]
public void Ctor_NullSocket_ThrowsArgumentNullExceptions()
@@ -455,7 +455,7 @@ namespace System.Net.Sockets.Tests
}
[Fact]
public async Task ReadWrite_Success()
public async Task ReadWrite_Array_Success()
{
await RunWithConnectedNetworkStreamsAsync((server, client) =>
{

View File

@@ -0,0 +1,59 @@
// 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;
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_Precanceled_Throws()
{
await RunWithConnectedNetworkStreamsAsync(async (server, client) =>
{
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => server.WriteAsync((ArraySegment<byte>)new byte[0], new CancellationToken(true)));
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => server.ReadAsync((ArraySegment<byte>)new byte[0], new CancellationToken(true)).AsTask());
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => server.WriteAsync((ReadOnlyMemory<byte>)new byte[0], new CancellationToken(true)));
await Assert.ThrowsAnyAsync<OperationCanceledException>(() => server.ReadAsync((Memory<byte>)new byte[0], new CancellationToken(true)).AsTask());
});
}
}
}

View File

@@ -11,8 +11,10 @@ namespace System.Net.Sockets.Tests
public class ReceiveMessageFrom
{
[OuterLoop] // TODO: Issue #11345
[Fact]
public void Success()
[Theory]
[InlineData(false)]
[InlineData(true)]
public void Success(bool forceNonBlocking)
{
if (Socket.OSSupportsIPv4)
{
@@ -21,9 +23,13 @@ namespace System.Net.Sockets.Tests
int port = receiver.BindToAnonymousPort(IPAddress.Loopback);
receiver.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
receiver.ForceNonBlocking(forceNonBlocking);
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sender.Bind(new IPEndPoint(IPAddress.Loopback, 0));
sender.ForceNonBlocking(forceNonBlocking);
for (int i = 0; i < TestSettings.UDPRedundancy; i++)
{
sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.Loopback, port));
@@ -45,8 +51,10 @@ namespace System.Net.Sockets.Tests
}
[OuterLoop] // TODO: Issue #11345
[Fact]
public void Success_IPv6()
[Theory]
[InlineData(false)]
[InlineData(true)]
public void Success_IPv6(bool forceNonBlocking)
{
if (Socket.OSSupportsIPv6)
{
@@ -55,9 +63,13 @@ namespace System.Net.Sockets.Tests
int port = receiver.BindToAnonymousPort(IPAddress.IPv6Loopback);
receiver.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.PacketInformation, true);
receiver.ForceNonBlocking(forceNonBlocking);
Socket sender = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
sender.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 0));
sender.ForceNonBlocking(forceNonBlocking);
for (int i = 0; i < TestSettings.UDPRedundancy; i++)
{
sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.IPv6Loopback, port));

View File

@@ -146,7 +146,7 @@ namespace System.Net.Sockets.Tests
}
[PlatformSpecific(~TestPlatforms.OSX)] // typical OSX install has very low max open file descriptors value
[ConditionalFact(nameof(PlatformDetection) + "." + nameof(PlatformDetection.IsNotWindowsSubsystemForLinux))] // https://github.com/Microsoft/BashOnWindows/issues/989
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsSubsystemForLinux))] // https://github.com/Microsoft/BashOnWindows/issues/308
public void Select_Error_OneReadyAtATime()
{
const int Errors = 90; // value larger than the internal value in SocketPal.Unix that swaps between stack and heap allocation

View File

@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -27,6 +28,15 @@ namespace System.Net.Sockets.Tests
}
}
public static IEnumerable<object[]> SendFileSync_MemberData()
{
foreach (object[] memberData in SendFile_MemberData())
{
yield return memberData.Concat(new object[] { true }).ToArray();
yield return memberData.Concat(new object[] { false }).ToArray();
}
}
private string CreateFileToSend(int size, bool sendPreAndPostBuffers, out byte[] preBuffer, out byte[] postBuffer, out Fletcher32 checksum)
{
// Create file to send
@@ -97,8 +107,8 @@ namespace System.Net.Sockets.Tests
[OuterLoop] // TODO: Issue #11345
[Theory]
[MemberData(nameof(SendFile_MemberData))]
public void SendFile_Synchronous(IPAddress listenAt, bool sendPreAndPostBuffers, int bytesToSend)
[MemberData(nameof(SendFileSync_MemberData))]
public void SendFile_Synchronous(IPAddress listenAt, bool sendPreAndPostBuffers, int bytesToSend, bool forceNonBlocking)
{
const int ListenBacklog = 1;
const int TestTimeout = 30000;
@@ -115,6 +125,8 @@ namespace System.Net.Sockets.Tests
server.Listen(ListenBacklog);
server.ForceNonBlocking(forceNonBlocking);
int bytesReceived = 0;
var receivedChecksum = new Fletcher32();
var serverThread = new Thread(() =>
@@ -124,6 +136,8 @@ namespace System.Net.Sockets.Tests
Socket remote = server.Accept();
Assert.NotNull(remote);
remote.ForceNonBlocking(forceNonBlocking);
using (remote)
{
var recvBuffer = new byte[256];
@@ -146,6 +160,9 @@ namespace System.Net.Sockets.Tests
// Run client
EndPoint clientEndpoint = server.LocalEndPoint;
var client = new Socket(clientEndpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
client.ForceNonBlocking(forceNonBlocking);
client.Connect(clientEndpoint);
using (client)

View File

@@ -3,37 +3,14 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
namespace System.Net.Sockets.Tests
{
public abstract class SendReceive : MemberDatas
public abstract class SendReceive<T> : SocketTestHelperBase<T> where T : SocketHelperBase, new()
{
private readonly ITestOutputHelper _log;
public SendReceive(ITestOutputHelper output)
{
_log = output;
}
public abstract Task<Socket> AcceptAsync(Socket s);
public abstract Task ConnectAsync(Socket s, EndPoint endPoint);
public abstract Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer);
public abstract Task<SocketReceiveFromResult> ReceiveFromAsync(
Socket s, ArraySegment<byte> buffer, EndPoint endPoint);
public abstract Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList);
public abstract Task<int> SendAsync(Socket s, ArraySegment<byte> buffer);
public abstract Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList);
public abstract Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endpoint);
public virtual bool GuaranteedSendOrdering => true;
public virtual bool ValidatesArrayArguments => true;
public virtual bool UsesSync => false;
public virtual bool DisposeDuringOperationResultsInDisposedException => false;
[Theory]
[InlineData(null, 0, 0)] // null array
[InlineData(1, -1, 0)] // offset low
@@ -858,6 +835,207 @@ namespace System.Net.Sockets.Tests
}
}
public class SendReceive
{
[Fact]
public void SendRecvIovMaxTcp_Success()
{
// sending/receiving more than IOV_MAX segments causes EMSGSIZE on some platforms.
// This is handled internally for stream sockets so this error shouldn't surface.
// Use more than IOV_MAX (1024 on Linux & macOS) segments.
const int SegmentCount = 2400;
using (var server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
server.BindToAnonymousPort(IPAddress.Loopback);
server.Listen(1);
var sendBuffer = new byte[SegmentCount];
Task serverProcessingTask = Task.Run(() =>
{
using (Socket acceptSocket = server.Accept())
{
// send data as SegmentCount (> IOV_MAX) 1-byte segments.
var sendSegments = new List<ArraySegment<byte>>();
for (int i = 0; i < SegmentCount; i++)
{
sendBuffer[i] = (byte)i;
sendSegments.Add(new ArraySegment<byte>(sendBuffer, i, 1));
}
SocketError error;
// Send blocks until all segments are sent.
int bytesSent = acceptSocket.Send(sendSegments, SocketFlags.None, out error);
Assert.Equal(SegmentCount, bytesSent);
Assert.Equal(SocketError.Success, error);
}
});
using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
client.Connect(server.LocalEndPoint);
// receive data as 1-byte segments.
var receiveBuffer = new byte[SegmentCount];
var receiveSegments = new List<ArraySegment<byte>>();
for (int i = 0; i < SegmentCount; i++)
{
receiveSegments.Add(new ArraySegment<byte>(receiveBuffer, i, 1));
}
var bytesReceivedTotal = 0;
do
{
SocketError error;
// Receive can return up to IOV_MAX segments.
int bytesReceived = client.Receive(receiveSegments, SocketFlags.None, out error);
bytesReceivedTotal += bytesReceived;
// Offset receiveSegments for next Receive.
receiveSegments.RemoveRange(0, bytesReceived);
Assert.NotEqual(0, bytesReceived);
Assert.Equal(SocketError.Success, error);
} while (bytesReceivedTotal != SegmentCount);
Assert.Equal(sendBuffer, receiveBuffer);
}
}
}
[Fact]
public void SendIovMaxUdp_SuccessOrMessageSize()
{
// sending more than IOV_MAX segments causes EMSGSIZE on some platforms.
// We handle this for stream sockets by truncating.
// This test verifies we are not truncating non-stream sockets.
// Use more than IOV_MAX (1024 on Linux & macOS) segments
// and less than Ethernet MTU.
const int SegmentCount = 1200;
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
socket.BindToAnonymousPort(IPAddress.Loopback);
// Use our own address as destination.
socket.Connect(socket.LocalEndPoint);
var sendBuffer = new byte[SegmentCount];
var sendSegments = new List<ArraySegment<byte>>();
for (int i = 0; i < SegmentCount; i++)
{
sendBuffer[i] = (byte)i;
sendSegments.Add(new ArraySegment<byte>(sendBuffer, i, 1));
}
SocketError error;
// send data as SegmentCount (> IOV_MAX) 1-byte segments.
int bytesSent = socket.Send(sendSegments, SocketFlags.None, out error);
if (error == SocketError.Success)
{
// platform sent message with > IOV_MAX segments
Assert.Equal(SegmentCount, bytesSent);
}
else
{
// platform returns EMSGSIZE
Assert.Equal(SocketError.MessageSize, error);
Assert.Equal(0, bytesSent);
}
}
}
[Fact]
public async Task ReceiveIovMaxUdp_SuccessOrMessageSize()
{
// receiving more than IOV_MAX segments causes EMSGSIZE on some platforms.
// We handle this for stream sockets by truncating.
// This test verifies we are not truncating non-stream sockets.
// Use more than IOV_MAX (1024 on Linux & macOS) segments
// and less than Ethernet MTU.
const int SegmentCount = 1200;
var sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sender.BindToAnonymousPort(IPAddress.Loopback);
var receiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
receiver.Connect(sender.LocalEndPoint); // only receive from sender
EndPoint receiverEndPoint = receiver.LocalEndPoint;
Task receiveTask = Task.Run(() =>
{
using (receiver)
{
var receiveBuffer = new byte[SegmentCount];
var receiveSegments = new List<ArraySegment<byte>>();
for (int i = 0; i < SegmentCount; i++)
{
receiveSegments.Add(new ArraySegment<byte>(receiveBuffer, i, 1));
}
// receive data as SegmentCount (> IOV_MAX) 1-byte segments.
SocketError error;
int bytesReceived = receiver.Receive(receiveSegments, SocketFlags.None, out error);
if (error == SocketError.Success)
{
// platform received message in > IOV_MAX segments
Assert.Equal(SegmentCount, bytesReceived);
}
else
{
// platform returns EMSGSIZE
Assert.Equal(SocketError.MessageSize, error);
Assert.Equal(0, bytesReceived);
}
}
});
using (sender)
{
sender.Connect(receiverEndPoint);
var sendBuffer = new byte[SegmentCount];
for (int i = 0; i < 10; i++) // UDPRedundancy
{
int bytesSent = sender.Send(sendBuffer);
Assert.Equal(SegmentCount, bytesSent);
await Task.WhenAny(receiveTask, Task.Delay(1));
if (receiveTask.IsCompleted)
{
break;
}
}
}
Assert.True(receiveTask.IsCompleted);
await receiveTask;
}
[Fact]
[PlatformSpecific(~TestPlatforms.Windows)] // All data is sent, even when very large (100M).
public void SocketSendWouldBlock_ReturnsBytesSent()
{
using (var server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
// listen
server.BindToAnonymousPort(IPAddress.Loopback);
server.Listen(1);
// connect
client.Connect(server.LocalEndPoint);
// accept
using (Socket socket = server.Accept())
{
// We send a large amount of data but don't read it.
// A chunck will be sent, attempts to send more will return SocketError.WouldBlock.
// Socket.Send must return the success of the partial send.
socket.Blocking = false;
var data = new byte[5_000_000];
SocketError error;
int bytesSent = socket.Send(data, 0, data.Length, SocketFlags.None, out error);
Assert.Equal(SocketError.Success, error);
Assert.InRange(bytesSent, 1, data.Length - 1);
}
}
}
}
public sealed class SendReceiveUdpClient : MemberDatas
{
[OuterLoop] // TODO: Issue #11345
@@ -870,8 +1048,8 @@ namespace System.Net.Sockets.Tests
// TODO #5185: harden against packet loss
const int DatagramSize = 256;
const int DatagramsToSend = 256;
const int AckTimeout = 1000;
const int TestTimeout = 30000;
const int AckTimeout = 10000;
const int TestTimeout = 60000;
using (var left = new UdpClient(new IPEndPoint(leftAddress, 0)))
using (var right = new UdpClient(new IPEndPoint(rightAddress, 0)))
@@ -1014,229 +1192,9 @@ namespace System.Net.Sockets.Tests
}
}
public sealed class SendReceiveSync : SendReceive
{
public SendReceiveSync(ITestOutputHelper output) : base(output) { }
public override Task<Socket> AcceptAsync(Socket s) =>
Task.Run(() => s.Accept());
public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
Task.Run(() => s.Connect(endPoint));
public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
Task.Run(() => s.Receive(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None));
public override Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
Task.Run(() => s.Receive(bufferList, SocketFlags.None));
public override Task<SocketReceiveFromResult> ReceiveFromAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
Task.Run(() =>
{
int received = s.ReceiveFrom(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, ref endPoint);
return new SocketReceiveFromResult
{
ReceivedBytes = received,
RemoteEndPoint = endPoint
};
});
public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
Task.Run(() => s.Send(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None));
public override Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
Task.Run(() => s.Send(bufferList, SocketFlags.None));
public override Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
Task.Run(() => s.SendTo(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, endPoint));
public override bool GuaranteedSendOrdering => false;
public override bool UsesSync => true;
}
public sealed class SendReceiveApm : SendReceive
{
public SendReceiveApm(ITestOutputHelper output) : base(output) { }
public override bool DisposeDuringOperationResultsInDisposedException => true;
public override Task<Socket> AcceptAsync(Socket s) =>
Task.Factory.FromAsync(s.BeginAccept, s.EndAccept, null);
public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
Task.Factory.FromAsync(s.BeginConnect, s.EndConnect, endPoint, null);
public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
Task.Factory.FromAsync((callback, state) =>
s.BeginReceive(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, callback, state),
s.EndReceive, null);
public override Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
Task.Factory.FromAsync(s.BeginReceive, s.EndReceive, bufferList, SocketFlags.None, null);
public override Task<SocketReceiveFromResult> ReceiveFromAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint)
{
var tcs = new TaskCompletionSource<SocketReceiveFromResult>();
s.BeginReceiveFrom(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, ref endPoint, iar =>
{
try
{
int receivedBytes = s.EndReceiveFrom(iar, ref endPoint);
tcs.TrySetResult(new SocketReceiveFromResult
{
ReceivedBytes = receivedBytes,
RemoteEndPoint = endPoint
});
}
catch (Exception e) { tcs.TrySetException(e); }
}, null);
return tcs.Task;
}
public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
Task.Factory.FromAsync((callback, state) =>
s.BeginSend(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, callback, state),
s.EndSend, null);
public override Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
Task.Factory.FromAsync(s.BeginSend, s.EndSend, bufferList, SocketFlags.None, null);
public override Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
Task.Factory.FromAsync(
(callback, state) => s.BeginSendTo(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, endPoint, callback, state),
s.EndSendTo, null);
}
public sealed class SendReceiveTask : SendReceive
{
public SendReceiveTask(ITestOutputHelper output) : base(output) { }
public override bool DisposeDuringOperationResultsInDisposedException =>
PlatformDetection.IsFullFramework; // due to SocketTaskExtensions.netfx implementation wrapping APM rather than EAP
public override Task<Socket> AcceptAsync(Socket s) =>
s.AcceptAsync();
public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
s.ConnectAsync(endPoint);
public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
s.ReceiveAsync(buffer, SocketFlags.None);
public override Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
s.ReceiveAsync(bufferList, SocketFlags.None);
public override Task<SocketReceiveFromResult> ReceiveFromAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
s.ReceiveFromAsync(buffer, SocketFlags.None, endPoint);
public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
s.SendAsync(buffer, SocketFlags.None);
public override Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
s.SendAsync(bufferList, SocketFlags.None);
public override Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
s.SendToAsync(buffer, SocketFlags.None, endPoint);
}
public sealed class SendReceiveEap : SendReceive
{
public SendReceiveEap(ITestOutputHelper output) : base(output) { }
public override bool ValidatesArrayArguments => false;
public override Task<Socket> AcceptAsync(Socket s) =>
InvokeAsync(s, e => e.AcceptSocket, e => s.AcceptAsync(e));
public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
InvokeAsync(s, e => true, e =>
{
e.RemoteEndPoint = endPoint;
return s.ConnectAsync(e);
});
public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
InvokeAsync(s, e => e.BytesTransferred, e =>
{
e.SetBuffer(buffer.Array, buffer.Offset, buffer.Count);
return s.ReceiveAsync(e);
});
public override Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
InvokeAsync(s, e => e.BytesTransferred, e =>
{
e.BufferList = bufferList;
return s.ReceiveAsync(e);
});
public override Task<SocketReceiveFromResult> ReceiveFromAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
InvokeAsync(s, e => new SocketReceiveFromResult { ReceivedBytes = e.BytesTransferred, RemoteEndPoint = e.RemoteEndPoint }, e =>
{
e.SetBuffer(buffer.Array, buffer.Offset, buffer.Count);
e.RemoteEndPoint = endPoint;
return s.ReceiveFromAsync(e);
});
public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
InvokeAsync(s, e => e.BytesTransferred, e =>
{
e.SetBuffer(buffer.Array, buffer.Offset, buffer.Count);
return s.SendAsync(e);
});
public override Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
InvokeAsync(s, e => e.BytesTransferred, e =>
{
e.BufferList = bufferList;
return s.SendAsync(e);
});
public override Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
InvokeAsync(s, e => e.BytesTransferred, e =>
{
e.SetBuffer(buffer.Array, buffer.Offset, buffer.Count);
e.RemoteEndPoint = endPoint;
return s.SendToAsync(e);
});
private static Task<TResult> InvokeAsync<TResult>(
Socket s,
Func<SocketAsyncEventArgs, TResult> getResult,
Func<SocketAsyncEventArgs, bool> invoke)
{
var tcs = new TaskCompletionSource<TResult>();
var saea = new SocketAsyncEventArgs();
EventHandler<SocketAsyncEventArgs> handler = (_, e) =>
{
if (e.SocketError == SocketError.Success) tcs.SetResult(getResult(e));
else tcs.SetException(new SocketException((int)e.SocketError));
saea.Dispose();
};
saea.Completed += handler;
if (!invoke(saea)) handler(s, saea);
return tcs.Task;
}
[Theory]
[InlineData(1, -1, 0)] // offset low
[InlineData(1, 2, 0)] // offset high
[InlineData(1, 0, -1)] // count low
[InlineData(1, 1, 2)] // count high
public void BufferList_InvalidArguments_Throws(int length, int offset, int count)
{
using (var e = new SocketAsyncEventArgs())
{
ArraySegment<byte> invalidBuffer = new FakeArraySegment { Array = new byte[length], Offset = offset, Count = count }.ToActual();
Assert.Throws<ArgumentOutOfRangeException>(() => e.BufferList = new List<ArraySegment<byte>> { invalidBuffer });
ArraySegment<byte> validBuffer = new ArraySegment<byte>(new byte[1]);
Assert.Throws<ArgumentOutOfRangeException>(() => e.BufferList = new List<ArraySegment<byte>> { validBuffer, invalidBuffer });
}
}
}
public abstract class MemberDatas
{
public static readonly object[][] Loopbacks = new[]
{
new object[] { IPAddress.Loopback },
new object[] { IPAddress.IPv6Loopback },
};
public static readonly object[][] LoopbacksAndBuffers = new object[][]
{
new object[] { IPAddress.IPv6Loopback, true },
new object[] { IPAddress.IPv6Loopback, false },
new object[] { IPAddress.Loopback, true },
new object[] { IPAddress.Loopback, false },
};
}
internal struct FakeArraySegment
{
public byte[] Array;
public int Offset;
public int Count;
public ArraySegment<byte> ToActual()
{
ArraySegmentWrapper wrapper = default(ArraySegmentWrapper);
wrapper.Fake = this;
return wrapper.Actual;
}
}
[StructLayout(LayoutKind.Explicit)]
internal struct ArraySegmentWrapper
{
[FieldOffset(0)] public ArraySegment<byte> Actual;
[FieldOffset(0)] public FakeArraySegment Fake;
}
public sealed class SendReceiveSync : SendReceive<SocketHelperArraySync> { }
public sealed class SendReceiveSyncForceNonBlocking : SendReceive<SocketHelperSyncForceNonBlocking> { }
public sealed class SendReceiveApm : SendReceive<SocketHelperApm> { }
public sealed class SendReceiveTask : SendReceive<SocketHelperTask> { }
public sealed class SendReceiveEap : SendReceive<SocketHelperEap> { }
}

View File

@@ -0,0 +1,10 @@
// 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.
namespace System.Net.Sockets.Tests
{
public sealed class SendReceiveSpanSync : SendReceive<SocketHelperSpanSync> { }
public sealed class SendReceiveSpanSyncForceNonBlocking : SendReceive<SocketHelperSpanSyncForceNonBlocking> { }
public sealed class SendReceiveMemoryArrayTask : SendReceive<SocketHelperMemoryArrayTask> { }
}

View File

@@ -42,6 +42,7 @@ namespace System.Net.Sockets.Tests
var client = (Socket)args.UserToken;
if (args.BytesTransferred == 0)
{
client.Shutdown(SocketShutdown.Send);
client.Dispose();
break;
}

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Net.Test.Common;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
@@ -249,6 +250,23 @@ namespace System.Net.Sockets.Tests
}
}
[Theory]
[InlineData(1, -1, 0)] // offset low
[InlineData(1, 2, 0)] // offset high
[InlineData(1, 0, -1)] // count low
[InlineData(1, 1, 2)] // count high
public void BufferList_InvalidArguments_Throws(int length, int offset, int count)
{
using (var e = new SocketAsyncEventArgs())
{
ArraySegment<byte> invalidBuffer = new FakeArraySegment { Array = new byte[length], Offset = offset, Count = count }.ToActual();
Assert.Throws<ArgumentOutOfRangeException>(() => e.BufferList = new List<ArraySegment<byte>> { invalidBuffer });
ArraySegment<byte> validBuffer = new ArraySegment<byte>(new byte[1]);
Assert.Throws<ArgumentOutOfRangeException>(() => e.BufferList = new List<ArraySegment<byte>> { validBuffer, invalidBuffer });
}
}
[Fact]
public async Task Completed_RegisterThenInvoked_UnregisterThenNotInvoked()
{
@@ -333,7 +351,8 @@ namespace System.Net.Sockets.Tests
connectSaea.Completed += (s, e) => tcs.SetResult(e.SocketError);
connectSaea.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, ((IPEndPoint)listen.LocalEndPoint).Port);
Assert.True(Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, connectSaea), $"ConnectAsync completed synchronously with SocketError == {connectSaea.SocketError}");
bool pending = Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, connectSaea);
if (!pending) tcs.SetResult(connectSaea.SocketError);
if (tcs.Task.IsCompleted)
{
Assert.NotEqual(SocketError.Success, tcs.Task.Result);
@@ -454,5 +473,105 @@ namespace System.Net.Sockets.Tests
}
}
}
public void OnAcceptCompleted(object sender, SocketAsyncEventArgs args)
{
EventWaitHandle handle = (EventWaitHandle)args.UserToken;
handle.Set();
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // Unix platforms don't yet support receiving data with AcceptAsync.
public void AcceptAsync_WithReceiveBuffer_Success()
{
Assert.True(Capability.IPv4Support());
AutoResetEvent accepted = new AutoResetEvent(false);
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = server.BindToAnonymousPort(IPAddress.Loopback);
server.Listen(1);
const int acceptBufferOverheadSize = 288; // see https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.acceptasync(v=vs.110).aspx
const int acceptBufferDataSize = 256;
const int acceptBufferSize = acceptBufferOverheadSize + acceptBufferDataSize;
byte[] sendBuffer = new byte[acceptBufferDataSize];
new Random().NextBytes(sendBuffer);
SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs();
acceptArgs.Completed += OnAcceptCompleted;
acceptArgs.UserToken = accepted;
acceptArgs.SetBuffer(new byte[acceptBufferSize], 0, acceptBufferSize);
Assert.True(server.AcceptAsync(acceptArgs));
using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
client.Connect(IPAddress.Loopback, port);
client.Send(sendBuffer);
client.Shutdown(SocketShutdown.Both);
}
Assert.True(
accepted.WaitOne(TestSettings.PassingTestTimeout), "Test completed in allotted time");
Assert.Equal(
SocketError.Success, acceptArgs.SocketError);
Assert.Equal(
acceptBufferDataSize, acceptArgs.BytesTransferred);
Assert.Equal(
new ArraySegment<byte>(sendBuffer),
new ArraySegment<byte>(acceptArgs.Buffer, 0, acceptArgs.BytesTransferred));
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[PlatformSpecific(TestPlatforms.Windows)] // Unix platforms don't yet support receiving data with AcceptAsync.
public void AcceptAsync_WithTooSmallReceiveBuffer_Failure()
{
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = server.BindToAnonymousPort(IPAddress.Loopback);
server.Listen(1);
SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs();
acceptArgs.Completed += OnAcceptCompleted;
acceptArgs.UserToken = new ManualResetEvent(false);
byte[] buffer = new byte[1];
acceptArgs.SetBuffer(buffer, 0, buffer.Length);
AssertExtensions.Throws<ArgumentException>(null, () => server.AcceptAsync(acceptArgs));
}
}
[OuterLoop] // TODO: Issue #11345
[Fact]
[PlatformSpecific(TestPlatforms.AnyUnix)] // Unix platforms don't yet support receiving data with AcceptAsync.
public void AcceptAsync_WithReceiveBuffer_Failure()
{
Assert.True(Capability.IPv4Support());
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
int port = server.BindToAnonymousPort(IPAddress.Loopback);
server.Listen(1);
SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs();
acceptArgs.Completed += OnAcceptCompleted;
acceptArgs.UserToken = new ManualResetEvent(false);
byte[] buffer = new byte[1024];
acceptArgs.SetBuffer(buffer, 0, buffer.Length);
Assert.Throws<PlatformNotSupportedException>(() => server.AcceptAsync(acceptArgs));
}
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Net.Test.Common;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
@@ -86,6 +87,11 @@ namespace System.Net.Sockets.Tests
[Fact]
public async Task MulticastInterface_Set_AnyInterface_Succeeds()
{
if (PlatformDetection.IsFedora)
{
return; // [ActiveIssue(24008)]
}
// On all platforms, index 0 means "any interface"
await MulticastInterface_Set_Helper(0);
}
@@ -130,6 +136,10 @@ namespace System.Net.Sockets.Tests
sendSocket.SendTo(Encoding.UTF8.GetBytes(message), new IPEndPoint(multicastAddress, port));
}
var cts = new CancellationTokenSource();
Assert.True(await Task.WhenAny(receiveTask, Task.Delay(20_000, cts.Token)) == receiveTask, "Waiting for received data timed out");
cts.Cancel();
int bytesReceived = await receiveTask;
string receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, bytesReceived);
@@ -150,7 +160,7 @@ namespace System.Net.Sockets.Tests
}
[OuterLoop] // TODO: Issue #11345
[ConditionalTheory(nameof(PlatformDetection) + "." + nameof(PlatformDetection.IsNotWindowsSubsystemForLinux))] // In WSL, the connect() call fails immediately.
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotWindowsSubsystemForLinux))] // In WSL, the connect() call fails immediately.
[InlineData(false)]
[InlineData(true)]
public void FailedConnect_GetSocketOption_SocketOptionNameError(bool simpleGet)

View File

@@ -0,0 +1,313 @@
// 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.Runtime.InteropServices;
using System.Threading.Tasks;
namespace System.Net.Sockets.Tests
{
// Abstract base class for various different socket "modes" (sync, async, etc)
// See SendReceive.cs for usage
public abstract class SocketHelperBase
{
public abstract Task<Socket> AcceptAsync(Socket s);
public abstract Task<Socket> AcceptAsync(Socket s, Socket acceptSocket);
public abstract Task ConnectAsync(Socket s, EndPoint endPoint);
public abstract Task MultiConnectAsync(Socket s, IPAddress[] addresses, int port);
public abstract Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer);
public abstract Task<SocketReceiveFromResult> ReceiveFromAsync(
Socket s, ArraySegment<byte> buffer, EndPoint endPoint);
public abstract Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList);
public abstract Task<int> SendAsync(Socket s, ArraySegment<byte> buffer);
public abstract Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList);
public abstract Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endpoint);
public virtual bool GuaranteedSendOrdering => true;
public virtual bool ValidatesArrayArguments => true;
public virtual bool UsesSync => false;
public virtual bool DisposeDuringOperationResultsInDisposedException => false;
public virtual bool ConnectAfterDisconnectResultsInInvalidOperationException => false;
public virtual bool SupportsMultiConnect => true;
public virtual bool SupportsAcceptIntoExistingSocket => true;
}
public class SocketHelperArraySync : SocketHelperBase
{
public override Task<Socket> AcceptAsync(Socket s) =>
Task.Run(() => s.Accept());
public override Task<Socket> AcceptAsync(Socket s, Socket acceptSocket) => throw new NotSupportedException();
public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
Task.Run(() => s.Connect(endPoint));
public override Task MultiConnectAsync(Socket s, IPAddress[] addresses, int port) =>
Task.Run(() => s.Connect(addresses, port));
public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
Task.Run(() => s.Receive(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None));
public override Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
Task.Run(() => s.Receive(bufferList, SocketFlags.None));
public override Task<SocketReceiveFromResult> ReceiveFromAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
Task.Run(() =>
{
int received = s.ReceiveFrom(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, ref endPoint);
return new SocketReceiveFromResult
{
ReceivedBytes = received,
RemoteEndPoint = endPoint
};
});
public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
Task.Run(() => s.Send(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None));
public override Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
Task.Run(() => s.Send(bufferList, SocketFlags.None));
public override Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
Task.Run(() => s.SendTo(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, endPoint));
public override bool GuaranteedSendOrdering => false;
public override bool UsesSync => true;
public override bool ConnectAfterDisconnectResultsInInvalidOperationException => true;
public override bool SupportsAcceptIntoExistingSocket => false;
}
public sealed class SocketHelperSyncForceNonBlocking : SocketHelperArraySync
{
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 SocketHelperApm : SocketHelperBase
{
public override bool DisposeDuringOperationResultsInDisposedException => true;
public override Task<Socket> AcceptAsync(Socket s) =>
Task.Factory.FromAsync(s.BeginAccept, s.EndAccept, null);
public override Task<Socket> AcceptAsync(Socket s, Socket acceptSocket) =>
Task.Factory.FromAsync(s.BeginAccept, s.EndAccept, acceptSocket, 0, null);
public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
Task.Factory.FromAsync(s.BeginConnect, s.EndConnect, endPoint, null);
public override Task MultiConnectAsync(Socket s, IPAddress[] addresses, int port) =>
Task.Factory.FromAsync(s.BeginConnect, s.EndConnect, addresses, port, null);
public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
Task.Factory.FromAsync((callback, state) =>
s.BeginReceive(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, callback, state),
s.EndReceive, null);
public override Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
Task.Factory.FromAsync(s.BeginReceive, s.EndReceive, bufferList, SocketFlags.None, null);
public override Task<SocketReceiveFromResult> ReceiveFromAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint)
{
var tcs = new TaskCompletionSource<SocketReceiveFromResult>();
s.BeginReceiveFrom(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, ref endPoint, iar =>
{
try
{
int receivedBytes = s.EndReceiveFrom(iar, ref endPoint);
tcs.TrySetResult(new SocketReceiveFromResult
{
ReceivedBytes = receivedBytes,
RemoteEndPoint = endPoint
});
}
catch (Exception e) { tcs.TrySetException(e); }
}, null);
return tcs.Task;
}
public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
Task.Factory.FromAsync((callback, state) =>
s.BeginSend(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, callback, state),
s.EndSend, null);
public override Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
Task.Factory.FromAsync(s.BeginSend, s.EndSend, bufferList, SocketFlags.None, null);
public override Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
Task.Factory.FromAsync(
(callback, state) => s.BeginSendTo(buffer.Array, buffer.Offset, buffer.Count, SocketFlags.None, endPoint, callback, state),
s.EndSendTo, null);
}
public class SocketHelperTask : SocketHelperBase
{
public override bool DisposeDuringOperationResultsInDisposedException =>
PlatformDetection.IsFullFramework; // due to SocketTaskExtensions.netfx implementation wrapping APM rather than EAP
public override Task<Socket> AcceptAsync(Socket s) =>
s.AcceptAsync();
public override Task<Socket> AcceptAsync(Socket s, Socket acceptSocket) =>
s.AcceptAsync(acceptSocket);
public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
s.ConnectAsync(endPoint);
public override Task MultiConnectAsync(Socket s, IPAddress[] addresses, int port) =>
s.ConnectAsync(addresses, port);
public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
s.ReceiveAsync(buffer, SocketFlags.None);
public override Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
s.ReceiveAsync(bufferList, SocketFlags.None);
public override Task<SocketReceiveFromResult> ReceiveFromAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
s.ReceiveFromAsync(buffer, SocketFlags.None, endPoint);
public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
s.SendAsync(buffer, SocketFlags.None);
public override Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
s.SendAsync(bufferList, SocketFlags.None);
public override Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
s.SendToAsync(buffer, SocketFlags.None, endPoint);
}
public sealed class SocketHelperEap : SocketHelperBase
{
public override bool ValidatesArrayArguments => false;
public override Task<Socket> AcceptAsync(Socket s) =>
InvokeAsync(s, e => e.AcceptSocket, e => s.AcceptAsync(e));
public override Task<Socket> AcceptAsync(Socket s, Socket acceptSocket) =>
InvokeAsync(s, e => e.AcceptSocket, e =>
{
e.AcceptSocket = acceptSocket;
return s.AcceptAsync(e);
});
public override Task ConnectAsync(Socket s, EndPoint endPoint) =>
InvokeAsync(s, e => true, e =>
{
e.RemoteEndPoint = endPoint;
return s.ConnectAsync(e);
});
public override Task MultiConnectAsync(Socket s, IPAddress[] addresses, int port) => throw new NotSupportedException();
public override Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) =>
InvokeAsync(s, e => e.BytesTransferred, e =>
{
e.SetBuffer(buffer.Array, buffer.Offset, buffer.Count);
return s.ReceiveAsync(e);
});
public override Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
InvokeAsync(s, e => e.BytesTransferred, e =>
{
e.BufferList = bufferList;
return s.ReceiveAsync(e);
});
public override Task<SocketReceiveFromResult> ReceiveFromAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
InvokeAsync(s, e => new SocketReceiveFromResult { ReceivedBytes = e.BytesTransferred, RemoteEndPoint = e.RemoteEndPoint }, e =>
{
e.SetBuffer(buffer.Array, buffer.Offset, buffer.Count);
e.RemoteEndPoint = endPoint;
return s.ReceiveFromAsync(e);
});
public override Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) =>
InvokeAsync(s, e => e.BytesTransferred, e =>
{
e.SetBuffer(buffer.Array, buffer.Offset, buffer.Count);
return s.SendAsync(e);
});
public override Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList) =>
InvokeAsync(s, e => e.BytesTransferred, e =>
{
e.BufferList = bufferList;
return s.SendAsync(e);
});
public override Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endPoint) =>
InvokeAsync(s, e => e.BytesTransferred, e =>
{
e.SetBuffer(buffer.Array, buffer.Offset, buffer.Count);
e.RemoteEndPoint = endPoint;
return s.SendToAsync(e);
});
private static Task<TResult> InvokeAsync<TResult>(
Socket s,
Func<SocketAsyncEventArgs, TResult> getResult,
Func<SocketAsyncEventArgs, bool> invoke)
{
var tcs = new TaskCompletionSource<TResult>();
var saea = new SocketAsyncEventArgs();
EventHandler<SocketAsyncEventArgs> handler = (_, e) =>
{
if (e.SocketError == SocketError.Success)
tcs.SetResult(getResult(e));
else
tcs.SetException(new SocketException((int)e.SocketError));
saea.Dispose();
};
saea.Completed += handler;
if (!invoke(saea))
handler(s, saea);
return tcs.Task;
}
public override bool SupportsMultiConnect => false;
}
public abstract class SocketTestHelperBase<T> : MemberDatas
where T : SocketHelperBase, new()
{
private readonly T _socketHelper;
public SocketTestHelperBase()
{
_socketHelper = new T();
}
//
// Methods that delegate to SocketHelper implementation
//
public Task<Socket> AcceptAsync(Socket s) => _socketHelper.AcceptAsync(s);
public Task<Socket> AcceptAsync(Socket s, Socket acceptSocket) => _socketHelper.AcceptAsync(s, acceptSocket);
public Task ConnectAsync(Socket s, EndPoint endPoint) => _socketHelper.ConnectAsync(s, endPoint);
public Task MultiConnectAsync(Socket s, IPAddress[] addresses, int port) => _socketHelper.MultiConnectAsync(s, addresses, port);
public Task<int> ReceiveAsync(Socket s, ArraySegment<byte> buffer) => _socketHelper.ReceiveAsync(s, buffer);
public Task<SocketReceiveFromResult> ReceiveFromAsync(
Socket s, ArraySegment<byte> buffer, EndPoint endPoint) => _socketHelper.ReceiveFromAsync(s, buffer, endPoint);
public Task<int> ReceiveAsync(Socket s, IList<ArraySegment<byte>> bufferList) => _socketHelper.ReceiveAsync(s, bufferList);
public Task<int> SendAsync(Socket s, ArraySegment<byte> buffer) => _socketHelper.SendAsync(s, buffer);
public Task<int> SendAsync(Socket s, IList<ArraySegment<byte>> bufferList) => _socketHelper.SendAsync(s, bufferList);
public Task<int> SendToAsync(Socket s, ArraySegment<byte> buffer, EndPoint endpoint) => _socketHelper.SendToAsync(s, buffer, endpoint);
public bool GuaranteedSendOrdering => _socketHelper.GuaranteedSendOrdering;
public bool ValidatesArrayArguments => _socketHelper.ValidatesArrayArguments;
public bool UsesSync => _socketHelper.UsesSync;
public bool DisposeDuringOperationResultsInDisposedException => _socketHelper.DisposeDuringOperationResultsInDisposedException;
public bool ConnectAfterDisconnectResultsInInvalidOperationException => _socketHelper.ConnectAfterDisconnectResultsInInvalidOperationException;
public bool SupportsMultiConnect => _socketHelper.SupportsMultiConnect;
public bool SupportsAcceptIntoExistingSocket => _socketHelper.SupportsAcceptIntoExistingSocket;
}
//
// MemberDatas that are generally useful
//
public abstract class MemberDatas
{
public static readonly object[][] Loopbacks = new[]
{
new object[] { IPAddress.Loopback },
new object[] { IPAddress.IPv6Loopback },
};
public static readonly object[][] LoopbacksAndBuffers = new object[][]
{
new object[] { IPAddress.IPv6Loopback, true },
new object[] { IPAddress.IPv6Loopback, false },
new object[] { IPAddress.Loopback, true },
new object[] { IPAddress.Loopback, false },
};
}
//
// Utility stuff
//
internal struct FakeArraySegment
{
public byte[] Array;
public int Offset;
public int Count;
public ArraySegment<byte> ToActual()
{
ArraySegmentWrapper wrapper = default(ArraySegmentWrapper);
wrapper.Fake = this;
return wrapper.Actual;
}
}
[StructLayout(LayoutKind.Explicit)]
internal struct ArraySegmentWrapper
{
[FieldOffset(0)] public ArraySegment<byte> Actual;
[FieldOffset(0)] public FakeArraySegment Fake;
}
}

Some files were not shown because too many files have changed in this diff Show More