Skip to content

Commit d7a81fd

Browse files
chore: reflect tcp only in name and reduce code duplication
1 parent 0e54a69 commit d7a81fd

File tree

9 files changed

+64
-95
lines changed

9 files changed

+64
-95
lines changed

src/Testcontainers/Configurations/WaitStrategies/HostPortWaitStrategy.cs

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
using System.Net.Sockets;
2+
using System.Threading.Tasks;
3+
using DotNet.Testcontainers.Containers;
4+
5+
namespace DotNet.Testcontainers.Configurations
6+
{
7+
/// <summary>
8+
/// Wait for a TCP connection to be established.
9+
/// </summary>
10+
/// <remarks>
11+
/// Some docker configurations (DockerForMac & Rancher on Mac & Windows) allow establishing a connection to any mapped port.
12+
/// https://forums.docker.com/t/port-forwarding-of-exposed-ports-behaves-unexpectedly/15807
13+
/// In these cases, the mapped port is always available even if the container is not listening on it.
14+
/// </remarks>
15+
/// <param name="port">The container port to check.</param>
16+
internal sealed class HostTcpPortWaitStrategy(int port) : IWaitUntil
17+
{
18+
// We don't have access to all mapped ports, so we need the user to provide the container port.
19+
private readonly int _containerPort = port;
20+
21+
public async Task<bool> UntilAsync(IContainer container)
22+
{
23+
ushort hostPort;
24+
try
25+
{
26+
hostPort = container.GetMappedPublicPort(_containerPort);
27+
}
28+
catch
29+
{
30+
return false;
31+
}
32+
33+
using var tcpClient = new TcpClient();
34+
try
35+
{
36+
await tcpClient.ConnectAsync(container.Hostname, hostPort)
37+
.ConfigureAwait(false);
38+
return tcpClient.Connected;
39+
}
40+
catch
41+
{
42+
return false;
43+
}
44+
}
45+
}
46+
}

src/Testcontainers/Configurations/WaitStrategies/IWaitForContainerOS.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,13 @@ public interface IWaitForContainerOS
6868
IWaitForContainerOS UntilPortIsAvailable(int port, Action<IWaitStrategy> waitStrategyModifier = null);
6969

7070
/// <summary>
71-
/// Waits until the tcp connection is established successfully from host.
71+
/// Waits until the TCP port is available in the container and a connection can be established from the host to the container.
7272
/// </summary>
73-
/// <remarks>
74-
/// Some docker configurations (DockerForMac & Rancher on Mac & Windows) allow establishing a connection to any mapped port.
75-
/// The test will always succeed in these cases.
76-
/// </remarks>
7773
/// <param name="port">The container port to be checked.</param>
7874
/// <param name="waitStrategyModifier">The wait strategy modifier to cancel the readiness check.</param>
7975
/// <returns>A configured instance of <see cref="IWaitForContainerOS" />.</returns>
8076
[PublicAPI]
81-
IWaitForContainerOS UntilHostPortAvailable(int port, Action<IWaitStrategy> waitStrategyModifier = null);
77+
IWaitForContainerOS UntilHostTcpPortAvailable(int port, Action<IWaitStrategy> waitStrategyModifier = null);
8278

8379

8480
/// <summary>

src/Testcontainers/Configurations/WaitStrategies/UntilTcpConnected.cs

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/Testcontainers/Configurations/WaitStrategies/WaitForContainerOS.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ public IEnumerable<WaitStrategy> Build()
9494
}
9595

9696
/// <inheritdoc />
97-
abstract public IWaitForContainerOS UntilHostPortAvailable(int port, Action<IWaitStrategy> waitStrategyModifier = null);
97+
public IWaitForContainerOS UntilHostTcpPortAvailable(int port, Action<IWaitStrategy> waitStrategyModifier = null)
98+
{
99+
UntilPortIsAvailable(port, waitStrategyModifier);
100+
return AddCustomWaitStrategy(new HostTcpPortWaitStrategy(port), waitStrategyModifier);
101+
}
98102
}
99103
}

src/Testcontainers/Configurations/WaitStrategies/WaitForContainerUnix.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@ public override IWaitForContainerOS UntilCommandIsCompleted(IEnumerable<string>
2525
return AddCustomWaitStrategy(new UntilUnixCommandIsCompleted(command.ToArray()), waitStrategyModifier);
2626
}
2727

