Skip to content

Commit

Permalink
Change functional tests to use dynamic ports (#2458)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNK authored Jun 6, 2024
1 parent b57c87f commit 5e6821c
Show file tree
Hide file tree
Showing 9 changed files with 306 additions and 123 deletions.
20 changes: 9 additions & 11 deletions test/FunctionalTests/Balancer/BalancerHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ namespace Grpc.AspNetCore.FunctionalTests.Balancer;
internal static class BalancerHelpers
{
public static EndpointContext<TRequest, TResponse> CreateGrpcEndpoint<TRequest, TResponse>(
int port,
UnaryServerMethod<TRequest, TResponse> callHandler,
string methodName,
HttpProtocols? protocols = null,
bool? isHttps = null,
X509Certificate2? certificate = null,
ILoggerFactory? loggerFactory = null,
Action<KestrelServerOptions>? configureServer = null)
Action<KestrelServerOptions>? configureServer = null,
int? explicitPort = null)
where TRequest : class, IMessage, new()
where TResponse : class, IMessage, new()
{
var server = CreateServer(port, protocols, isHttps, certificate, loggerFactory, configureServer);
var server = CreateServer(protocols, isHttps, certificate, loggerFactory, configureServer, explicitPort);
var method = server.DynamicGrpc.AddUnaryMethod(callHandler, methodName);
var url = server.GetUrl(isHttps.GetValueOrDefault(false) ? TestServerEndpointName.Http2WithTls : TestServerEndpointName.Http2);

Expand Down Expand Up @@ -90,12 +90,12 @@ public void Dispose()
}

public static GrpcTestFixture<Startup> CreateServer(
int port,
HttpProtocols? protocols = null,
bool? isHttps = null,
X509Certificate2? certificate = null,
ILoggerFactory? loggerFactory = null,
Action<KestrelServerOptions>? configureServer = null)
Action<KestrelServerOptions>? configureServer = null,
int? explicitPort = null)
{
var endpointName = isHttps.GetValueOrDefault(false) ? TestServerEndpointName.Http2WithTls : TestServerEndpointName.Http2;

Expand All @@ -107,14 +107,10 @@ public static GrpcTestFixture<Startup> CreateServer(
services.AddSingleton<ILoggerFactory>(loggerFactory);
}
},
(options, urls) =>
(context, options, urls) =>
{
configureServer?.Invoke(options);
urls[endpointName] = isHttps.GetValueOrDefault(false)
? $"https://127.0.0.1:{port}"
: $"http://127.0.0.1:{port}";
options.ListenLocalhost(port, listenOptions =>
options.Listen(IPAddress.Loopback, explicitPort ?? 0, listenOptions =>
{
listenOptions.Protocols = protocols ?? HttpProtocols.Http2;
Expand All @@ -131,6 +127,8 @@ public static GrpcTestFixture<Startup> CreateServer(
listenOptions.UseHttps(certificate);
}
}
urls[endpointName] = IPEndpointInfoContainer.Create(listenOptions, isHttps.GetValueOrDefault(false));
});
},
endpointName);
Expand Down
37 changes: 18 additions & 19 deletions test/FunctionalTests/Balancer/ConnectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ async Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext conte
}

// Arrange
var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50051, UnaryMethod, nameof(UnaryMethod));
var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod));
endpoint.Dispose();

var connectTcs = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);
Expand Down Expand Up @@ -123,7 +123,7 @@ async Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext conte
}

// Arrange
using var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50051, UnaryMethod, nameof(UnaryMethod));
using var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod));

// Dispose endpoint so that channel pauses while attempting to connect to the port.
endpoint.Dispose();
Expand Down Expand Up @@ -160,7 +160,7 @@ Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
}

// Arrange
using var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50051, UnaryMethod, nameof(UnaryMethod), loggerFactory: LoggerFactory);
using var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod), loggerFactory: LoggerFactory);

var connectionIdleTimeout = TimeSpan.FromMilliseconds(milliseconds);
var channel = await BalancerHelpers.CreateChannel(
Expand Down Expand Up @@ -198,7 +198,7 @@ Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
}

