Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WireMock.Net.Testcontainers: Use 'sheyenrath/wiremock.net-alpine' image as default for Linux #1181

Merged
merged 7 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 113 additions & 11 deletions examples/WireMock.Net.TestcontainersExample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright © WireMock.Net

using Newtonsoft.Json;
using Testcontainers.MsSql;
using WireMock.Net.Testcontainers;

namespace WireMock.Net.TestcontainersExample;
Expand All @@ -10,17 +9,125 @@ internal class Program
{
private static async Task Main(string[] args)
{
var container = new WireMockContainerBuilder()
var original = Console.ForegroundColor;
try
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Linux");
await TestAsync("sheyenrath/wiremock.net:1.6.4");
await Task.Delay(1_000);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.ForegroundColor = original;
}

try
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Linux Alpine");
await TestAsync("sheyenrath/wiremock.net-alpine:1.6.4");
await Task.Delay(1_000);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.ForegroundColor = original;
}

try
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine("WithLinux");
await TestAsync("WithLinux");
await Task.Delay(1_000);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.ForegroundColor = original;
}

try
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Windows");
await TestAsync("sheyenrath/wiremock.net-windows:1.6.4");
await Task.Delay(1_000);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.ForegroundColor = original;
}

try
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine("WithWindows");
await TestAsync("WithWindows");
await Task.Delay(1_000);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
Console.ForegroundColor = original;
}

try
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Automatic");
await TestAsync();
}
finally
{
Console.ForegroundColor = original;
}
}

