Skip to content

Commit dca3fd0

Browse files
authored
WireMock.Net.Testcontainers: Use 'sheyenrath/wiremock.net-alpine' image as default for Linux (#1181)
* WireMock.Net.Testcontainers: Use 'sheyenrath/wiremock.net-alpine' image as default for Linux * ... * . * WithBindMount * fix * r * .
1 parent 9599442 commit dca3fd0

File tree

4 files changed

+265
-57
lines changed

4 files changed

+265
-57
lines changed
Lines changed: 124 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright © WireMock.Net
22

3+
using System.Runtime.InteropServices;
34
using Newtonsoft.Json;
4-
using Testcontainers.MsSql;
55
using WireMock.Net.Testcontainers;
66

77
namespace WireMock.Net.TestcontainersExample;
@@ -10,17 +10,134 @@ internal class Program
1010
{
1111
private static async Task Main(string[] args)
1212
{
13-
var container = new WireMockContainerBuilder()
13+
var original = Console.ForegroundColor;
14+
15+
try
16+
{
17+
Console.ForegroundColor = ConsoleColor.Yellow;
18+
Console.WriteLine("Linux");
19+
await TestAsync("sheyenrath/wiremock.net:1.6.4");
20+
await Task.Delay(1_000);
21+
}
22+
catch (Exception e)
23+
{
24+
Console.WriteLine(e);
25+
}
26+
finally
27+
{
28+
Console.ForegroundColor = original;
29+
}
30+
31+
try
32+
{
33+
Console.ForegroundColor = ConsoleColor.White;
34+
Console.WriteLine("Linux Alpine");
35+
await TestAsync("sheyenrath/wiremock.net-alpine:1.6.4");
36+
await Task.Delay(1_000);
37+
}
38+
catch (Exception e)
39+
{
40+
Console.WriteLine(e);
41+
}
42+
finally
43+
{
44+
Console.ForegroundColor = original;
45+
}
46+
47+
try
48+
{
49+
Console.ForegroundColor = ConsoleColor.Gray;
50+
Console.WriteLine("WithLinux");
51+
await TestAsync("WithLinux");
52+
await Task.Delay(1_000);
53+
}
54+
catch (Exception e)
55+
{
56+
Console.WriteLine(e);
57+
}
58+
finally
59+
{
60+
Console.ForegroundColor = original;
61+
}
62+
63+
try
64+
{
65+
Console.ForegroundColor = ConsoleColor.Cyan;
66+
Console.WriteLine("Windows");
67+
await TestAsync("sheyenrath/wiremock.net-windows:1.6.4");
68+
await Task.Delay(1_000);
69+
}
70+
catch (Exception e)
71+
{
72+
Console.WriteLine(e);
73+
}
74+
finally
75+
{
76+
Console.ForegroundColor = original;
77+
}
78+
79+
try
80+
{
81+
Console.ForegroundColor = ConsoleColor.Blue;
82+
Console.WriteLine("WithWindows");
83+
await TestAsync("WithWindows");
84+
await Task.Delay(1_000);
85+
}
86+
catch (Exception e)
87+
{
88+
Console.WriteLine(e);
89+
}
90+
finally
91+
{
92+
Console.ForegroundColor = original;
93+
}
94+
95+
try
96+
{
97+
Console.ForegroundColor = ConsoleColor.Red;
98+
Console.WriteLine("Automatic");
99+
await TestAsync();
100+
}
101+
finally
102+
{
103+
Console.ForegroundColor = original;
104+
}
105+
}
106+
107+
private static async Task TestAsync(string? image = null)
108+
{
109+
var builder = new WireMockContainerBuilder()
14110
.WithAdminUserNameAndPassword("x", "y")
15-
.WithMappings(@"C:\Dev\GitHub\WireMock.Net\examples\WireMock.Net.Console.NET6\__admin\mappings")
16111
.WithWatchStaticMappings(true)
17112
.WithAutoRemove(true)
18-
.WithCleanUp(true)
19-
.Build();
113+
.WithCleanUp(true);
114+
115+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
116+
{
117+
builder = builder.WithMappings(@"C:\Dev\GitHub\WireMock.Net\examples\WireMock.Net.Console.NET6\__admin\mappings");
118+
}
119+
else
120+
{
121+
builder = builder.WithMappings("./examples/WireMock.Net.Console.NET6/__admin/mappings");
122+
}
123+
124+
if (image != null)
125+
{
126+
builder = image switch
127+
{
128+
"WithWindows" => builder.WithWindowsImage(),
129+
"WithLinux" => builder.WithLinuxImage(),
130+
_ => builder.WithImage(image)
131+
};
132+
}
133+
134+
var container = builder.Build();
20135

21-
await container.StartAsync().ConfigureAwait(false);
136+
await container.StartAsync();
22137

23-
var logs = await container.GetLogsAsync(DateTime.Now.AddDays(-1)).ConfigureAwait(false);
138+
await Task.Delay(1_000);
139+
140+
var logs = await container.GetLogsAsync(DateTime.Now.AddDays(-1));
24141
Console.WriteLine("logs = " + logs.Stdout);
25142

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

38155
await container.StopAsync();
39-
40-
var sql = new MsSqlBuilder()
41-
.WithAutoRemove(true)
42-
.WithCleanUp(true)
43-
.Build();
44156
}
45157
}
Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
4-
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
6-
<ImplicitUsings>enable</ImplicitUsings>
7-
<Nullable>enable</Nullable>
8-
</PropertyGroup>
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
99

10-
<ItemGroup>
11-
<PackageReference Include="Testcontainers.MsSql" Version="3.6.0" />
12-
</ItemGroup>
10+
<ItemGroup>
11+
<ProjectReference Include="..\..\src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj" />
12+
</ItemGroup>
1313

14-
<ItemGroup>
15-
<ProjectReference Include="..\..\src\WireMock.Net.Testcontainers\WireMock.Net.Testcontainers.csproj" />
16-
</ItemGroup>
17-
18-
<ItemGroup>
19-
<None Update="873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
20-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
21-
</None>
22-
</ItemGroup>
14+
<ItemGroup>
15+
<None Update="873d495f-940e-4b86-a1f4-4f0fc7be8b8b.json">
16+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
17+
</None>
18+
</ItemGroup>
2319

2420
</Project>

src/WireMock.Net.Testcontainers/WireMockContainerBuilder.cs

Lines changed: 70 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
using System;
44
using System.Collections.Generic;
5+
using System.Runtime.InteropServices;
56
using System.Threading.Tasks;
67
using Docker.DotNet.Models;
78
using DotNet.Testcontainers.Builders;
@@ -17,15 +18,14 @@ namespace WireMock.Net.Testcontainers;
1718
/// </summary>
1819
public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContainerBuilder, WireMockContainer, WireMockConfiguration>
1920
{
20-
private readonly Dictionary<bool, ContainerInfo> _info = new()
21+
private const string DefaultLogger = "WireMockConsoleLogger";
22+
private readonly Dictionary<OSPlatform, ContainerInfo> _info = new()
2123
{
22-
{ false, new ContainerInfo("sheyenrath/wiremock.net:latest", "/app/__admin/mappings") },
23-
{ true, new ContainerInfo("sheyenrath/wiremock.net-windows:latest", @"c:\app\__admin\mappings") }
24+
{ OSPlatform.Linux, new ContainerInfo("sheyenrath/wiremock.net-alpine", "/app/__admin/mappings") },
25+
{ OSPlatform.Windows, new ContainerInfo("sheyenrath/wiremock.net-windows", @"c:\app\__admin\mappings") }
2426
};
2527

26-
private const string DefaultLogger = "WireMockConsoleLogger";
27-
28-
private readonly Lazy<Task<bool>> _isWindowsAsLazy = new(async () =>
28+
private readonly Lazy<Task<OSPlatform>> _getOSAsLazy = new(async () =>
2929
{
3030
if (TestcontainersSettings.OS.DockerEndpointAuthConfig == null)
3131
{
@@ -36,9 +36,12 @@ public sealed class WireMockContainerBuilder : ContainerBuilder<WireMockContaine
3636
using var dockerClient = dockerClientConfig.CreateClient();
3737

3838
var version = await dockerClient.System.GetVersionAsync();
39-
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) > -1;
39+
return version.Os.IndexOf("Windows", StringComparison.OrdinalIgnoreCase) >= 0 ? OSPlatform.Windows : OSPlatform.Linux;
4040
});
4141

42+
private OSPlatform? _imageOS;
43+
private string? _staticMappingsPath;
44+
4245
/// <summary>
4346
/// Initializes a new instance of the <see cref="ContainerBuilder" /> class.
4447
/// </summary>
@@ -48,14 +51,36 @@ public WireMockContainerBuilder() : this(new WireMockConfiguration())
4851
}
4952

5053
/// <summary>
51-
/// Automatically set the correct image (Linux or Windows) for WireMock which to create the container.
54+
/// Automatically use the correct image for WireMock.
55+
/// For Linux this is "sheyenrath/wiremock.net-alpine:latest"
56+
/// For Windows this is "sheyenrath/wiremock.net-windows:latest"
5257
/// </summary>
5358
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
5459
[PublicAPI]
5560
public WireMockContainerBuilder WithImage()
5661
{
57-
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
58-
return WithImage(_info[isWindows].Image);
62+
_imageOS ??= _getOSAsLazy.Value.GetAwaiter().GetResult();
63+
return WithImage(_imageOS.Value);
64+
}
65+
66+
/// <summary>
67+
/// Automatically use a Linux image for WireMock. This is "sheyenrath/wiremock.net-alpine:latest"
68+
/// </summary>
69+
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
70+
[PublicAPI]
71+
public WireMockContainerBuilder WithLinuxImage()
72+
{
73+
return WithImage(OSPlatform.Linux);
74+
}
75+
76+
/// <summary>
77+
/// Automatically use a Windows image for WireMock. This is "sheyenrath/wiremock.net-windows:latest"
78+
/// </summary>
79+
/// <returns>A configured instance of <see cref="WireMockContainerBuilder"/></returns>
80+
[PublicAPI]
81+
public WireMockContainerBuilder WithWindowsImage()
82+
{
83+
return WithImage(OSPlatform.Windows);
5984
}
6085

6186
/// <summary>
@@ -118,13 +143,9 @@ public WireMockContainerBuilder WithWatchStaticMappings(bool includeSubDirectori
118143
[PublicAPI]
119144
public WireMockContainerBuilder WithMappings(string path, bool includeSubDirectories = false)
120145
{
121-
Guard.NotNullOrEmpty(path);
122-
123-
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
146+
_staticMappingsPath = Guard.NotNullOrEmpty(path);
124147

125-
return WithReadStaticMappings()
126-
.WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}")
127-
.WithBindMount(path, _info[isWindows].MappingsPath);
148+
return WithReadStaticMappings().WithCommand($"--WatchStaticMappingsInSubdirectories {includeSubDirectories}");
128149
}
129150

130151
private WireMockContainerBuilder(WireMockConfiguration dockerResourceConfiguration) : base(dockerResourceConfiguration)
@@ -138,24 +159,41 @@ private WireMockContainerBuilder(WireMockConfiguration dockerResourceConfigurati
138159
/// <inheritdoc />
139160
public override WireMockContainer Build()
140161
{
141-
Validate();
162+
var builder = this;
142163

143-
return new WireMockContainer(DockerResourceConfiguration);
164+
// In case no image has been set, set the image using internal logic.
165+
if (DockerResourceConfiguration.Image == null)
166+
{
167+
builder = WithImage();
168+
}
169+
170+
// In case the _imageOS is not set, determine it from the Image FullName.
171+
if (_imageOS == null)
172+
{
173+
if (builder.DockerResourceConfiguration.Image.FullName.IndexOf("wiremock.net", StringComparison.OrdinalIgnoreCase) < 0)
174+
{
175+
throw new InvalidOperationException();
176+
}
177+
178+
_imageOS = builder.DockerResourceConfiguration.Image.FullName.IndexOf("windows", StringComparison.OrdinalIgnoreCase) >= 0 ? OSPlatform.Windows : OSPlatform.Linux;
179+
}
180+
181+
if (!string.IsNullOrEmpty(_staticMappingsPath))
182+
{
183+
builder = builder.WithBindMount(_staticMappingsPath, _info[_imageOS.Value].MappingsPath);
184+
}
185+
186+
builder.Validate();
187+
188+
return new WireMockContainer(builder.DockerResourceConfiguration);
144189
}
145190

146191
/// <inheritdoc />
147192
protected override WireMockContainerBuilder Init()
148193
{
149194
var builder = base.Init();
150195

151-
// In case no image has been set, set the image using internal logic.
152-
if (builder.DockerResourceConfiguration.Image == null)
153-
{
154-
builder = builder.WithImage();
155-
}
156-
157-
var isWindows = _isWindowsAsLazy.Value.GetAwaiter().GetResult();
158-
var waitForContainerOS = isWindows ? Wait.ForWindowsContainer() : Wait.ForUnixContainer();
196+
var waitForContainerOS = _imageOS == OSPlatform.Windows ? Wait.ForWindowsContainer() : Wait.ForUnixContainer();
159197
return builder
160198
.WithPortBinding(WireMockContainer.ContainerPort, true)
161199
.WithCommand($"--WireMockLogger {DefaultLogger}")
@@ -179,4 +217,10 @@ protected override WireMockContainerBuilder Merge(WireMockConfiguration oldValue
179217
{
180218
return new WireMockContainerBuilder(new WireMockConfiguration(oldValue, newValue));
181219
}
220+
221+
private WireMockContainerBuilder WithImage(OSPlatform os)
222+
{
223+
_imageOS = os;
224+
return WithImage(_info[os].Image);
225+
}
182226
}

0 commit comments

Comments
 (0)