Skip to content

Commit

Permalink
importing containers from excontainers
Browse files Browse the repository at this point in the history
  • Loading branch information
jarlah committed Oct 14, 2023
1 parent 48cdb61 commit 822241f
Show file tree
Hide file tree
Showing 15 changed files with 392 additions and 176 deletions.
40 changes: 26 additions & 14 deletions lib/api.ex
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# SPDX-License-Identifier: MIT
defmodule TestcontainersElixir.Docker.Api do
alias TestcontainersElixir.WaitStrategy
alias DockerEngineAPI.Model.ContainerCreateRequest
alias DockerEngineAPI.Model.ContainerCreateResponse
alias DockerEngineAPI.Api
alias TestcontainersElixir.Container
alias TestcontainersElixir.Reaper
alias TestcontainersElixir.Container
alias TestcontainersElixir.Connection

def run(%Container{} = container_config, options \\ []) do
conn = Connection.get_connection()
def run(%Container{} = container_config, options \\ [], conn \\ Connection.get_connection()) do
on_exit = Keyword.get(options, :on_exit, nil)
wait_fn = container_config.waiting_strategy
wait_strategy = container_config.waiting_strategy
create_request = container_create_request(container_config)

with {:ok, _} <- Api.Image.image_create(conn, fromImage: create_request."Image"),
Expand All @@ -25,17 +25,35 @@ defmodule TestcontainersElixir.Docker.Api do
else
:ok
end),
{:ok, container} <- get_container(conn, container_id),
{:ok, _} <- if(wait_fn != nil, do: wait_fn.(container), else: {:ok, nil}) do
{:ok, container} <- get_container(container_id, conn),
:ok <-
if(wait_strategy != nil,
do:
WaitStrategy.wait_until_container_is_ready(wait_strategy, container.container_id),
else: :ok
) do
{:ok, container}
end
end

def stdout_logs(container_id) do
conn = Connection.get_connection()
def stdout_logs(container_id, conn \\ Connection.get_connection()) do
Api.Container.container_logs(conn, container_id, stdout: true)
end

def execute_cmd(container_id, cmd, conn \\ Connection.get_connection()) when is_list(cmd) do
with {:ok, %DockerEngineAPI.Model.IdResponse{Id: container_id}} <-
Api.Exec.container_exec(conn, container_id, %DockerEngineAPI.Model.ExecConfig{Cmd: cmd}) do
{:ok, container_id}
end
end

def get_container(container_id, conn \\ Connection.get_connection())
when is_binary(container_id) do
with {:ok, response} <- Api.Container.container_inspect(conn, container_id) do
{:ok, from(response)}
end
end

defp container_create_request(%Container{} = container_config) do
%ContainerCreateRequest{
Image: container_config.image,
Expand Down Expand Up @@ -92,12 +110,6 @@ defmodule TestcontainersElixir.Docker.Api do
end
end

defp get_container(conn, container_id) when is_binary(container_id) do
with {:ok, response} <- Api.Container.container_inspect(conn, container_id) do
{:ok, from(response)}
end
end

defp reap_container(container_id) when is_binary(container_id) do
case Reaper.start_link() do
{:error, {:already_started, _}} -> :ok
Expand Down
19 changes: 8 additions & 11 deletions lib/ceph_container.ex → lib/container/ceph_container.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# SPDX-License-Identifier: MIT
defmodule TestcontainersElixir.CephContainer do
defmodule TestcontainersElixir.Container.CephContainer do
alias TestcontainersElixir.WaitStrategy.LogWaitStrategy
alias TestcontainersElixir.Container
alias TestcontainersElixir.LogChecker

@waiting_strategy LogWaitStrategy.new(
~r/.*Bucket 's3:\/\/.*\/' created.*/,
300_000
)

def new(options \\ []) do
image = Keyword.get(options, :image, "quay.io/ceph/demo:latest-quincy")
Expand All @@ -20,15 +25,7 @@ defmodule TestcontainersElixir.CephContainer do
MON_IP: "127.0.0.1",
RGW_NAME: "localhost"
},
waiting_strategy: &waiting_strategy/1
waiting_strategy: @waiting_strategy
)
end

defp waiting_strategy(container),
do:
LogChecker.wait_for_log(
container.container_id,
~r/.*Bucket 's3:\/\/.*\/' created.*/,
300_000
)
end
67 changes: 67 additions & 0 deletions lib/container/mysql_container.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# SPDX-License-Identifier: MIT
# Original by: Marco Dallagiacoma @ 2023 in https://github.com/dallagi/excontainers
# Modified by: Jarl André Hübenthal @ 2023
defmodule TestcontainersElixir.Container.MySqlContainer do
@moduledoc """
Functions to build and interact with MySql containers.
"""

