Skip to content

Commit

Permalink
send user agent to docker engine api + rename protocol method (#93)
Browse files Browse the repository at this point in the history
* send user agent to docker engine api

* fix constant

* rename method
  • Loading branch information
jarlah authored May 15, 2024
1 parent 81718ba commit 8ced2f3
Show file tree
Hide file tree
Showing 18 changed files with 89 additions and 56 deletions.
7 changes: 5 additions & 2 deletions lib/container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,12 @@ defmodule Testcontainers.Container do
config
end

@doc """
Do stuff after container has started.
"""
@impl true
@spec is_starting(%Testcontainers.Container{}, %Testcontainers.Container{}, %Tesla.Env{}) ::
@spec after_start(%Testcontainers.Container{}, %Testcontainers.Container{}, %Tesla.Env{}) ::
:ok
def is_starting(_config, _container, _conn), do: :ok
def after_start(_config, _container, _conn), do: :ok
end
end
4 changes: 2 additions & 2 deletions lib/container/cassandra_container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ defmodule Testcontainers.CassandraContainer do
end

@impl true
@spec is_starting(%CassandraContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def is_starting(_config, _container, _conn), do: :ok
@spec after_start(%CassandraContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def after_start(_config, _container, _conn), do: :ok
end
end
4 changes: 2 additions & 2 deletions lib/container/ceph_container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,8 @@ defmodule Testcontainers.CephContainer do
end

@impl true
@spec is_starting(%CephContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def is_starting(_config, _container, _conn), do: :ok
@spec after_start(%CephContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def after_start(_config, _container, _conn), do: :ok
end
end

Expand Down
4 changes: 2 additions & 2 deletions lib/container/emqx_container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ defmodule Testcontainers.EmqxContainer do
]

@impl true
# TODO Implement the `is_starting/3` function for the `ContainerBuilder` protocol.
def is_starting(_config, _container, _conn), do: :ok
# TODO Implement the `after_start/3` function for the `ContainerBuilder` protocol.
def after_start(_config, _container, _conn), do: :ok
end
end
8 changes: 4 additions & 4 deletions lib/container/kafka_container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,13 @@ defmodule Testcontainers.KafkaContainer do
end

@doc """
Checks if the container is starting.
If yes, that means that we know both the host and the port of the container and we can
Do stuff after container has started.
We now know both the host and the port of the container and we can
assign them to the config.
"""
@impl true
@spec is_starting(%KafkaContainer{}, %Testcontainers.Container{}, %Tesla.Env{}) :: :ok
def is_starting(config = %{start_file_path: start_file_path}, container, conn) do
@spec after_start(%KafkaContainer{}, %Testcontainers.Container{}, %Tesla.Env{}) :: :ok
def after_start(config = %{start_file_path: start_file_path}, container, conn) do
with script <- build_startup_script(container, config),
{:ok, _} <-
Docker.Api.put_file(container.container_id, conn, "/", start_file_path, script) do
Expand Down
4 changes: 2 additions & 2 deletions lib/container/minio_container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ defmodule Testcontainers.MinioContainer do
end

@impl true
@spec is_starting(%MinioContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def is_starting(_config, _container, _conn), do: :ok
@spec after_start(%MinioContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def after_start(_config, _container, _conn), do: :ok
end
end
4 changes: 2 additions & 2 deletions lib/container/mysql_container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,8 @@ defmodule Testcontainers.MySqlContainer do
end

@impl true
@spec is_starting(%MySqlContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def is_starting(_config, _container, _conn), do: :ok
@spec after_start(%MySqlContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def after_start(_config, _container, _conn), do: :ok
end

@doc false
Expand Down
4 changes: 2 additions & 2 deletions lib/container/postgres_container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ defmodule Testcontainers.PostgresContainer do
end

@impl true
@spec is_starting(%PostgresContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def is_starting(_config, _container, _conn), do: :ok
@spec after_start(%PostgresContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def after_start(_config, _container, _conn), do: :ok
end

@doc false
Expand Down
7 changes: 5 additions & 2 deletions lib/container/protocols/container_builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ defprotocol Testcontainers.ContainerBuilder do
@spec build(t()) :: %Testcontainers.Container{}
def build(builder)

@spec is_starting(t(), %Testcontainers.Container{}, %Tesla.Env{}) :: :ok
def is_starting(builder, container, connection)
@doc """
Do stuff after container has started.
"""
@spec after_start(t(), %Testcontainers.Container{}, %Tesla.Env{}) :: :ok
def after_start(builder, container, connection)
end
22 changes: 11 additions & 11 deletions lib/container/rabbitmq_container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ defmodule Testcontainers.RabbitMQContainer do
Overrides the default image use for the RabbitMQ container.
## Examples
iex> config = RabbitMQContainer.new() |> RabbitMQContainer.with_image("rabbitmq:xyz")
iex> config.image
"rabbitmq:xyz"
Expand All @@ -58,7 +58,7 @@ defmodule Testcontainers.RabbitMQContainer do
Overrides the default port used for the RabbitMQ container.
## Examples
iex> config = RabbitMQContainer.new() |> RabbitMQContainer.with_port(1111)
iex> config.port
1111
Expand All @@ -73,7 +73,7 @@ defmodule Testcontainers.RabbitMQContainer do
Note: this timeout will be used for each individual wait strategy.
## Examples
iex> config = RabbitMQContainer.new() |> RabbitMQContainer.with_wait_timeout(60000)
iex> config.wait_timeout
60000
Expand All @@ -86,7 +86,7 @@ defmodule Testcontainers.RabbitMQContainer do
Overrides the default user used for the RabbitMQ container.
## Examples
iex> config = RabbitMQContainer.new() |> RabbitMQContainer.with_username("rabbitmq")
iex> config.username
"rabbitmq"
Expand All @@ -99,7 +99,7 @@ defmodule Testcontainers.RabbitMQContainer do
Overrides the default password used for the RabbitMQ container.
## Examples
iex> config = RabbitMQContainer.new() |> RabbitMQContainer.with_password("rabbitmq")
iex> config.password
"rabbitmq"
Expand All @@ -112,7 +112,7 @@ defmodule Testcontainers.RabbitMQContainer do
Overrides the default virtual host used for the RabbitMQ container.
## Examples
iex> config = RabbitMQContainer.new() |> RabbitMQContainer.with_virtual_host("/")
iex> config.password
"/"
Expand All @@ -125,7 +125,7 @@ defmodule Testcontainers.RabbitMQContainer do
Overrides the default command used for the RabbitMQ container.
## Examples
iex> config = RabbitMQContainer.new() |> RabbitMQContainer.with_cmd(["sh", "-c", "rabbitmq-server"])
iex> config.cmd
["sh", "-c", "rabbitmq-server"]
Expand Down Expand Up @@ -172,9 +172,9 @@ defmodule Testcontainers.RabbitMQContainer do
## Examples
iex> RabbitMQContainer.connection_url(container)
"amqp://guest:guest@localhost:32768"
"amqp://guest:guest@localhost:32768"
iex> RabbitMQContainer.connection_url(container_with_vhost)
"amqp://guest:guest@localhost:32768/vhost"
"amqp://guest:guest@localhost:32768/vhost"
"""
def connection_url(%Container{} = container) do
"amqp://#{container.environment[:RABBITMQ_DEFAULT_USER]}:#{container.environment[:RABBITMQ_DEFAULT_PASS]}@#{Testcontainers.get_host()}:#{port(container)}#{virtual_host_segment(container)}"
Expand Down Expand Up @@ -264,7 +264,7 @@ defmodule Testcontainers.RabbitMQContainer do
end

@impl true
@spec is_starting(%RabbitMQContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def is_starting(_config, _container, _conn), do: :ok
@spec after_start(%RabbitMQContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def after_start(_config, _container, _conn), do: :ok
end
end
4 changes: 2 additions & 2 deletions lib/container/redis_container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ defmodule Testcontainers.RedisContainer do
end

@impl true
@spec is_starting(%RedisContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def is_starting(_config, _container, _conn), do: :ok
@spec after_start(%RedisContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def after_start(_config, _container, _conn), do: :ok
end
end

Expand Down
4 changes: 2 additions & 2 deletions lib/container/selenium_container.ex
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ defmodule Testcontainers.SeleniumContainer do
end

@impl true
@spec is_starting(%SeleniumContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def is_starting(_config, _container, _conn), do: :ok
@spec after_start(%SeleniumContainer{}, %Container{}, %Tesla.Env{}) :: :ok
def after_start(_config, _container, _conn), do: :ok
end
end

Expand Down
56 changes: 41 additions & 15 deletions lib/docker/api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ defmodule Testcontainers.Docker.Api do
Internal docker api. Only for direct use by `Testcontainers`
"""

alias DockerEngineAPI.Model.ContainerCreateRequest
alias DockerEngineAPI.Api
alias Testcontainers.Container
alias Testcontainers.Constants

def get_container(container_id, conn)
when is_binary(container_id) do
case Api.Container.container_inspect(conn, container_id) do
case Api.Container.container_inspect(conn, container_id,
"User-Agent": Constants.user_agent()
) do
{:error, %Tesla.Env{status: other}} ->
{:error, {:http_error, other}}

Expand All @@ -25,7 +27,11 @@ defmodule Testcontainers.Docker.Api do
def pull_image(image, conn, opts \\ []) when is_binary(image) do
auth = Keyword.get(opts, :auth, nil)

case Api.Image.image_create(conn, fromImage: image, "X-Registry-Auth": auth) do
case Api.Image.image_create(conn,
fromImage: image,
"X-Registry-Auth": auth,
"User-Agent": Constants.user_agent()
) do
{:ok, %Tesla.Env{status: 200}} ->
{:ok, nil}

Expand All @@ -38,7 +44,9 @@ defmodule Testcontainers.Docker.Api do
end

def create_container(%Container{} = container, conn) do
case Api.Container.container_create(conn, container_create_request(container)) do
case Api.Container.container_create(conn, container_create_request(container),
"User-Agent": Constants.user_agent()
) do
{:error, %Tesla.Env{status: other}} ->
{:error, {:http_error, other}}

Expand All @@ -51,7 +59,9 @@ defmodule Testcontainers.Docker.Api do
end

def start_container(id, conn) when is_binary(id) do
case Api.Container.container_start(conn, id) do
case Api.Container.container_start(conn, id,
"User-Agent": Constants.user_agent()
) do
{:ok, %Tesla.Env{status: 204}} ->
:ok

Expand All @@ -64,15 +74,23 @@ defmodule Testcontainers.Docker.Api do
end

def stop_container(container_id, conn) when is_binary(container_id) do
with {:ok, _} <- Api.Container.container_kill(conn, container_id),
{:ok, _} <- Api.Container.container_delete(conn, container_id) do
with {:ok, _} <-
Api.Container.container_kill(conn, container_id,
"User-Agent": Constants.user_agent()
),
{:ok, _} <-
Api.Container.container_delete(conn, container_id,
"User-Agent": Constants.user_agent()
) do
:ok
end
end

def put_file(container_id, connection, path, file_name, file_contents) do
with {:ok, tar_file_contents} <- create_tar_stream(file_name, file_contents) do
Api.Container.put_container_archive(connection, container_id, path, tar_file_contents)
Api.Container.put_container_archive(connection, container_id, path, tar_file_contents,
"User-Agent": Constants.user_agent()
)
end
end

Expand All @@ -95,7 +113,7 @@ defmodule Testcontainers.Docker.Api do
end

def inspect_exec(exec_id, conn) do
case DockerEngineAPI.Api.Exec.exec_inspect(conn, exec_id) do
case Api.Exec.exec_inspect(conn, exec_id, "User-Agent": Constants.user_agent()) do
{:ok, %DockerEngineAPI.Model.ExecInspectResponse{} = body} ->
{:ok, parse_inspect_result(body)}

Expand All @@ -118,11 +136,12 @@ defmodule Testcontainers.Docker.Api do
end

def stdout_logs(container_id, conn) do
case DockerEngineAPI.Api.Container.container_logs(
case Api.Container.container_logs(
conn,
container_id,
stdout: true,
stderr: true
stderr: true,
"User-Agent": Constants.user_agent()
) do
{:ok, %Tesla.Env{body: body}} ->
{:ok, body}
Expand All @@ -136,7 +155,9 @@ defmodule Testcontainers.Docker.Api do
end

def get_bridge_gateway(conn) do
case DockerEngineAPI.Api.Network.network_inspect(conn, "bridge") do
case Api.Network.network_inspect(conn, "bridge",
"User-Agent": Constants.user_agent()
) do
{:ok, %DockerEngineAPI.Model.Network{IPAM: %DockerEngineAPI.Model.Ipam{Config: config}}} ->
with_gateway =
config
Expand All @@ -159,7 +180,7 @@ defmodule Testcontainers.Docker.Api do
end

defp container_create_request(%Container{} = container_config) do
%ContainerCreateRequest{
%DockerEngineAPI.Model.ContainerCreateRequest{
Image: container_config.image,
Cmd: container_config.cmd,
ExposedPorts: map_exposed_ports(container_config),
Expand Down Expand Up @@ -250,7 +271,9 @@ defmodule Testcontainers.Docker.Api do
defp create_exec(container_id, command, conn) do
data = %{"Cmd" => command}

case DockerEngineAPI.Api.Exec.container_exec(conn, container_id, data) do
case Api.Exec.container_exec(conn, container_id, data,
"User-Agent": Constants.user_agent()
) do
{:ok, %DockerEngineAPI.Model.IdResponse{Id: id}} ->
{:ok, id}

Expand All @@ -266,7 +289,10 @@ defmodule Testcontainers.Docker.Api do
end

defp start_exec(exec_id, conn) do
case DockerEngineAPI.Api.Exec.exec_start(conn, exec_id, body: %{}) do
case Api.Exec.exec_start(conn, exec_id,
body: %{},
"User-Agent": Constants.user_agent()
) do
{:ok, %Tesla.Env{status: 200}} ->
:ok

Expand Down
2 changes: 1 addition & 1 deletion lib/testcontainers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ defmodule Testcontainers do
{:ok, id} <- Api.create_container(config, state.conn),
:ok <- Api.start_container(id, state.conn),
{:ok, container} <- Api.get_container(id, state.conn),
:ok <- ContainerBuilder.is_starting(config_builder, container, state.conn),
:ok <- ContainerBuilder.after_start(config_builder, container, state.conn),
:ok <- wait_for_container(container, config.wait_strategies || [], state.conn) do
{:ok, container}
end
Expand Down
3 changes: 2 additions & 1 deletion lib/util/constants.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ defmodule Testcontainers.Constants do
@moduledoc false

def library_name, do: :testcontainers
def library_version, do: "1.7.1"
def library_version, do: "1.8.0"
def container_label, do: "org.testcontainers"
def container_lang_label, do: "org.testcontainers.lang"
def container_lang_value, do: Elixir |> Atom.to_string() |> String.downcase()
def container_sessionId_label, do: "org.testcontainers.sessionId"
def container_version_label, do: "org.testcontainers.version"
def user_agent, do: "tc-elixir/" <> __MODULE__.library_version()
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule TestcontainersElixir.MixProject do
use Mix.Project

@app :testcontainers
@version "1.7.1"
@version "1.8.0"
@source_url "https://github.com/testcontainers/testcontainers-elixir"

def project do
Expand Down
Loading

0 comments on commit 8ced2f3

Please sign in to comment.