Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit a5c79c8

Browse files
committed
Merge pull request #7112 from ericeil/UdpReliability
Improve UDP test reliability
2 parents a31e463 + af630f0 commit a5c79c8

File tree

9 files changed

+108
-51
lines changed

9 files changed

+108
-51
lines changed

src/Common/tests/System/Net/Sockets/Configuration.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ namespace System.Net.Sockets.Tests
99
public static class Configuration
1010
{
1111
// Timeout values in milliseconds.
12-
public static readonly int PassingTestTimeout = 5000;
13-
public static readonly int FailingTestTimeout = 100;
12+
public const int PassingTestTimeout = 5000;
13+
public const int FailingTestTimeout = 100;
14+
15+
// Number of redundant UDP packets to send to increase test reliability
16+
public const int UDPRedundancy = 10;
1417
}
1518
}

src/System.Net.Sockets.Legacy/tests/FunctionalTests/DualModeSocketTest.cs

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,8 +1099,12 @@ private void DualModeSendTo_IPEndPointToHost_Helper(IPAddress connectTo, IPAddre
10991099
Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp);
11001100
using (SocketUdpServer server = new SocketUdpServer(listenOn, dualModeServer, out port))
11011101
{
1102-
int sent = client.SendTo(new byte[1], new IPEndPoint(connectTo, port));
1103-
Assert.Equal(1, sent);
1102+
// Send a few packets, in case they aren't delivered reliably.
1103+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
1104+
{
1105+
int sent = client.SendTo(new byte[1], new IPEndPoint(connectTo, port));
1106+
Assert.Equal(1, sent);
1107+
}
11041108

11051109
bool success = server.WaitHandle.WaitOne(expectedToTimeout ? Configuration.FailingTestTimeout : Configuration.PassingTestTimeout); // Make sure the bytes were received
11061110
if (!success)
@@ -1187,10 +1191,14 @@ private void DualModeBeginSendTo_EndPointToHost_Helper(IPAddress connectTo, IPAd
11871191
Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp);
11881192
using (SocketUdpServer server = new SocketUdpServer(listenOn, dualModeServer, out port))
11891193
{
1190-
IAsyncResult async = client.BeginSendTo(new byte[1], 0, 1, SocketFlags.None, new IPEndPoint(connectTo, port), null, null);
1194+
// Send a few packets, in case they aren't delivered reliably.
1195+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
1196+
{
1197+
IAsyncResult async = client.BeginSendTo(new byte[1], 0, 1, SocketFlags.None, new IPEndPoint(connectTo, port), null, null);
11911198

1192-
int sent = client.EndSendTo(async);
1193-
Assert.Equal(1, sent);
1199+
int sent = client.EndSendTo(async);
1200+
Assert.Equal(1, sent);
1201+
}
11941202

11951203
bool success = server.WaitHandle.WaitOne(expectedToTimeout ? Configuration.FailingTestTimeout : Configuration.PassingTestTimeout); // Make sure the bytes were received
11961204
if (!success)
@@ -1281,26 +1289,31 @@ public void SendToAsyncV6IPEndPointToDualHost_Success()
12811289
private void DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress connectTo, IPAddress listenOn, bool dualModeServer, bool expectedToTimeout = false)
12821290
{
12831291
int port;
1284-
ManualResetEvent waitHandle = new ManualResetEvent(false);
12851292
Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp);
12861293
using (SocketUdpServer server = new SocketUdpServer(listenOn, dualModeServer, out port))
12871294
{
1288-
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
1289-
args.RemoteEndPoint = new IPEndPoint(connectTo, port);
1290-
args.SetBuffer(new byte[1], 0, 1);
1291-
args.UserToken = waitHandle;
1292-
args.Completed += AsyncCompleted;
1293-
1294-
bool async = client.SendToAsync(args);
1295-
if (async)
1295+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
12961296
{
1297-
Assert.True(waitHandle.WaitOne(Configuration.PassingTestTimeout), "Timeout while waiting for connection");
1298-
}
1299-
1300-
Assert.Equal(1, args.BytesTransferred);
1301-
if (args.SocketError != SocketError.Success)
1302-
{
1303-
throw new SocketException((int)args.SocketError);
1297+
using (ManualResetEvent waitHandle = new ManualResetEvent(false))
1298+
{
1299+
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
1300+
args.RemoteEndPoint = new IPEndPoint(connectTo, port);
1301+
args.SetBuffer(new byte[1], 0, 1);
1302+
args.UserToken = waitHandle;
1303+
args.Completed += AsyncCompleted;
1304+
1305+
bool async = client.SendToAsync(args);
1306+
if (async)
1307+
{
1308+
Assert.True(waitHandle.WaitOne(Configuration.PassingTestTimeout), "Timeout while waiting for connection");
1309+
}
1310+
1311+
Assert.Equal(1, args.BytesTransferred);
1312+
if (args.SocketError != SocketError.Success)
1313+
{
1314+
throw new SocketException((int)args.SocketError);
1315+
}
1316+
}
13041317
}
13051318

13061319
bool success = server.WaitHandle.WaitOne(expectedToTimeout ? Configuration.FailingTestTimeout : Configuration.PassingTestTimeout); // Make sure the bytes were received
@@ -2541,7 +2554,11 @@ private void ClientSend(object state)
25412554
try
25422555
{
25432556
Socket socket = new Socket(_connectTo.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
2544-
socket.SendTo(new byte[1], new IPEndPoint(_connectTo, _port));
2557+
2558+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
2559+
{
2560+
socket.SendTo(new byte[1], new IPEndPoint(_connectTo, _port));
2561+
}
25452562
}
25462563
catch (SocketException)
25472564
{

src/System.Net.Sockets.Legacy/tests/FunctionalTests/ReceiveMessageFrom.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ public void Success()
2020

2121
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
2222
sender.Bind(new IPEndPoint(IPAddress.Loopback, 0));
23-
sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.Loopback, port));
23+
24+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
25+
{
26+
sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.Loopback, port));
27+
}
2428

