Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Newton-King <james@newtonking.com>2022-08-20 09:38:14 +0300
committerJames Newton-King <james@newtonking.com>2022-08-20 09:38:14 +0300
commita9c2d4d42723ef70b2fda0542a06f3d35e52bba8 (patch)
tree6e8743c4745b73dc728fe5f3a3009fb29f79a395
parente62c9c9f83254e8c0abf8dac5181859780882321 (diff)
Rewrite retry helper to get ports via binding port to 0jamesnk/http3-flaky-test
-rw-r--r--src/Servers/Kestrel/shared/test/ServerRetryHelper.cs41
1 files changed, 37 insertions, 4 deletions
diff --git a/src/Servers/Kestrel/shared/test/ServerRetryHelper.cs b/src/Servers/Kestrel/shared/test/ServerRetryHelper.cs
index 1466596c7b..d211dde1fd 100644
--- a/src/Servers/Kestrel/shared/test/ServerRetryHelper.cs
+++ b/src/Servers/Kestrel/shared/test/ServerRetryHelper.cs
@@ -1,28 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Net;
+using System.Net.Sockets;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Testing;
public static class ServerRetryHelper
{
- private const int RetryCount = 15;
+ private const int RetryCount = 10;
/// <summary>
/// Retry a func. Useful when a test needs an explicit port and you want to avoid port conflicts.
/// </summary>
public static async Task BindPortsWithRetry(Func<int, Task> retryFunc, ILogger logger)
{
+ var ports = GetFreePorts(RetryCount);
+
var retryCount = 0;
while (true)
{
- // Approx dynamic port range on Windows and Linux.
- var randomPort = Random.Shared.Next(35000, 60000);
try
{
- await retryFunc(randomPort);
+ await retryFunc(ports[retryCount]);
break;
}
catch (Exception ex)
@@ -40,4 +42,35 @@ public static class ServerRetryHelper
}
}
}
+
+ private static int[] GetFreePorts(int count)
+ {
+ var sockets = new List<Socket>();
+
+ for (var i = 0; i < count; i++)
+ {
+ // Find a port that's free by binding port 0.
+ // Note that this port should be free when the test runs, but:
+ // - Something else could steal it before the test uses it.
+ // - UDP port with the same number could be in use.
+ // For that reason, some retries should be available.
+ var ipEndPoint = new IPEndPoint(IPAddress.Loopback, 0);
+ var listenSocket = new Socket(ipEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
+
+ listenSocket.Bind(ipEndPoint);
+
+ sockets.Add(listenSocket);
+ }
+
+ // Ports are calculated upfront. Rebinding with port 0 could result the same port
+ // being returned for each retry.
+ var ports = sockets.Select(s => (IPEndPoint)s.LocalEndPoint).Select(ep => ep.Port).ToArray();
+
+ foreach (var socket in sockets)
+ {
+ socket.Dispose();
+ }
+
+ return ports;
+ }
}