// Arrange
using var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50051, UnaryMethod, nameof(UnaryMethod), loggerFactory: LoggerFactory);
using var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod), loggerFactory: LoggerFactory);

var channel = await BalancerHelpers.CreateChannel(
LoggerFactory,
Expand Down Expand Up @@ -237,7 +237,6 @@ Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)

// Arrange
using var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(
50051,
UnaryMethod,
nameof(UnaryMethod),
loggerFactory: LoggerFactory,
Expand Down Expand Up @@ -290,8 +289,8 @@ async Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext conte
}

// Arrange
using var endpoint1 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50051, UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true);
using var endpoint2 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50052, UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true);
using var endpoint1 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true);
using var endpoint2 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true);

var services = new ServiceCollection();
services.AddSingleton<ResolverFactory>(new StaticResolverFactory(_ => new[]
Expand Down Expand Up @@ -349,7 +348,7 @@ await TestHelpers.AssertIsTrueRetryAsync(() =>
}, "Wait for connections to start.");
foreach (var t in activeStreams)
{
Assert.AreEqual(new DnsEndPoint("127.0.0.1", 50051), t.EndPoint);
Assert.AreEqual(new DnsEndPoint("127.0.0.1", endpoint1.Address.Port), t.EndPoint);
}

// Act
Expand All @@ -370,7 +369,7 @@ await TestHelpers.AssertIsTrueRetryAsync(() =>
activeStreams = transport.GetActiveStreams();
return activeStreams.Count == 11;
}, "Wait for connections to start.");
Assert.AreEqual(new DnsEndPoint("127.0.0.1", 50051), activeStreams[activeStreams.Count - 1].EndPoint);
Assert.AreEqual(new DnsEndPoint("127.0.0.1", endpoint1.Address.Port), activeStreams[activeStreams.Count - 1].EndPoint);

tcs.SetResult(null);

Expand Down Expand Up @@ -406,11 +405,11 @@ await TestHelpers.AssertIsTrueRetryAsync(() =>
Logger.LogInformation($"Next call goes to fallback address.");
var reply = await client.UnaryCall(new HelloRequest { Name = "Balancer" }).ResponseAsync.TimeoutAfter(TimeSpan.FromSeconds(20));
Assert.AreEqual("Balancer", reply.Message);
Assert.AreEqual("127.0.0.1:50052", host);
Assert.AreEqual($"127.0.0.1:{endpoint2.Address.Port}", host);

activeStreams = transport.GetActiveStreams();
Assert.AreEqual(1, activeStreams.Count);
Assert.AreEqual(new DnsEndPoint("127.0.0.1", 50052), activeStreams[0].EndPoint);
Assert.AreEqual(new DnsEndPoint("127.0.0.1", endpoint2.Address.Port), activeStreams[0].EndPoint);
}

#if NET7_0_OR_GREATER
Expand All @@ -436,8 +435,8 @@ Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
var cert = new X509Certificate2(certPath, "11111");

// Arrange
using var endpoint1 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50051, UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true, certificate: cert);
using var endpoint2 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50052, UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true, certificate: cert);
using var endpoint1 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true, certificate: cert);
using var endpoint2 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true, certificate: cert);

var services = new ServiceCollection();
services.AddSingleton((ResolverFactory)new StaticResolverFactory(_ => (new[]
Expand Down Expand Up @@ -491,13 +490,13 @@ Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
Assert.AreEqual("localhost", host);
Assert.AreEqual(SslPolicyErrors.None, callbackPolicyErrors);
Assert.AreEqual(IPAddress.Parse("127.0.0.1"), ipAddress);
Assert.IsTrue(port == 50051 || port == 50052);
Assert.IsTrue(port == endpoint1.Address.Port || port == endpoint2.Address.Port);

ports.Add(port!.Value);
}

Assert.IsTrue(ports.Contains(50051), "Has 50051");
Assert.IsTrue(ports.Contains(50052), "Has 50052");
Assert.IsTrue(ports.Contains(endpoint1.Address.Port), $"Has {endpoint1.Address.Port}");
Assert.IsTrue(ports.Contains(endpoint2.Address.Port), $"Has {endpoint2.Address.Port}");

static BalancerAddress CreateAddress(Uri address, string hostOverride)
{
Expand All @@ -523,8 +522,8 @@ Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
metadata.Add("Authorization", $"Bearer TEST");
return Task.CompletedTask;
});
using var endpoint1 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50051, UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true);
using var endpoint2 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50052, UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true);
using var endpoint1 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true);
using var endpoint2 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod), HttpProtocols.Http1AndHttp2, isHttps: true);