2529
IPPacketInformation packetInformation;
2630
SocketFlags flags = SocketFlags.None;

src/System.Net.Sockets.Legacy/tests/FunctionalTests/ReceiveMessageFromAsync.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ public void Success()
3131

3232
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
3333
sender.Bind(new IPEndPoint(IPAddress.Loopback, 0));
34-
sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.Loopback, port));
34+
35+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
36+
{
37+
sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.Loopback, port));
38+
}
3539

3640
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
3741
args.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);

src/System.Net.Sockets.Legacy/tests/FunctionalTests/SelectAndPollTests.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ public void SelectRead_Single_Success()
4141
int receiverPort = receiver.BindToAnonymousPort(IPAddress.Loopback);
4242
var receiverEndpoint = new IPEndPoint(IPAddress.Loopback, receiverPort);
4343

44-
sender.SendTo(new byte[1], SocketFlags.None, receiverEndpoint);
44+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
45+
{
46+
sender.SendTo(new byte[1], SocketFlags.None, receiverEndpoint);
47+
}
4548

4649
var list = new List<Socket> { receiver };
4750
Socket.Select(list, null, null, SelectSuccessTimeoutMicroseconds);
@@ -78,8 +81,11 @@ public void SelectRead_Multiple_Success()
7881
int secondReceiverPort = secondReceiver.BindToAnonymousPort(IPAddress.Loopback);
7982
var secondReceiverEndpoint = new IPEndPoint(IPAddress.Loopback, secondReceiverPort);
8083

81-
sender.SendTo(new byte[1], SocketFlags.None, firstReceiverEndpoint);
82-
sender.SendTo(new byte[1], SocketFlags.None, secondReceiverEndpoint);
84+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
85+
{
86+
sender.SendTo(new byte[1], SocketFlags.None, firstReceiverEndpoint);
87+
sender.SendTo(new byte[1], SocketFlags.None, secondReceiverEndpoint);
88+
}
8389