private static async Task TestAsync(string? image = null)
{
var builder = new WireMockContainerBuilder()
.WithAdminUserNameAndPassword("x", "y")
.WithMappings(@"C:\Dev\GitHub\WireMock.Net\examples\WireMock.Net.Console.NET6\__admin\mappings")
.WithWatchStaticMappings(true)
.WithAutoRemove(true)
.WithCleanUp(true)
.Build();
.WithCleanUp(true);

if (image != null)
{
builder = image switch
{
"WithWindows" => builder.WithWindowsImage(),
"WithLinux" => builder.WithLinuxImage(),
_ => builder.WithImage(image)
};
}

var container = builder.Build();

await container.StartAsync().ConfigureAwait(false);
await container.StartAsync();

var logs = await container.GetLogsAsync(DateTime.Now.AddDays(-1)).ConfigureAwait(false);
await Task.Delay(1_000);

var logs = await container.GetLogsAsync(DateTime.Now.AddDays(-1));
Console.WriteLine("logs = " + logs.Stdout);

var restEaseApiClient = container.CreateWireMockAdminClient();
Expand All @@ -36,10 +143,5 @@ private static async Task Main(string[] args)
Console.WriteLine("result = " + result);

await container.StopAsync();

var sql = new MsSqlBuilder()
.WithAutoRemove(true)
.WithCleanUp(true)
.Build();
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Testcontainers.MsSql" Version="3.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Update="873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
57 changes: 43 additions & 14 deletions src/WireMock.Net.Testcontainers/WireMockContainerBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Docker.DotNet.Models;
using DotNet.Testcontainers.Builders;
Expand All @@ -17,15 +18,14 @@ namespace WireMock.Net.Testcontainers;
/// </summary>
public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContainerBuilder, WireMockContainer, WireMockConfiguration>
{
private readonly Dictionary<bool, ContainerInfo> _info = new()
private const string DefaultLogger = "WireMockConsoleLogger";
private readonly Dictionary<OSPlatform, ContainerInfo> _info = new()
{
{ false, new ContainerInfo("sheyenrath/wiremock.net:latest", "/app/__admin/mappings") },
{ true, new ContainerInfo("sheyenrath/wiremock.net-windows:latest", @"c:\app\__admin\mappings") }
{ OSPlatform.Linux, new ContainerInfo("sheyenrath/wiremock.net-alpine", "/app/__admin/mappings") },
{ OSPlatform.Windows, new ContainerInfo("sheyenrath/wiremock.net-windows", @"c:\app\__admin\mappings") }
};

private const string DefaultLogger = "WireMockConsoleLogger";

private readonly Lazy<Task<bool>> _isWindowsAsLazy = new(async () =>
private readonly Lazy<Task<OSPlatform>> _getOSAsLazy = new(async () =>
{
if (TestcontainersSettings.OS.DockerEndpointAuthConfig == null)
{
Expand All @@ -36,9 +36,11 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
using var dockerClient = dockerClientConfig.CreateClient();

var version = await dockerClient.System.GetVersionAsync();
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) > -1;
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) > -1 ? OSPlatform.Windows : OSPlatform.Linux;
StefH marked this conversation as resolved.
Show resolved Hide resolved
});

private OSPlatform? _imageOS;

/// <summary>
/// Initializes a new instance of the <see cref="ContainerBuilder" /> class.
/// </summary>
Expand All @@ -48,14 +50,36 @@ public WireMockContainerBuilder() : this(new WireMockConfiguration())
}

/// <summary>
/// Automatically set the correct image (Linux or Windows) for WireMock which to create the container.
/// Automatically use the correct image for WireMock.
/// For Linux this is "sheyenrath/wiremock.net-alpine:latest"
/// For Windows this is "sheyenrath/wiremock.net-windows:latest"
/// </summary>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
[PublicAPI]
public WireMockContainerBuilder WithImage()
{
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
return WithImage(_info[isWindows].Image);
_imageOS ??= _getOSAsLazy.Value.GetAwaiter().GetResult();
return WithImage(_imageOS.Value);
}

/// <summary>
/// Automatically use a Linux image for WireMock. This is "sheyenrath/wiremock.net-alpine:latest"
/// </summary>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
[PublicAPI]
public WireMockContainerBuilder WithLinuxImage()
{
return WithImage(OSPlatform.Linux);
}

/// <summary>
/// Automatically use a Windows image for WireMock. This is "sheyenrath/wiremock.net-windows:latest"
/// </summary>
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
[PublicAPI]
public WireMockContainerBuilder WithWindowsImage()
{
return WithImage(OSPlatform.Windows);
}

/// <summary>
Expand Down Expand Up @@ -120,11 +144,11 @@ public WireMockContainerBuilder WithMappings(string path, bool includeSubDirecto
{
Guard.NotNullOrEmpty(path);

var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
_imageOS ??= _getOSAsLazy.Value.GetAwaiter().GetResult();

return WithReadStaticMappings()
.WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}")
.WithBindMount(path, _info[isWindows].MappingsPath);
.WithBindMount(path, _info[_imageOS.Value].MappingsPath);
}

private WireMockContainerBuilder(WireMockConfiguration dockerResourceConfiguration) : base(dockerResourceConfiguration)
Expand Down Expand Up @@ -154,8 +178,7 @@ protected override WireMockContainerBuilder Init()
builder = builder.WithImage();
}

