Files
WireMock.Net-wiremock/test/WireMock.Net.Tests/Testcontainers/TestcontainersTestsGrpc.cs
Stef Heyenrath a292f28dda Version 2.x (#1359)
* Version 2.x

* Setup .NET 9

* 12

* cleanup some #if for NETSTANDARD1_3

* cleanup + fix tests for net8

* openapi

* NO ConfigureAwait(false) + cleanup

* .

* #endif

* HashSet

* WireMock.Net.NUnit

* HttpContext

* Add WebSockets (#1423)

* Add WebSockets

* Add tests

* fix

* more tests

* Add tests

* ...

* remove IOwin

* -

* tests

* fluent

* ok

* match

* .

* byte[]

* x

* func

* func

* byte

* trans

* ...

* frameworks.........

* jmes

* xxx

* sc

* using var httpClient = new HttpClient();

* usings

* maxRetries

* up

* xunit v3

* ct

* ---

* ct

* ct2

* T Unit

* WireMock.Net.TUnitTests / 10

* t unit first

* --project

* no tunit

* t2

* --project

* --project

* ci -  --project

* publish ./test/wiremock-coverage.xml

* windows

* .

* log

* ...

* log

* goed

* BodyType

* .

* .

* --scenario

* ...

* pact

* ct

* .

* WireMock.Net.RestClient.AwesomeAssertions (#1427)

* WireMock.Net.RestClient.AwesomeAssertions

* ok

* atpath

* fix test

* sonar fixes

* ports

* proxy test

* FIX?

* ---

* await Task.Delay(100, _ct);

* ?

* --project

* Aspire: use IDistributedApplicationEventingSubscriber (#1428)

* broadcast

* ok

* more tsts

* .

* Collection

* up

* .

* 2

* remove nfluent

* <VersionPrefix>2.0.0-preview-02</VersionPrefix>

* ...

* .

* nuget icon

* .

* <PackageReference Include="JmesPath.Net" Version="1.1.0" />

* x

* 500

* .

* fix some warnings

* ws
2026-03-11 17:02:47 +01:00

292 lines
11 KiB
C#

// Copyright © WireMock.Net
#if NET6_0_OR_GREATER
using System.Text;
using AwesomeAssertions;
using AwesomeAssertions.Execution;
using Greet;
using Grpc.Net.Client;
using Meziantou.Extensions.Logging.Xunit.v3;
using Microsoft.Extensions.Logging;
using WireMock.Constants;
using WireMock.Net.Testcontainers;
using WireMock.Util;
namespace WireMock.Net.Tests.Testcontainers;
[Collection("Grpc")]
public class TestcontainersTestsGrpc(ITestOutputHelper testOutputHelper)
{
private readonly CancellationToken _ct = TestContext.Current.CancellationToken;
private readonly ILogger _logger = new XUnitLogger(testOutputHelper, new LoggerExternalScopeProvider(), nameof(TestcontainersTestsGrpc), new XUnitLoggerOptions
{
IncludeCategory = true,
TimestampFormat = "yyy-MM-dd HH:mm:ss.fff"
});
[Fact]
public async Task WireMockContainer_Build_Grpc_TestPortsAndUrls1()
{
// Arrange
var adminUsername = $"username_{Guid.NewGuid()}";
var adminPassword = $"password_{Guid.NewGuid()}";
var port = PortUtils.FindFreeTcpPort();
// Act
var wireMockContainer = new WireMockContainerBuilder()
.WithLogger(_logger)
.WithAdminUserNameAndPassword(adminUsername, adminPassword)
.WithCommand("--UseHttp2")
.WithCommand("--Urls", $"http://*:80 grpc://*:{port}")
.WithPortBinding(port, true)
.Build();
try
{
await wireMockContainer.StartAsync(_ct);
// Assert
using (new AssertionScope())
{
var logs = await wireMockContainer.GetLogsAsync(DateTime.MinValue, ct: _ct);
logs.Should().NotBeNull();
var url = wireMockContainer.GetPublicUrl();
url.Should().NotBeNullOrWhiteSpace();
var urls = wireMockContainer.GetPublicUrls();
urls.Should().HaveCount(2);
var httpPort = wireMockContainer.GetMappedPublicPort(80);
httpPort.Should().BeGreaterThan(0);
var httpUrl = wireMockContainer.GetMappedPublicUrl(80);
httpUrl.Should().StartWith("http://");
var grpcPort = wireMockContainer.GetMappedPublicPort(port);
grpcPort.Should().BeGreaterThan(0);
var grpcUrl = wireMockContainer.GetMappedPublicUrl(port);
grpcUrl.Should().StartWith("http://");
var adminClient = wireMockContainer.CreateWireMockAdminClient();
var settings = await adminClient.GetSettingsAsync(_ct);
settings.Should().NotBeNull();
}
}
finally
{
await StopAsync(wireMockContainer);
}
}
[Fact]
public async Task WireMockContainer_Build_Grpc_TestPortsAndUrls2()
{
// Arrange
var adminUsername = $"username_{Guid.NewGuid()}";
var adminPassword = $"password_{Guid.NewGuid()}";
var ports = PortUtils.FindFreeTcpPorts(3);
// Act
var wireMockContainer = new WireMockContainerBuilder()
.WithLogger(_logger)
.WithAdminUserNameAndPassword(adminUsername, adminPassword)
.AddUrl($"http://*:{ports[0]}")
.AddUrl($"grpc://*:{ports[1]}")
.AddUrl($"grpc://*:{ports[2]}")
.Build();
try
{
await wireMockContainer.StartAsync(_ct);
// Assert
using (new AssertionScope())
{
var logs = await wireMockContainer.GetLogsAsync(DateTime.MinValue, ct: _ct);
logs.Should().NotBeNull();
var url = wireMockContainer.GetPublicUrl();
url.Should().NotBeNullOrWhiteSpace();
var urls = wireMockContainer.GetPublicUrls();
urls.Should().HaveCount(4);
foreach (var internalPort in new[] { ports[0], ports[1], ports[2], 80 })
{
var publicPort = wireMockContainer.GetMappedPublicPort(internalPort);
publicPort.Should().BeGreaterThan(0);
var publicUrl = wireMockContainer.GetMappedPublicUrl(internalPort);
publicUrl.Should().StartWith("http://");
}
var adminClient = wireMockContainer.CreateWireMockAdminClient();
var settings = await adminClient.GetSettingsAsync(_ct);
settings.Should().NotBeNull();
}
}
finally
{
await StopAsync(wireMockContainer);
}
}
[Fact]
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionFromJson_UsingGrpcGeneratedClient()
{
var wireMockContainer = await Given_WireMockContainerIsStartedForHttpAndGrpcAsync();
await Given_ProtoBufMappingIsAddedViaAdminInterfaceAsync(wireMockContainer, "protobuf-mapping-1.json");
var reply = await When_GrpcClient_Calls_SayHelloAsync(wireMockContainer);
Then_ReplyMessage_Should_BeCorrect(reply);
await StopAsync(wireMockContainer);
}
[Fact]
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionAtServerLevel_UsingGrpcGeneratedClient()
{
var wireMockContainer = await Given_WireMockContainerWithProtoDefinitionAtServerLevelIsStartedForHttpAndGrpcAsync();
await Given_ProtoBufMappingIsAddedViaAdminInterfaceAsync(wireMockContainer, "protobuf-mapping-4.json");
var reply = await When_GrpcClient_Calls_SayHelloAsync(wireMockContainer);
Then_ReplyMessage_Should_BeCorrect(reply);
await StopAsync(wireMockContainer);
}
[Fact]
public async Task WireMockContainer_Build_Grpc_ProtoDefinitionAtServerLevel_UsingGrpcGeneratedClient_AndWithWatchStaticMappings()
{
var wireMockContainer = await Given_WireMockContainerWithProtoDefinitionAtServerLevelWithWatchStaticMappingsIsStartedForHttpAndGrpcAsync();
var reply = await When_GrpcClient_Calls_SayHelloAsync(wireMockContainer);
Then_ReplyMessage_Should_BeCorrect(reply);
await StopAsync(wireMockContainer);
}
private async Task<HelloReply> When_GrpcClient_Calls_SayHelloAsync(WireMockContainer wireMockContainer)
{
var address = wireMockContainer.GetPublicUrls().First(x => x.Key != 80).Value;
var channel = GrpcChannel.ForAddress(address);
var client = new Greeter.GreeterClient(channel);
try
{
return await client.SayHelloAsync(new HelloRequest { Name = "stef" });
}
catch (Exception ex)
{
testOutputHelper.WriteLine("Exception during GrpcClient Call to {0}. Exception = {1}.", address, ex);
testOutputHelper.WriteLine("Dumping WireMock.Net logs:");
var (stdOut, stdError) = await wireMockContainer.GetLogsAsync(DateTime.MinValue);
testOutputHelper.WriteLine("Out :\r\n{0}", stdOut);
testOutputHelper.WriteLine("Error:\r\n{0}", stdError);
testOutputHelper.WriteLine("Dumping WireMock.Net mappings:");
using var httpClient = wireMockContainer.CreateClient();
using var response = await httpClient.GetAsync("/__admin/mappings");
var mappings = await response.Content.ReadAsStringAsync();
testOutputHelper.WriteLine("Mappings:\r\n{0}", mappings);
throw;
}
}
private async Task StopAsync(WireMockContainer wireMockContainer)
{
try
{
await wireMockContainer.StopAsync();
}
catch (Exception ex)
{
// Sometimes we get this exception, so for now ignore it.
/*
Failed WireMock.Net.Tests.Testcontainers.TestcontainersTests.WireMockContainer_Build_WithImageAsText_And_StartAsync_and_StopAsync [9 s]
Error Message:
System.NullReferenceException : Object reference not set to an instance of an object.
Stack Trace:
at DotNet.Testcontainers.Containers.DockerContainer.UnsafeStopAsync(CancellationToken ct) in /_/src/Testcontainers/Containers/DockerContainer.cs:line 567
at DotNet.Testcontainers.Containers.DockerContainer.StopAsync(CancellationToken ct) in /_/src/Testcontainers/Containers/DockerContainer.cs:line 319
*/
testOutputHelper.WriteLine($"Exception during StopAsync: {ex}");
}
}
private async Task<WireMockContainer> Given_WireMockContainerIsStartedForHttpAndGrpcAsync()
{
var port = PortUtils.FindFreeTcpPort();
var wireMockContainer = new WireMockContainerBuilder()
.WithLogger(_logger)
.AddUrl($"grpc://*:{port}")
.Build();
await wireMockContainer.StartAsync();
return wireMockContainer;
}
private async Task<WireMockContainer> Given_WireMockContainerWithProtoDefinitionAtServerLevelIsStartedForHttpAndGrpcAsync()
{
var port = PortUtils.FindFreeTcpPort();
var wireMockContainer = new WireMockContainerBuilder()
.WithLogger(_logger)
.AddUrl($"grpc://*:{port}")
.AddProtoDefinition("my-greeter", ReadFile("greet.proto"))
.Build();
await wireMockContainer.StartAsync();
return wireMockContainer;
}
private async Task<WireMockContainer> Given_WireMockContainerWithProtoDefinitionAtServerLevelWithWatchStaticMappingsIsStartedForHttpAndGrpcAsync()
{
var port = PortUtils.FindFreeTcpPort();
var wireMockContainer = new WireMockContainerBuilder()
.WithLogger(_logger)
.AddUrl($"grpc://*:{port}")
.AddProtoDefinition("my-greeter", ReadFile("greet.proto"))
.WithMappings(Path.Combine(Directory.GetCurrentDirectory(), "__admin", "mappings"))
.Build();
await wireMockContainer.StartAsync();
return wireMockContainer;
}
private static async Task Given_ProtoBufMappingIsAddedViaAdminInterfaceAsync(WireMockContainer wireMockContainer, string filename)
{
var mappingsJson = ReadFile(filename);
using var httpClient = wireMockContainer.CreateClient();
var result = await httpClient.PostAsync("/__admin/mappings", new StringContent(mappingsJson, Encoding.UTF8, WireMockConstants.ContentTypeJson));
result.EnsureSuccessStatusCode();
}
private static void Then_ReplyMessage_Should_BeCorrect(HelloReply reply)
{
reply.Message.Should().Be("hello stef POST");
}
private static string ReadFile(string filename)
{
return File.ReadAllText(Path.Combine(Directory.GetCurrentDirectory(), "__admin", "mappings", filename));
}
}
#endif