alias TestcontainersElixir.Container
alias TestcontainersElixir.WaitStrategy.CommandWaitStrategy

@mysql_port 3306

@doc """
Builds a MySql container.
Uses MySql 8.0 by default, but a custom image can also be set.
## Options
- `username` sets the username for the user
- `password` sets the password for the user
- `database` sets the name of the database
"""
def new(image \\ "mysql:8.0", opts \\ []) do
username = Keyword.get(opts, :username, "test")
password = Keyword.get(opts, :password, "test")

Container.new(
image,
exposed_ports: [@mysql_port],
environment: %{
MYSQL_USER: username,
MYSQL_PASSWORD: password,
MYSQL_DATABASE: Keyword.get(opts, :database, "test"),
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
},
wait_strategy: wait_strategy(username, password)
)
end

@doc """
Returns the port on the _host machine_ where the MySql container is listening.
"""
def port(container), do: Container.mapped_port(container, @mysql_port)

@doc """
Returns the connection parameters to connect to the database from the _host machine_.
"""
def connection_parameters(%Container{} = container) do
[
hostname: "localhost",
port: port(container),
username: container.environment[:MYSQL_USER],
password: container.environment[:MYSQL_PASSWORD],
database: container.environment[:MYSQL_DATABASE]
]
end

defp wait_strategy(username, password) do
CommandWaitStrategy.new([
"sh",
"-c",
"mysqladmin ping --user='#{username}' --password='#{password}' -h localhost | grep 'mysqld is alive'"
])
end
end
65 changes: 65 additions & 0 deletions lib/container/postgres_container.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# SPDX-License-Identifier: MIT
# Original by: Marco Dallagiacoma @ 2023 in https://github.com/dallagi/excontainers
# Modified by: Jarl André Hübenthal @ 2023
defmodule TestcontainersElixir.Container.PostgresContainer do
@moduledoc """
Functions to build and interact with PostgreSql containers.
"""

alias TestcontainersElixir.Container
alias TestcontainersElixir.WaitStrategy.CommandWaitStrategy

@postgres_port 5432
@wait_strategy CommandWaitStrategy.new([
"pg_isready",
"-U",
"test",
"-d",
"test",
"-h",
"localhost"
])

@doc """
Builds a PostgreSql container.
Uses PostgreSql 13.1 by default, but a custom image can also be set.
## Options
- `username` sets the username for the user
- `password` sets the password for the user
- `database` sets the name of the database
"""
def new(image \\ "postgres:13.1", opts \\ []) do
Container.new(
image,
exposed_ports: [@postgres_port],
environment: %{
POSTGRES_USER: Keyword.get(opts, :username, "test"),
POSTGRES_PASSWORD: Keyword.get(opts, :password, "test"),
POSTGRES_DB: Keyword.get(opts, :database, "test")
},
wait_strategy: @wait_strategy
)
end

@doc """
Returns the port on the _host machine_ where the MySql container is listening.
"""
def port(%Container{} = container),
do: with({:ok, port} <- Container.mapped_port(container, @postgres_port), do: port)

@doc """
Returns the connection parameters to connect to the database from the _host machine_.
"""
def connection_parameters(%Container{} = container) do
[
hostname: "localhost",
port: port(container),
username: container.environment[:POSTGRES_USER],
password: container.environment[:POSTGRES_PASSWORD],
database: container.environment[:POSTGRES_DB]
]
end
end
38 changes: 38 additions & 0 deletions lib/container/redis_container.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# SPDX-License-Identifier: MIT
# Original by: Marco Dallagiacoma @ 2023 in https://github.com/dallagi/excontainers
# Modified by: Jarl André Hübenthal @ 2023
defmodule TestcontainersElixir.Container.RedisContainer do
@moduledoc """
Functions to build and interact with Redis containers.
"""

alias TestcontainersElixir.Container
alias TestcontainersElixir.WaitStrategy.CommandWaitStrategy

@redis_port 6379
@wait_strategy CommandWaitStrategy.new(["redis-cli", "PING"])

@doc """
Creates a Redis container.
Runs Redis 6.0 by default, but a custom image can also be set.
"""
def new(image \\ "redis:6.0-alpine", _opts \\ []) do
Container.new(
image,
exposed_ports: [@redis_port],
environment: %{},
wait_strategy: @wait_strategy
)
end

@doc """
Returns the port on the _host machine_ where the Redis container is listening.
"""
def port(%Container{} = container), do: Container.mapped_port(container, @redis_port)

@doc """
Returns the connection url to connect to Redis from the _host machine_.
"""
def connection_url(%Container{} = container), do: "redis://localhost:#{port(container)}/"
end
63 changes: 0 additions & 63 deletions lib/http_checker.ex

This file was deleted.

Loading

0 comments on commit 822241f

Please sign in to comment.