From ab7ce37e7ea4d1b351a50cf6f96189de6935b3b3 Mon Sep 17 00:00:00 2001 From: Stef Heyenrath Date: Tue, 31 Dec 2024 18:24:29 +0100 Subject: [PATCH] Fix WireMockContainerBuilder (duplicate entries) (#1222) --- WireMock.Net Solution.sln.DotSettings | 1 + .../Program.cs | 124 +++++++++++------- ...ntainerUtils.cs => TestcontainersUtils.cs} | 8 +- .../WireMockContainer.cs | 2 +- .../WireMockContainerBuilder.cs | 22 +++- .../Facts/RunOnDockerPlatformFact.cs | 19 +++ .../Testcontainers/TestcontainersTests.cs | 24 +++- 7 files changed, 145 insertions(+), 55 deletions(-) rename src/WireMock.Net.Testcontainers/Utils/{ContainerUtils.cs => TestcontainersUtils.cs} (82%) create mode 100644 test/WireMock.Net.Tests/Facts/RunOnDockerPlatformFact.cs diff --git a/WireMock.Net Solution.sln.DotSettings b/WireMock.Net Solution.sln.DotSettings index d9257030..8d0a52ef 100644 --- a/WireMock.Net Solution.sln.DotSettings +++ b/WireMock.Net Solution.sln.DotSettings @@ -44,6 +44,7 @@ True True True + True True True True diff --git a/examples/WireMock.Net.TestcontainersExample/Program.cs b/examples/WireMock.Net.TestcontainersExample/Program.cs index b6ddb0c3..38a23149 100644 --- a/examples/WireMock.Net.TestcontainersExample/Program.cs +++ b/examples/WireMock.Net.TestcontainersExample/Program.cs @@ -1,7 +1,8 @@ // Copyright © WireMock.Net -using DotNet.Testcontainers.Configurations; using System.Runtime.InteropServices; +using DotNet.Testcontainers.Builders; +using DotNet.Testcontainers.Configurations; using Newtonsoft.Json; using WireMock.Net.Testcontainers; @@ -9,15 +10,33 @@ namespace WireMock.Net.TestcontainersExample; internal class Program { + private static readonly ConsoleColor OriginalColor = Console.ForegroundColor; + private static async Task Main(string[] args) { - var original = Console.ForegroundColor; + await TestLinux(); + + await TestAutomatic(); + + await TestLinuxWithVersionTag(); + + await TestLinuxAlpineWithVersionTag(); + + await TestWindowsWithVersionTag(); + + await TestWindows(); + + await TestCopy(); + } + private static async Task TestWindows() + { try { - Console.ForegroundColor = ConsoleColor.DarkGreen; - Console.WriteLine("Copy"); - await TestCopyAsync(); + Console.ForegroundColor = ConsoleColor.Blue; + Console.WriteLine("WithWindows"); + await TestAsync("WithWindows"); + await Task.Delay(1_000); } catch (Exception e) { @@ -25,25 +44,36 @@ private static async Task Main(string[] args) } finally { - Console.ForegroundColor = original; + Console.ForegroundColor = OriginalColor; } + } + private static async Task TestWindowsWithVersionTag() + { try { - Console.ForegroundColor = ConsoleColor.DarkRed; - Console.WriteLine("Automatic"); - await TestAsync(); + Console.ForegroundColor = ConsoleColor.Cyan; + Console.WriteLine("Windows"); + await TestAsync("sheyenrath/wiremock.net-windows:1.6.5"); + await Task.Delay(1_000); + } + catch (Exception e) + { + Console.WriteLine(e); } finally { - Console.ForegroundColor = original; + Console.ForegroundColor = OriginalColor; } + } + private static async Task TestLinux() + { try { - Console.ForegroundColor = ConsoleColor.Yellow; - Console.WriteLine("Linux"); - await TestAsync("sheyenrath/wiremock.net:1.6.5"); + Console.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine("WithLinux"); + await TestAsync("WithLinux"); await Task.Delay(1_000); } catch (Exception e) @@ -52,9 +82,12 @@ private static async Task Main(string[] args) } finally { - Console.ForegroundColor = original; + Console.ForegroundColor = OriginalColor; } + } + private static async Task TestLinuxAlpineWithVersionTag() + { try { Console.ForegroundColor = ConsoleColor.White; @@ -68,14 +101,17 @@ private static async Task Main(string[] args) } finally { - Console.ForegroundColor = original; + Console.ForegroundColor = OriginalColor; } + } + private static async Task TestLinuxWithVersionTag() + { try { - Console.ForegroundColor = ConsoleColor.Gray; - Console.WriteLine("WithLinux"); - await TestAsync("WithLinux"); + Console.ForegroundColor = ConsoleColor.Yellow; + Console.WriteLine("Linux"); + await TestAsync("sheyenrath/wiremock.net:1.6.5"); await Task.Delay(1_000); } catch (Exception e) @@ -84,31 +120,31 @@ private static async Task Main(string[] args) } finally { - Console.ForegroundColor = original; + Console.ForegroundColor = OriginalColor; } + } + private static async Task TestAutomatic() + { try { - Console.ForegroundColor = ConsoleColor.Cyan; - Console.WriteLine("Windows"); - await TestAsync("sheyenrath/wiremock.net-windows:1.6.5"); - await Task.Delay(1_000); - } - catch (Exception e) - { - Console.WriteLine(e); + Console.ForegroundColor = ConsoleColor.DarkRed; + Console.WriteLine("Automatic"); + await TestAsync(); } finally { - Console.ForegroundColor = original; + Console.ForegroundColor = OriginalColor; } + } + private static async Task TestCopy() + { try { - Console.ForegroundColor = ConsoleColor.Blue; - Console.WriteLine("WithWindows"); - await TestAsync("WithWindows"); - await Task.Delay(1_000); + Console.ForegroundColor = ConsoleColor.DarkGreen; + Console.WriteLine("Copy"); + await TestWindowsCopyAsync(); } catch (Exception e) { @@ -116,11 +152,11 @@ private static async Task Main(string[] args) } finally { - Console.ForegroundColor = original; + Console.ForegroundColor = OriginalColor; } } - private static async Task TestCopyAsync() + private static async Task TestWindowsCopyAsync() { var builder = new WireMockContainerBuilder() .WithWatchStaticMappings(true) @@ -152,9 +188,6 @@ private static async Task TestCopyAsync() await Task.Delay(1_000); - //Console.WriteLine("Press any key to stop."); - //Console.ReadKey(); - await container.StopAsync(); } @@ -162,11 +195,18 @@ private static async Task TestAsync(string? image = null) { var mappingsPath = Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "..", "..", "WireMock.Net.Console.NET6", "__admin", "mappings"); + var dummyNetwork = new NetworkBuilder() + .WithName($"Dummy Network for {image ?? "null"}") + .WithReuse(true) + .WithCleanUp(true) + .Build(); + var builder = new WireMockContainerBuilder() + .WithNetwork(dummyNetwork) .WithAdminUserNameAndPassword("x", "y") .WithMappings(mappingsPath) .WithWatchStaticMappings(true) - .WithAutoRemove(true) + // .WithAutoRemove(true) .WithCleanUp(true); if (image != null) @@ -202,16 +242,10 @@ private static async Task TestAsync(string? image = null) var result = await client.GetStringAsync("/static/mapping"); Console.WriteLine("result = " + result); - //if (image == null) - //{ - // Console.WriteLine("Press any key to stop."); - // Console.ReadKey(); - //} - await container.StopAsync(); } - private static Lazy> GetImageOSAsync = new(async () => + private static readonly Lazy> GetImageOSAsync = new(async () => { if (TestcontainersSettings.OS.DockerEndpointAuthConfig == null) { diff --git a/src/WireMock.Net.Testcontainers/Utils/ContainerUtils.cs b/src/WireMock.Net.Testcontainers/Utils/TestcontainersUtils.cs similarity index 82% rename from src/WireMock.Net.Testcontainers/Utils/ContainerUtils.cs rename to src/WireMock.Net.Testcontainers/Utils/TestcontainersUtils.cs index ce0d8113..ae1a7fc9 100644 --- a/src/WireMock.Net.Testcontainers/Utils/ContainerUtils.cs +++ b/src/WireMock.Net.Testcontainers/Utils/TestcontainersUtils.cs @@ -7,8 +7,14 @@ namespace WireMock.Net.Testcontainers.Utils; -internal static class ContainerUtils +/// +/// Some utility methods for containers. +/// +public static class TestcontainersUtils { + /// + /// Get the OS platform of the Docker image. + /// public static Lazy> GetImageOSAsync = new(async () => { if (TestcontainersSettings.OS.DockerEndpointAuthConfig == null) diff --git a/src/WireMock.Net.Testcontainers/WireMockContainer.cs b/src/WireMock.Net.Testcontainers/WireMockContainer.cs index 35394dce..141f03a4 100644 --- a/src/WireMock.Net.Testcontainers/WireMockContainer.cs +++ b/src/WireMock.Net.Testcontainers/WireMockContainer.cs @@ -164,7 +164,7 @@ protected override ValueTask DisposeAsyncCore() private static async Task PathStartsWithContainerMappingsPath(string value) { - var imageOs = await ContainerUtils.GetImageOSAsync.Value; + var imageOs = await TestcontainersUtils.GetImageOSAsync.Value; return value.StartsWith(ContainerInfoProvider.Info[imageOs].MappingsPath); } diff --git a/src/WireMock.Net.Testcontainers/WireMockContainerBuilder.cs b/src/WireMock.Net.Testcontainers/WireMockContainerBuilder.cs index 48c54eae..9ec17b05 100644 --- a/src/WireMock.Net.Testcontainers/WireMockContainerBuilder.cs +++ b/src/WireMock.Net.Testcontainers/WireMockContainerBuilder.cs @@ -36,7 +36,7 @@ public WireMockContainerBuilder() : this(new WireMockConfiguration()) [PublicAPI] public WireMockContainerBuilder WithImage() { - _imageOS ??= ContainerUtils.GetImageOSAsync.Value.GetAwaiter().GetResult(); + _imageOS ??= TestcontainersUtils.GetImageOSAsync.Value.GetAwaiter().GetResult(); return WithImage(_imageOS.Value); } @@ -108,9 +108,10 @@ public WireMockContainerBuilder WithReadStaticMappings() [PublicAPI] public WireMockContainerBuilder WithWatchStaticMappings(bool includeSubDirectories) { - return Merge(DockerResourceConfiguration, DockerResourceConfiguration.WithWatchStaticMappings(includeSubDirectories)) - .WithCommand("--WatchStaticMappings true") - .WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}"); + DockerResourceConfiguration.WithWatchStaticMappings(includeSubDirectories); + return + WithCommand("--WatchStaticMappings true"). + WithCommand("--WatchStaticMappingsInSubdirectories", includeSubDirectories); } /// @@ -124,9 +125,16 @@ public WireMockContainerBuilder WithMappings(string path, bool includeSubDirecto { Guard.NotNullOrEmpty(path); - return Merge(DockerResourceConfiguration, DockerResourceConfiguration.WithStaticMappingsPath(path)) - .WithReadStaticMappings() - .WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}"); + DockerResourceConfiguration.WithStaticMappingsPath(path); + + return + WithReadStaticMappings(). + WithCommand("--WatchStaticMappingsInSubdirectories", includeSubDirectories); + } + + private WireMockContainerBuilder WithCommand(string param, bool value) + { + return !value ? this : WithCommand($"{param} true"); } private WireMockContainerBuilder(WireMockConfiguration dockerResourceConfiguration) : base(dockerResourceConfiguration) diff --git a/test/WireMock.Net.Tests/Facts/RunOnDockerPlatformFact.cs b/test/WireMock.Net.Tests/Facts/RunOnDockerPlatformFact.cs new file mode 100644 index 00000000..9d479a0f --- /dev/null +++ b/test/WireMock.Net.Tests/Facts/RunOnDockerPlatformFact.cs @@ -0,0 +1,19 @@ +// Copyright © WireMock.Net +#if NET6_0_OR_GREATER +using System.Runtime.InteropServices; +using WireMock.Net.Testcontainers.Utils; +using Xunit; + +namespace WireMock.Net.Tests.Facts; + +public sealed class RunOnDockerPlatformFact : FactAttribute +{ + public RunOnDockerPlatformFact(string platform) + { + if (TestcontainersUtils.GetImageOSAsync.Value.Result != OSPlatform.Create(platform)) + { + Skip = $"Only run test when Docker OS Platform {platform} is used."; + } + } +} +#endif \ No newline at end of file diff --git a/test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs b/test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs index e4b6af95..1b0f1bc1 100644 --- a/test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs +++ b/test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs @@ -4,9 +4,11 @@ using System; using System.Runtime.InteropServices; using System.Threading.Tasks; +using DotNet.Testcontainers.Builders; using FluentAssertions; using FluentAssertions.Execution; using WireMock.Net.Testcontainers; +using WireMock.Net.Tests.Facts; using Xunit; namespace WireMock.Net.Tests.Testcontainers; @@ -27,7 +29,27 @@ public async Task WireMockContainer_Build_WithNoImage_And_StartAsync_and_StopAsy await StartTestAndStopAsync(wireMockContainer); } - + + // https://github.com/testcontainers/testcontainers-dotnet/issues/1322 + [RunOnDockerPlatformFact("Linux")] + public async Task WireMockContainer_Build_WithNoImageAndNetwork_And_StartAsync_and_StopAsync() + { + // Act + var dummyNetwork = new NetworkBuilder() + .WithName("Dummy Network for TestcontainersTests") + .WithCleanUp(true) + .Build(); + + var wireMockContainer = new WireMockContainerBuilder() + .WithNetwork(dummyNetwork) + .WithWatchStaticMappings(true) + .WithAutoRemove(true) + .WithCleanUp(true) + .Build(); + + await StartTestAndStopAsync(wireMockContainer); + } + [Fact] public async Task WireMockContainer_Build_WithImage_And_StartAsync_and_StopAsync() {