Skip to content

Commit

Permalink
Harmonize ReceiveMessageFrom tests and bring them back to Inner Loop (#…
Browse files Browse the repository at this point in the history
…46862)

* extend SocketTestHelper

* SocketHelperMemoryNativeTask: implement UDP methods

* unified test for ReceiveSentMessages_Success

* oops, these overloads are not here yet

* ReceiveSentMessages_ReuseEventArgs_Success

* altering bufferMode does not work on Linux

* remove ReceiveMessageFromAsync.cs

* use AssertExtensions.SequenceEqual
  • Loading branch information
antonfirsov authored Jan 13, 2021
1 parent a568dcc commit b95de55
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 213 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,173 +3,124 @@

using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace System.Net.Sockets.Tests
{
public class ReceiveMessageFrom
public abstract class ReceiveMessageFrom<T> : SocketTestHelperBase<T> where T : SocketHelperBase, new()
{
[OuterLoop]
[Theory]
[InlineData(false)]
[InlineData(true)]
public void Success(bool forceNonBlocking)
{
if (Socket.OSSupportsIPv4)
{
using (Socket receiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
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);

sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.Loopback, port));
protected ReceiveMessageFrom(ITestOutputHelper output) : base(output) { }

IPPacketInformation packetInformation;
SocketFlags flags = SocketFlags.None;
EndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);

int len = receiver.ReceiveMessageFrom(new byte[1024], 0, 1024, ref flags, ref remoteEP, out packetInformation);

Assert.Equal(1024, len);
Assert.Equal(sender.LocalEndPoint, remoteEP);
Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, packetInformation.Address);

sender.Dispose();
}
}
}

[OuterLoop]
[Theory]
[InlineData(false)]
[InlineData(true)]
public void Success_IPv6(bool forceNonBlocking)
public async Task ReceiveSentMessages_Success(bool ipv4)
{
if (Socket.OSSupportsIPv6)
{
using (Socket receiver = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp))
{
int port = receiver.BindToAnonymousPort(IPAddress.IPv6Loopback);
receiver.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.PacketInformation, true);
const int DatagramSize = 256;
const int DatagramsToSend = 16;

receiver.ForceNonBlocking(forceNonBlocking);
IPAddress address = ipv4 ? IPAddress.Loopback : IPAddress.IPv6Loopback;
using Socket receiver = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
using Socket sender = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

Socket sender = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
sender.Bind(new IPEndPoint(IPAddress.IPv6Loopback, 0));
receiver.SetSocketOption(ipv4 ? SocketOptionLevel.IP : SocketOptionLevel.IPv6, SocketOptionName.PacketInformation, true);
ConfigureNonBlocking(sender);
ConfigureNonBlocking(receiver);

sender.ForceNonBlocking(forceNonBlocking);
receiver.BindToAnonymousPort(address);
sender.BindToAnonymousPort(address);

sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.IPv6Loopback, port));
byte[] sendBuffer = new byte[DatagramSize];
byte[] receiveBuffer = new byte[DatagramSize];
Random rnd = new Random(0);

IPPacketInformation packetInformation;
SocketFlags flags = SocketFlags.None;
EndPoint remoteEP = new IPEndPoint(IPAddress.IPv6Any, 0);
IPEndPoint remoteEp = new IPEndPoint(ipv4 ? IPAddress.Any : IPAddress.IPv6Any, 0);

int len = receiver.ReceiveMessageFrom(new byte[1024], 0, 1024, ref flags, ref remoteEP, out packetInformation);
for (int i = 0; i < DatagramsToSend; i++)
{
rnd.NextBytes(sendBuffer);
sender.SendTo(sendBuffer, receiver.LocalEndPoint);

Assert.Equal(1024, len);
Assert.Equal(sender.LocalEndPoint, remoteEP);
Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, packetInformation.Address);
SocketReceiveMessageFromResult result = await ReceiveMessageFromAsync(receiver, receiveBuffer, remoteEp);
IPPacketInformation packetInformation = result.PacketInformation;

sender.Dispose();
}
Assert.Equal(DatagramSize, result.ReceivedBytes);
AssertExtensions.SequenceEqual(sendBuffer, receiveBuffer);
Assert.Equal(sender.LocalEndPoint, result.RemoteEndPoint);
Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, packetInformation.Address);
}
}
}