8490
var sw = Stopwatch.StartNew();
8591
Assert.True(SpinWait.SpinUntil(() =>
@@ -126,7 +132,10 @@ public void SelectRead_Multiple_Mixed()
126132
int secondReceiverPort = secondReceiver.BindToAnonymousPort(IPAddress.Loopback);
127133
var secondReceiverEndpoint = new IPEndPoint(IPAddress.Loopback, secondReceiverPort);
128134

129-
sender.SendTo(new byte[1], SocketFlags.None, secondReceiverEndpoint);
135+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
136+
{
137+
sender.SendTo(new byte[1], SocketFlags.None, secondReceiverEndpoint);
138+
}
130139

131140
var list = new List<Socket> { firstReceiver, secondReceiver };
132141
Socket.Select(list, null, null, SelectSuccessTimeoutMicroseconds);
@@ -272,7 +281,10 @@ public void PollRead_Single_Success()
272281
int receiverPort = receiver.BindToAnonymousPort(IPAddress.Loopback);
273282
var receiverEndpoint = new IPEndPoint(IPAddress.Loopback, receiverPort);
274283

275-
sender.SendTo(new byte[1], SocketFlags.None, receiverEndpoint);
284+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
285+
{
286+
sender.SendTo(new byte[1], SocketFlags.None, receiverEndpoint);
287+
}
276288

277289
Assert.True(receiver.Poll(SelectSuccessTimeoutMicroseconds, SelectMode.SelectRead));
278290
}

src/System.Net.Sockets.Legacy/tests/FunctionalTests/SendReceive.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public SendReceive(ITestOutputHelper output)
2222

2323
private static void SendToRecvFrom_Datagram_UDP(IPAddress leftAddress, IPAddress rightAddress)
2424
{
25+
// TODO #5185: Harden against packet loss
2526
const int DatagramSize = 256;
2627
const int DatagramsToSend = 256;
2728
const int AckTimeout = 1000;
@@ -96,6 +97,7 @@ private static void SendToRecvFrom_Datagram_UDP(IPAddress leftAddress, IPAddress
9697

9798
private static void SendToRecvFromAPM_Datagram_UDP(IPAddress leftAddress, IPAddress rightAddress)
9899
{
100+
// TODO #5185: Harden against packet loss
99101
const int DatagramSize = 256;
100102
const int DatagramsToSend = 256;
101103
const int AckTimeout = 1000;

src/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -447,25 +447,32 @@ public void SendToAsyncV6IPEndPointToDualHost_Success()
447447
private void DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress connectTo, IPAddress listenOn, bool dualModeServer)
448448
{
449449
int port;
450-
ManualResetEvent waitHandle = new ManualResetEvent(false);
451450
Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp);
452451
using (SocketUdpServer server = new SocketUdpServer(_log, listenOn, dualModeServer, out port))
453452
{
454-
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
455-
args.RemoteEndPoint = new IPEndPoint(connectTo, port);
456-
args.SetBuffer(new byte[1], 0, 1);
457-
args.UserToken = waitHandle;
458-
args.Completed += AsyncCompleted;
459-
460-
bool async = client.SendToAsync(args);
461-
if (async)
453+
// Send a few packets, in case they aren't delivered reliably.
454+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
462455
{
463-
Assert.True(waitHandle.WaitOne(5000), "Timeout while waiting for connection");
464-
}
465-
Assert.Equal(1, args.BytesTransferred);
466-
if (args.SocketError != SocketError.Success)
467-
{
468-
throw new SocketException((int)args.SocketError);
456+
using (ManualResetEvent waitHandle = new ManualResetEvent(false))
457+
{
458+
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
459+
args.RemoteEndPoint = new IPEndPoint(connectTo, port);
460+
args.SetBuffer(new byte[1], 0, 1);
461+
args.UserToken = waitHandle;
462+
args.Completed += AsyncCompleted;
463+
464+
bool async = client.SendToAsync(args);
465+
if (async)
466+
{
467+
Assert.True(waitHandle.WaitOne(5000), "Send completed in alotted time");
468+
}
469+
470+
Assert.Equal(1, args.BytesTransferred);
471+
if (args.SocketError != SocketError.Success)
472+
{
473+
throw new SocketException((int)args.SocketError);
474+
}
475+
}
469476
}
470477

471478
bool success = server.WaitHandle.WaitOne(Configuration.FailingTestTimeout); // Make sure the bytes were received
@@ -916,11 +923,14 @@ private void ClientSend(object state)
916923
{
917924
Socket socket = new Socket(_connectTo.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
918925

919-
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
920-
e.RemoteEndPoint = new IPEndPoint(_connectTo, _port);
921-
e.SetBuffer(new byte[1], 0, 1);
926+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
927+
{
928+
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
929+
e.RemoteEndPoint = new IPEndPoint(_connectTo, _port);
930+
e.SetBuffer(new byte[1], 0, 1);
922931

923-
socket.SendToAsync(e);
932+
socket.SendToAsync(e);
933+
}
924934
}
925935
catch (SocketException)
926936
{

src/System.Net.Sockets/tests/FunctionalTests/IPPacketInformationTest.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ private IPPacketInformation GetNonDefaultIPPacketInformation()
7272

7373
Assert.True(receiver.ReceiveMessageFromAsync(receiveArgs));
7474

75-
sender.SendTo(new byte[1], new IPEndPoint(IPAddress.Loopback, port));
75+
// Send a few packets, in case they aren't delivered reliably.
76+
for (int i = 0; i < Configuration.UDPRedundancy; i++)
77+
{
78+
sender.SendTo(new byte[1], new IPEndPoint(IPAddress.Loopback, port));
79+
}
7680

7781
Assert.True(waitHandle.WaitOne(ReceiveTimeout));
7882

src/System.Net.Sockets/tests/FunctionalTests/SendReceive.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public SendReceive(ITestOutputHelper output)
3030
[MemberData(nameof(SendToRecvFromAsync_Datagram_UDP_MemberData))]
3131
public void SendToRecvFromAsync_Datagram_UDP(IPAddress leftAddress, IPAddress rightAddress)
3232
{
33+
// TODO #5185: harden against packet loss
3334
const int DatagramSize = 256;
3435
const int DatagramsToSend = 256;
3536
const int AckTimeout = 1000;

0 commit comments

Comments
 (0)