From 8b71d9b302f4a594b6ed749f2910fccf0002ea51 Mon Sep 17 00:00:00 2001 From: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com> Date: Thu, 15 Aug 2019 12:45:34 +0200 Subject: [PATCH] [#129] #EXTEND 'assemblyName: DotNet.Testcontainers; function: IDockerContainer' {Add GetMappedPublicPort to get the public host port associated with the private container port.} --- .../Unit/Linux/TestcontainersContainerTest.cs | 21 +++++++++++++++++-- .../Core/Builder/TestcontainersBuilder.cs | 3 +-- .../Core/Containers/IDockerContainer.cs | 14 +++++++++++++ .../Containers/TestcontainersContainer.cs | 20 ++++++++++++++++-- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/src/DotNet.Testcontainers.Tests/Unit/Linux/TestcontainersContainerTest.cs b/src/DotNet.Testcontainers.Tests/Unit/Linux/TestcontainersContainerTest.cs index 8359bde24..ca81c7f06 100644 --- a/src/DotNet.Testcontainers.Tests/Unit/Linux/TestcontainersContainerTest.cs +++ b/src/DotNet.Testcontainers.Tests/Unit/Linux/TestcontainersContainerTest.cs @@ -112,14 +112,14 @@ public async Task PortBindingsHttpAndHttps() var https = new { From = 443, To = 80 }; - var nginx = new TestcontainersBuilder() + var testcontainersBuilder = new TestcontainersBuilder() .WithImage("nginx"); // When // Then foreach (var port in new[] { http, https }) { - using (var testcontainer = nginx + using (var testcontainer = testcontainersBuilder .WithPortBinding(port.From, port.To) .WithWaitStrategy(Wait.UntilPortsAreAvailable(port.To)) .Build()) @@ -137,6 +137,23 @@ public async Task PortBindingsHttpAndHttps() } } + [Fact] + public async Task RandomHostPortBindings() + { + // Given + var testcontainersBuilder = new TestcontainersBuilder() + .WithImage("nginx") + .WithPortBinding(80, true); + + // When + // Then + using (var testcontainer = testcontainersBuilder.Build()) + { + await testcontainer.StartAsync(); + Assert.NotEqual(0, testcontainer.GetMappedPublicPort(80)); + } + } + [Fact] public async Task VolumeAndCommand() { diff --git a/src/DotNet.Testcontainers/Core/Builder/TestcontainersBuilder.cs b/src/DotNet.Testcontainers/Core/Builder/TestcontainersBuilder.cs index 4c47d5acf..c1316a856 100644 --- a/src/DotNet.Testcontainers/Core/Builder/TestcontainersBuilder.cs +++ b/src/DotNet.Testcontainers/Core/Builder/TestcontainersBuilder.cs @@ -110,8 +110,7 @@ public ITestcontainersBuilder WithExposedPort(string port) public ITestcontainersBuilder WithPortBinding(int port, bool assignRandomHostPort = false) { - var hostPort = assignRandomHostPort ? TestcontainersNetworkService.GetAvailablePort() : port; - return this.WithPortBinding(hostPort, port); + return this.WithPortBinding($"{port}", assignRandomHostPort); } public ITestcontainersBuilder WithPortBinding(int hostPort, int containerPort) diff --git a/src/DotNet.Testcontainers/Core/Containers/IDockerContainer.cs b/src/DotNet.Testcontainers/Core/Containers/IDockerContainer.cs index 2cf8909e6..e7ccb47f7 100644 --- a/src/DotNet.Testcontainers/Core/Containers/IDockerContainer.cs +++ b/src/DotNet.Testcontainers/Core/Containers/IDockerContainer.cs @@ -21,6 +21,20 @@ public interface IDockerContainer : IDisposable /// Returns the Docker container mac address if present or an empty string instead. string MacAddress { get; } + /// + /// Gets the public host port associated with the private container port. + /// + /// Private container port. + /// Returns the public host port associated with the private container port. + int GetMappedPublicPort(int privatePort); + + /// + /// Gets the public host port associated with the private container port. + /// + /// Private container port. + /// Returns the public host port associated with the private container port. + int GetMappedPublicPort(string privatePort); + /// /// Starts the Testcontainer. If the image does not exist, it will be downloaded automatically. Non-existing containers are created at first start. /// diff --git a/src/DotNet.Testcontainers/Core/Containers/TestcontainersContainer.cs b/src/DotNet.Testcontainers/Core/Containers/TestcontainersContainer.cs index 0abc34de0..d2c54f32d 100644 --- a/src/DotNet.Testcontainers/Core/Containers/TestcontainersContainer.cs +++ b/src/DotNet.Testcontainers/Core/Containers/TestcontainersContainer.cs @@ -66,7 +66,7 @@ public string IPAddress } var ipAddress = this.container.NetworkSettings.Networks.FirstOrDefault(); - return ipAddress.Value == null ? string.Empty : ipAddress.Value.IPAddress; + return ipAddress.Value?.IPAddress ?? string.Empty; } } @@ -80,12 +80,28 @@ public string MacAddress } var macAddress = this.container.NetworkSettings.Networks.FirstOrDefault(); - return macAddress.Value == null ? string.Empty : macAddress.Value.IPAddress; + return macAddress.Value?.MacAddress ?? string.Empty; } } private TestcontainersConfiguration Configuration { get; } + public int GetMappedPublicPort(int privatePort) + { + return this.GetMappedPublicPort($"{privatePort}"); + } + + public int GetMappedPublicPort(string privatePort) + { + if (this.container == null) + { + throw new InvalidOperationException("Testcontainer is not running."); + } + + var mappedPort = this.container.Ports.FirstOrDefault(port => $"{port.PrivatePort}".Equals(privatePort)); + return mappedPort?.PublicPort ?? 0; + } + public async Task StartAsync() { await this.Create();