[OuterLoop]
[Theory]
[InlineData(false)]
[InlineData(true)]
public void Success_APM(bool ipv4)
{
AddressFamily family;
IPAddress loopback, any;
SocketOptionLevel level;
if (ipv4)
{
if (!Socket.OSSupportsIPv4) return;
family = AddressFamily.InterNetwork;
loopback = IPAddress.Loopback;
any = IPAddress.Any;
level = SocketOptionLevel.IP;
}
else
{
if (!Socket.OSSupportsIPv6) return;
family = AddressFamily.InterNetworkV6;
loopback = IPAddress.IPv6Loopback;
any = IPAddress.IPv6Any;
level = SocketOptionLevel.IPv6;
}

using (var receiver = new Socket(family, SocketType.Dgram, ProtocolType.Udp))
using (var sender = new Socket(family, SocketType.Dgram, ProtocolType.Udp))
{
int port = receiver.BindToAnonymousPort(loopback);
receiver.SetSocketOption(level, SocketOptionName.PacketInformation, true);
sender.Bind(new IPEndPoint(loopback, 0));
public sealed class ReceiveMessageFrom_Sync : ReceiveMessageFrom<SocketHelperArraySync>
{
public ReceiveMessageFrom_Sync(ITestOutputHelper output) : base(output) { }
}

sender.SendTo(new byte[1024], new IPEndPoint(loopback, port));
public sealed class ReceiveMessageFrom_SyncForceNonBlocking : ReceiveMessageFrom<SocketHelperSyncForceNonBlocking>
{
public ReceiveMessageFrom_SyncForceNonBlocking(ITestOutputHelper output) : base(output) { }
}

IPPacketInformation packetInformation;
SocketFlags flags = SocketFlags.None;
EndPoint remoteEP = new IPEndPoint(any, 0);
public sealed class ReceiveMessageFrom_Apm : ReceiveMessageFrom<SocketHelperApm>
{
public ReceiveMessageFrom_Apm(ITestOutputHelper output) : base(output) { }
}

IAsyncResult ar = receiver.BeginReceiveMessageFrom(new byte[1024], 0, 1024, flags, ref remoteEP, null, null);
int len = receiver.EndReceiveMessageFrom(ar, ref flags, ref remoteEP, out packetInformation);
public sealed class ReceiveMessageFrom_Task : ReceiveMessageFrom<SocketHelperTask>
{
public ReceiveMessageFrom_Task(ITestOutputHelper output) : base(output) { }
}

Assert.Equal(1024, len);
Assert.Equal(sender.LocalEndPoint, remoteEP);
Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, packetInformation.Address);
}
}
public sealed class ReceiveMessageFrom_Eap : ReceiveMessageFrom<SocketHelperEap>
{
public ReceiveMessageFrom_Eap(ITestOutputHelper output) : base(output) { }

[OuterLoop]
[Theory]
[InlineData(false, 0)]
[InlineData(false, 1)]
[InlineData(false, 2)]
[InlineData(true, 0)]
[InlineData(true, 1)]
[InlineData(true, 2)]
public void Success_EventArgs(bool ipv4, int bufferMode)
public void ReceiveSentMessages_ReuseEventArgs_Success(bool ipv4, int bufferMode)
{
const int DatagramsToSend = 30;
const int TimeoutMs = 30_000;

AddressFamily family;
IPAddress loopback, any;
SocketOptionLevel level;
if (ipv4)
{
if (!Socket.OSSupportsIPv4) return;
family = AddressFamily.InterNetwork;
loopback = IPAddress.Loopback;
any = IPAddress.Any;
level = SocketOptionLevel.IP;
}
else
{
if (!Socket.OSSupportsIPv6) return;
family = AddressFamily.InterNetworkV6;
loopback = IPAddress.IPv6Loopback;
any = IPAddress.IPv6Any;
level = SocketOptionLevel.IPv6;
}

using (var receiver = new Socket(family, SocketType.Dgram, ProtocolType.Udp))
using (var sender = new Socket(family, SocketType.Dgram, ProtocolType.Udp))
using (var saea = new SocketAsyncEventArgs())
{
int port = receiver.BindToAnonymousPort(loopback);
receiver.SetSocketOption(level, SocketOptionName.PacketInformation, true);
sender.Bind(new IPEndPoint(loopback, 0));
using var receiver = new Socket(family, SocketType.Dgram, ProtocolType.Udp);
using var sender = new Socket(family, SocketType.Dgram, ProtocolType.Udp);
using var saea = new SocketAsyncEventArgs();
var completed = new ManualResetEventSlim();
saea.Completed += delegate { completed.Set(); };

saea.RemoteEndPoint = new IPEndPoint(any, 0);
int port = receiver.BindToAnonymousPort(loopback);
receiver.SetSocketOption(level, SocketOptionName.PacketInformation, true);
sender.Bind(new IPEndPoint(loopback, 0));
saea.RemoteEndPoint = new IPEndPoint(any, 0);

for (int i = 0; i < DatagramsToSend; i++)
{
switch (bufferMode)
{
case 0: // single buffer
Expand All @@ -190,17 +141,35 @@ public void Success_EventArgs(bool ipv4, int bufferMode)
break;
}

var mres = new ManualResetEventSlim();
saea.Completed += delegate { mres.Set(); };

bool pending = receiver.ReceiveMessageFromAsync(saea);
sender.SendTo(new byte[1024], new IPEndPoint(loopback, port));
if (pending) Assert.True(mres.Wait(30000), "Expected operation to complete within timeout");
if (pending) Assert.True(completed.Wait(TimeoutMs), "Expected operation to complete within timeout");
completed.Reset();

Assert.Equal(1024, saea.BytesTransferred);
Assert.Equal(sender.LocalEndPoint, saea.RemoteEndPoint);
Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, saea.ReceiveMessageFromPacketInfo.Address);
}
}
}
}

public sealed class ReceiveMessageFrom_SpanSync : ReceiveMessageFrom<SocketHelperSpanSync>
{
public ReceiveMessageFrom_SpanSync(ITestOutputHelper output) : base(output) { }
}

public sealed class ReceiveMessageFrom_SpanSyncForceNonBlocking : ReceiveMessageFrom<SocketHelperSpanSyncForceNonBlocking>
{
public ReceiveMessageFrom_SpanSyncForceNonBlocking(ITestOutputHelper output) : base(output) { }
}

public sealed class ReceiveMessageFrom_MemoryArrayTask : ReceiveMessageFrom<SocketHelperMemoryArrayTask>
{
public ReceiveMessageFrom_MemoryArrayTask(ITestOutputHelper output) : base(output) { }
}

public sealed class ReceiveMessageFrom_MemoryNativeTask : ReceiveMessageFrom<SocketHelperMemoryNativeTask>
{
public ReceiveMessageFrom_MemoryNativeTask(ITestOutputHelper output) : base(output) { }
}
}

This file was deleted.

Loading

0 comments on commit b95de55

Please sign in to comment.