28-
public override IWaitForContainerOS UntilHostPortAvailable(int port, Action<IWaitStrategy> waitStrategyModifier = null)
29-
{
30-
UntilPortIsAvailable(port, waitStrategyModifier);
31-
return AddCustomWaitStrategy(new HostPortWaitStrategy(port), waitStrategyModifier);
32-
}
33-
3428
/// <inheritdoc />
3529
public override IWaitForContainerOS UntilPortIsAvailable(int port, Action<IWaitStrategy> waitStrategyModifier = null)
3630
{

src/Testcontainers/Configurations/WaitStrategies/WaitForContainerWindows.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@ public override IWaitForContainerOS UntilCommandIsCompleted(IEnumerable<string>
2525
return AddCustomWaitStrategy(new UntilWindowsCommandIsCompleted(command.ToArray()), waitStrategyModifier);
2626
}
2727

28-
public override IWaitForContainerOS UntilHostPortAvailable(int port, Action<IWaitStrategy> waitStrategyModifier = null)
29-
{
30-
UntilPortIsAvailable(port, waitStrategyModifier);
31-
return AddCustomWaitStrategy(new HostPortWaitStrategy(port), waitStrategyModifier);
32-
}
33-
3428
/// <inheritdoc />
3529
public override IWaitForContainerOS UntilPortIsAvailable(int port, Action<IWaitStrategy> waitStrategyModifier = null)
3630
{

tests/Testcontainers.Platform.Windows.Tests/WindowsContainerTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ public UntilPortIsAvailable()
6464
}
6565

6666
[UsedImplicitly]
67-
public sealed class UntilHostPortIsAvailable : WindowsContainerTest
67+
public sealed class UntilHostTcpPortIsAvailable : WindowsContainerTest
6868
{
69-
public UntilHostPortIsAvailable()
69+
public UntilHostTcpPortIsAvailable()
7070
: base(new ContainerBuilder()
7171
.WithImage(CommonImages.ServerCore)
7272
.WithEntrypoint("PowerShell", "-NoLogo", "-Command")
7373
.WithCommand("$tcpListener = [System.Net.Sockets.TcpListener]80; $tcpListener.Start(); Start-Sleep -Seconds 120")
74-
.WithWaitStrategy(Wait.ForWindowsContainer().UntilHostPortAvailable(80))
74+
.WithWaitStrategy(Wait.ForWindowsContainer().UntilHostTcpPortAvailable(80))
7575
.Build())
7676
{
7777
}

tests/Testcontainers.Tests/Unit/Configurations/HostPortWaitStrategyTest.cs renamed to tests/Testcontainers.Tests/Unit/Configurations/HostTcpPortWaitStrategyTest.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace DotNet.Testcontainers.Tests.Unit
88
using JetBrains.Annotations;
99
using Xunit;
1010

11-
public sealed class HostPortWaitStrategyTest : IAsyncLifetime
11+
public sealed class HostTcpPortWaitStrategyTest : IAsyncLifetime
1212
{
1313
private const int listeningPort = 49152;
1414
private const int mappedPort = 49153;
@@ -20,7 +20,7 @@ public sealed class HostPortWaitStrategyTest : IAsyncLifetime
2020
.WithCommand("EXEC:cat")
2121
.WithPortBinding(listeningPort, true)
2222
.WithPortBinding(mappedPort, true)
23-
.WithWaitStrategy(Wait.ForUnixContainer().UntilHostPortAvailable(listeningPort))
23+
.WithWaitStrategy(Wait.ForUnixContainer().UntilHostTcpPortAvailable(listeningPort))
2424
.Build();
2525

2626
public async ValueTask InitializeAsync()
@@ -35,9 +35,9 @@ public ValueTask DisposeAsync()
3535
}
3636

3737
[Fact]
38-
public async Task hostPortWaitStrategyIsSucceeded()
38+
public async Task HostTcpPortWaitStrategyIsSucceeded()
3939
{
40-
var hostPortWaitStrategy = new HostPortWaitStrategy(listeningPort);
40+
var hostPortWaitStrategy = new HostTcpPortWaitStrategy(listeningPort);
4141

4242
var succeeded = await hostPortWaitStrategy.UntilAsync(_container);
4343

@@ -49,19 +49,19 @@ public async Task hostPortWaitStrategyIsSucceeded()
4949
/// This test might fail in docker configurations where mapped ports are always listened eg. DockerForMac (https://forums.docker.com/t/port-forwarding-of-exposed-ports-behaves-unexpectedly/15807/2)
5050
/// </summary>
5151
[Fact]
52-
public async Task hostPortWaitStrategyFailsWhenPortNotListening()
52+
public async Task HostTcpPortWaitStrategyFailsWhenPortNotListening()
5353
{
54-
var hostPortWaitStrategy = new HostPortWaitStrategy(mappedPort);
54+
var hostPortWaitStrategy = new HostTcpPortWaitStrategy(mappedPort);
5555

5656
var succeeded = await hostPortWaitStrategy.UntilAsync(_container);
5757

5858
Assert.False(succeeded);
5959
}
6060

6161
[Fact]
62-
public async Task hostPortWaitStrategyFailsWhenPortNotMapped()
62+
public async Task HostTcpPortWaitStrategyFailsWhenPortNotMapped()
6363
{
64-
var hostPortWaitStrategy = new HostPortWaitStrategy(unmappedPort);
64+
var hostPortWaitStrategy = new HostTcpPortWaitStrategy(unmappedPort);
6565

6666
var succeeded = await hostPortWaitStrategy.UntilAsync(_container);
6767

0 commit comments

Comments
 (0)