var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
var waitForContainerOS = isWindows ? Wait.ForWindowsContainer() : Wait.ForUnixContainer();
var waitForContainerOS = _imageOS is null || _imageOS == OSPlatform.Windows ? Wait.ForWindowsContainer() : Wait.ForUnixContainer();
return builder
.WithPortBinding(WireMockContainer.ContainerPort, true)
.WithCommand($"--WireMockLogger {DefaultLogger}")
Expand All @@ -179,4 +202,10 @@ protected override WireMockContainerBuilder Merge(WireMockConfiguration oldValue
{
return new WireMockContainerBuilder(new WireMockConfiguration(oldValue, newValue));
}

private WireMockContainerBuilder WithImage(OSPlatform os)
{
_imageOS = os;
return WithImage(_info[os].Image);
}
}
58 changes: 57 additions & 1 deletion test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#if NET6_0_OR_GREATER
using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using FluentAssertions;
using FluentAssertions.Execution;
Expand All @@ -13,7 +14,7 @@
public class TestcontainersTests
{
[Fact]
public async Task WireMockContainer_Build_and_StartAsync_and_StopAsync()
public async Task WireMockContainer_Build_WithNoImage_And_StartAsync_and_StopAsync()
{
// Act
var adminUsername = $"username_{Guid.NewGuid()}";
Expand All @@ -24,6 +25,61 @@
.WithAdminUserNameAndPassword(adminUsername, adminPassword)
.Build();

await StartTestAndStopAsync(wireMockContainer);
}

Check warning on line 30 in test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs

View check run for this annotation

Codecov / codecov/patch

test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs#L30

Added line #L30 was not covered by tests
[Fact]
public async Task WireMockContainer_Build_WithImage_And_StartAsync_and_StopAsync()
{
// Arrange

Check warning on line 34 in test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs

View check run for this annotation

Codecov / codecov/patch

test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs#L34

Added line #L34 was not covered by tests
var adminUsername = $"username_{Guid.NewGuid()}";
var adminPassword = $"password_{Guid.NewGuid()}";
var wireMockContainerBuilder = new WireMockContainerBuilder()
.WithAutoRemove(true)
.WithCleanUp(true)
.WithAdminUserNameAndPassword(adminUsername, adminPassword);

Check warning on line 41 in test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs

View check run for this annotation

Codecov / codecov/patch

test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs#L41

Added line #L41 was not covered by tests
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
wireMockContainerBuilder = wireMockContainerBuilder.WithWindowsImage();
}

Check warning on line 45 in test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs

View check run for this annotation

Codecov / codecov/patch

test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs#L43-L45

Added lines #L43 - L45 were not covered by tests
else
{
wireMockContainerBuilder = wireMockContainerBuilder.WithLinuxImage();
}

var wireMockContainer = wireMockContainerBuilder.Build();

await StartTestAndStopAsync(wireMockContainer);
}

Check warning on line 55 in test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs

View check run for this annotation

Codecov / codecov/patch

test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs#L55

Added line #L55 was not covered by tests
[Fact]
public async Task WireMockContainer_Build_WithImageAsText_And_StartAsync_and_StopAsync()
{
// Arrange
var adminUsername = $"username_{Guid.NewGuid()}";
var adminPassword = $"password_{Guid.NewGuid()}";
var wireMockContainerBuilder = new WireMockContainerBuilder()
.WithAutoRemove(true)
.WithCleanUp(true)
.WithAdminUserNameAndPassword(adminUsername, adminPassword);

Check warning on line 66 in test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs

View check run for this annotation

Codecov / codecov/patch

test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs#L66

Added line #L66 was not covered by tests
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
wireMockContainerBuilder = wireMockContainerBuilder.WithImage("sheyenrath/wiremock.net-windows");
}
else

Check warning on line 71 in test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs

View check run for this annotation

Codecov / codecov/patch

test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs#L68-L71

Added lines #L68 - L71 were not covered by tests
{
wireMockContainerBuilder = wireMockContainerBuilder.WithImage("sheyenrath/wiremock.net");
}

Check warning on line 75 in test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs

View check run for this annotation

Codecov / codecov/patch

test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs#L75

Added line #L75 was not covered by tests
var wireMockContainer = wireMockContainerBuilder.Build();

Check warning on line 77 in test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs

View check run for this annotation

Codecov / codecov/patch

test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs#L77

Added line #L77 was not covered by tests
await StartTestAndStopAsync(wireMockContainer);
}

private static async Task StartTestAndStopAsync(WireMockContainer wireMockContainer)

Check warning on line 81 in test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs

View check run for this annotation

Codecov / codecov/patch

test/WireMock.Net.Tests/Testcontainers/TestcontainersTests.cs#L81

Added line #L81 was not covered by tests
{
try
{
await wireMockContainer.StartAsync().ConfigureAwait(false);
Expand Down
Loading