Skip to content

Commit 8b71d9b

Browse files
committed
[#129] #EXTEND 'assemblyName: DotNet.Testcontainers; function: IDockerContainer'
{Add GetMappedPublicPort to get the public host port associated with the private container port.}
1 parent 8d44cc2 commit 8b71d9b

File tree

4 files changed

+52
-6
lines changed

4 files changed

+52
-6
lines changed

src/DotNet.Testcontainers.Tests/Unit/Linux/TestcontainersContainerTest.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,14 @@ public async Task PortBindingsHttpAndHttps()
112112

113113
var https = new { From = 443, To = 80 };
114114

115-
var nginx = new TestcontainersBuilder<TestcontainersContainer>()
115+
var testcontainersBuilder = new TestcontainersBuilder<TestcontainersContainer>()
116116
.WithImage("nginx");
117117

118118
// When
119119
// Then
120120
foreach (var port in new[] { http, https })
121121
{
122-
using (var testcontainer = nginx
122+
using (var testcontainer = testcontainersBuilder
123123
.WithPortBinding(port.From, port.To)
124124
.WithWaitStrategy(Wait.UntilPortsAreAvailable(port.To))
125125
.Build())
@@ -137,6 +137,23 @@ public async Task PortBindingsHttpAndHttps()
137137
}
138138
}
139139

140+
[Fact]
141+
public async Task RandomHostPortBindings()
142+
{
143+
// Given
144+
var testcontainersBuilder = new TestcontainersBuilder<TestcontainersContainer>()
145+
.WithImage("nginx")
146+
.WithPortBinding(80, true);
147+
148+
// When
149+
// Then
150+
using (var testcontainer = testcontainersBuilder.Build())
151+
{
152+
await testcontainer.StartAsync();
153+
Assert.NotEqual(0, testcontainer.GetMappedPublicPort(80));
154+
}
155+
}
156+
140157
[Fact]
141158
public async Task VolumeAndCommand()
142159
{

src/DotNet.Testcontainers/Core/Builder/TestcontainersBuilder.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,7 @@ public ITestcontainersBuilder<T> WithExposedPort(string port)
110110

111111
public ITestcontainersBuilder<T> WithPortBinding(int port, bool assignRandomHostPort = false)
112112
{
113-
var hostPort = assignRandomHostPort ? TestcontainersNetworkService.GetAvailablePort() : port;
114-
return this.WithPortBinding(hostPort, port);
113+
return this.WithPortBinding($"{port}", assignRandomHostPort);
115114
}
116115

117116
public ITestcontainersBuilder<T> WithPortBinding(int hostPort, int containerPort)

src/DotNet.Testcontainers/Core/Containers/IDockerContainer.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,20 @@ public interface IDockerContainer : IDisposable
2121
/// <value>Returns the Docker container mac address if present or an empty string instead.</value>
2222
string MacAddress { get; }
2323

24+
/// <summary>
25+
/// Gets the public host port associated with the private container port.
26+
/// </summary>
27+
/// <param name="privatePort">Private container port.</param>
28+
/// <returns>Returns the public host port associated with the private container port.</returns>
29+
int GetMappedPublicPort(int privatePort);
30+
31+
/// <summary>
32+
/// Gets the public host port associated with the private container port.
33+
/// </summary>
34+
/// <param name="privatePort">Private container port.</param>
35+
/// <returns>Returns the public host port associated with the private container port.</returns>
36+
int GetMappedPublicPort(string privatePort);
37+
2438
/// <summary>
2539
/// Starts the Testcontainer. If the image does not exist, it will be downloaded automatically. Non-existing containers are created at first start.
2640
/// </summary>

src/DotNet.Testcontainers/Core/Containers/TestcontainersContainer.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public string IPAddress
6666
}
6767

6868
var ipAddress = this.container.NetworkSettings.Networks.FirstOrDefault();
69-
return ipAddress.Value == null ? string.Empty : ipAddress.Value.IPAddress;
69+
return ipAddress.Value?.IPAddress ?? string.Empty;
7070
}
7171
}
7272

@@ -80,12 +80,28 @@ public string MacAddress
8080
}
8181

8282
var macAddress = this.container.NetworkSettings.Networks.FirstOrDefault();
83-
return macAddress.Value == null ? string.Empty : macAddress.Value.IPAddress;
83+
return macAddress.Value?.MacAddress ?? string.Empty;
8484
}
8585
}
8686

8787
private TestcontainersConfiguration Configuration { get; }
8888

89+
public int GetMappedPublicPort(int privatePort)
90+
{
91+
return this.GetMappedPublicPort($"{privatePort}");
92+
}
93+
94+
public int GetMappedPublicPort(string privatePort)
95+
{
96+
if (this.container == null)
97+
{
98+
throw new InvalidOperationException("Testcontainer is not running.");
99+
}
100+
101+
var mappedPort = this.container.Ports.FirstOrDefault(port => $"{port.PrivatePort}".Equals(privatePort));
102+
return mappedPort?.PublicPort ?? 0;
103+
}
104+
89105
public async Task StartAsync()
90106
{
91107
await this.Create();

0 commit comments

Comments
 (0)