diff --git a/lib/container.ex b/lib/container.ex index 38a329ff..002ec165 100644 --- a/lib/container.ex +++ b/lib/container.ex @@ -90,18 +90,30 @@ defmodule Testcontainers.Container do Adds a _port_ to be exposed on the _container_. """ def with_exposed_port(%__MODULE__{} = config, port) when is_integer(port) do - filtered_ports = config.exposed_ports |> Enum.reject(fn p -> p == port end) + filtered_ports = + config.exposed_ports + |> Enum.reject(fn + {p, _} -> p == port + p -> p == port + end) - %__MODULE__{config | exposed_ports: [port | filtered_ports]} + %__MODULE__{config | exposed_ports: [{port, nil} | filtered_ports]} end @doc """ Adds multiple _ports_ to be exposed on the _container_. """ def with_exposed_ports(%__MODULE__{} = config, ports) when is_list(ports) do - filtered_ports = config.exposed_ports |> Enum.reject(fn port -> port in ports end) + filtered_ports = + config.exposed_ports + |> Enum.reject(fn + {p, _} -> p in ports + p -> p in ports + end) + + new_ports = Enum.map(ports, fn port -> {port, nil} end) - %__MODULE__{config | exposed_ports: ports ++ filtered_ports} + %__MODULE__{config | exposed_ports: new_ports ++ filtered_ports} end @doc """ @@ -242,13 +254,10 @@ defmodule Testcontainers.Container do """ def mapped_port(%__MODULE__{} = container, port) when is_number(port) do container.exposed_ports - |> Enum.filter(fn - {exposed_port, _} -> exposed_port == port - port -> port == port + |> Enum.find_value(nil, fn + {^port, host_port} -> host_port + _ -> nil end) - |> List.first({}) - |> Tuple.to_list() - |> List.last() end @doc """ diff --git a/lib/docker/api.ex b/lib/docker/api.ex index da22e1ea..ed4ee76f 100644 --- a/lib/docker/api.ex +++ b/lib/docker/api.ex @@ -224,7 +224,6 @@ defmodule Testcontainers.Docker.Api do container_config.exposed_ports |> Enum.map(fn {container_port, _host_port} -> {container_port, %{}} - port -> {port, %{}} end) |> Enum.into(%{}) end @@ -237,11 +236,11 @@ defmodule Testcontainers.Docker.Api do defp map_port_bindings(%Container{} = container_config) do container_config.exposed_ports |> Enum.map(fn + {container_port, host_port} when is_nil(host_port) -> + {container_port, [%{"HostIp" => "0.0.0.0", "HostPort" => ""}]} + {container_port, host_port} -> {container_port, [%{"HostIp" => "0.0.0.0", "HostPort" => to_string(host_port)}]} - - port -> - {port, [%{"HostIp" => "0.0.0.0", "HostPort" => ""}]} end) |> Enum.into(%{}) end diff --git a/test/container_test.exs b/test/container_test.exs index 9240fad4..b08c8289 100644 --- a/test/container_test.exs +++ b/test/container_test.exs @@ -21,10 +21,10 @@ defmodule Testcontainers.ContainerTest do container2 = ContainerBuilder.build(Testcontainers.PostgresContainer.new()) assert Testcontainers.Util.Hash.struct_to_hash(container1) == - "2ac8f31c61b760b17176a9b9e51bd9d969eb26adadc9bf3db4cdcac69cfb065f" + "082851e217cae88e1684169a9759a6d702d012016054c14b23d192f7e2559c63" assert Testcontainers.Util.Hash.struct_to_hash(container2) == - "2ac8f31c61b760b17176a9b9e51bd9d969eb26adadc9bf3db4cdcac69cfb065f" + "082851e217cae88e1684169a9759a6d702d012016054c14b23d192f7e2559c63" end end @@ -34,7 +34,7 @@ defmodule Testcontainers.ContainerTest do Container.new("my-image") |> Container.with_exposed_port(80) - assert container.exposed_ports == [80] + assert container.exposed_ports == [{80, nil}] end test "removes duplicate exposed ports" do @@ -43,7 +43,7 @@ defmodule Testcontainers.ContainerTest do |> Container.with_exposed_port(80) |> Container.with_exposed_port(80) - assert container.exposed_ports == [80] + assert container.exposed_ports == [{80, nil}] end end @@ -53,7 +53,7 @@ defmodule Testcontainers.ContainerTest do Container.new("my-image") |> Container.with_exposed_ports([80, 443]) - assert container.exposed_ports == [80, 443] + assert container.exposed_ports == [{80, nil}, {443, nil}] end test "removes duplicate exposed ports" do @@ -62,7 +62,7 @@ defmodule Testcontainers.ContainerTest do |> Container.with_exposed_ports([80, 443]) |> Container.with_exposed_ports([80]) - assert container.exposed_ports == [80, 443] + assert container.exposed_ports == [{80, nil}, {443, nil}] end end @@ -96,6 +96,11 @@ defmodule Testcontainers.ContainerTest do container = Container.new("my-image") assert Container.mapped_port(container, 80) == nil end + + test "returns nil (and does not crash) if the exposed port is present but not mapped (integer)" do + container = Container.new("my-image") |> Container.with_exposed_port(80) + assert Container.mapped_port(container, 80) == nil + end end describe "with_network_mode/2" do