var services = new ServiceCollection();
services.AddSingleton<ResolverFactory>(new StaticResolverFactory(_ => new[]
Expand Down Expand Up @@ -706,7 +705,7 @@ Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext context)
}

// Arrange
using var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50051, UnaryMethod, nameof(UnaryMethod));
using var endpoint = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod));

var channel = await BalancerHelpers.CreateChannel(
LoggerFactory,
Expand Down
14 changes: 7 additions & 7 deletions test/FunctionalTests/Balancer/LeastUsedBalancerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ async Task<HelloReply> UnaryMethod(HelloRequest request, ServerCallContext conte
}

// Arrange
using var endpoint1 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50051, UnaryMethod, nameof(UnaryMethod));
using var endpoint2 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(50052, UnaryMethod, nameof(UnaryMethod));
using var endpoint1 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod));
using var endpoint2 = BalancerHelpers.CreateGrpcEndpoint<HelloRequest, HelloReply>(UnaryMethod, nameof(UnaryMethod));

var channel = await BalancerHelpers.CreateChannel(LoggerFactory, new LoadBalancingConfig("least_used"), new[] { endpoint1.Address, endpoint2.Address }, connect: true);

Expand All @@ -79,34 +79,34 @@ await BalancerWaitHelpers.WaitForSubchannelsToBeReadyAsync(
var reply = await client.UnaryCall(new HelloRequest { Name = "Balancer" }).ResponseAsync.DefaultTimeout();
// Assert
Assert.AreEqual("Balancer", reply.Message);
Assert.AreEqual("127.0.0.1:50051", host);
Assert.AreEqual($"127.0.0.1:{endpoint1.Address.Port}", host);

// Act
reply = await client.UnaryCall(new HelloRequest { Name = "Balancer" }).ResponseAsync.DefaultTimeout();
// Assert
Assert.AreEqual("Balancer", reply.Message);
Assert.AreEqual("127.0.0.1:50051", host);
Assert.AreEqual($"127.0.0.1:{endpoint1.Address.Port}", host);

// Act
var sp1 = syncPoint = new SyncPoint(runContinuationsAsynchronously: true);
var pendingCall1 = client.UnaryCall(new HelloRequest { Name = "Balancer" });
// Assert
await syncPoint.WaitForSyncPoint().DefaultTimeout();
Assert.AreEqual("127.0.0.1:50051", host);
Assert.AreEqual($"127.0.0.1:{endpoint1.Address.Port}", host);

// Act
var sp2 = syncPoint = new SyncPoint(runContinuationsAsynchronously: true);
var pendingCall2 = client.UnaryCall(new HelloRequest { Name = "Balancer" });
// Assert
await syncPoint.WaitForSyncPoint().DefaultTimeout();
Assert.AreEqual("127.0.0.1:50052", host);
Assert.AreEqual($"127.0.0.1:{endpoint2.Address.Port}", host);

// Act
var sp3 = syncPoint = new SyncPoint(runContinuationsAsynchronously: true);
var pendingCall3 = client.UnaryCall(new HelloRequest { Name = "Balancer" });
// Assert
await syncPoint.WaitForSyncPoint().DefaultTimeout();
Assert.AreEqual("127.0.0.1:50051", host);
Assert.AreEqual($"127.0.0.1:{endpoint1.Address.Port}", host);

sp1.Continue();
sp2.Continue();
Expand Down
Loading

0 comments on commit 5e6821c

Please sign in to comment.