From 56c9fadbf0324bed6d3d9dd9ae3d939cfab74cca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarl=20Andr=C3=A9=20H=C3=BCbenthal?= Date: Thu, 12 Oct 2023 20:22:52 +0200 Subject: [PATCH] add simple macro and test it --- lib/ex_unit.ex | 52 +++++++++++++++++++++++++++++ lib/reaper.ex | 19 ++++++----- lib/testcontainers_elixir.ex | 33 ------------------ test/simple_test.exs | 9 +++++ test/testcontainers_elixir_test.exs | 10 ------ 5 files changed, 72 insertions(+), 51 deletions(-) create mode 100644 lib/ex_unit.ex delete mode 100644 lib/testcontainers_elixir.ex create mode 100644 test/simple_test.exs delete mode 100644 test/testcontainers_elixir_test.exs diff --git a/lib/ex_unit.ex b/lib/ex_unit.ex new file mode 100644 index 0000000..327ebf2 --- /dev/null +++ b/lib/ex_unit.ex @@ -0,0 +1,52 @@ +defmodule TestcontainersElixir.ExUnit do + + alias TestcontainersElixir.Reaper + alias DockerEngineAPI.Connection + alias DockerEngineAPI.Api + alias DockerEngineAPI.Model + + defmacro container(options \\ []) do + quote do + docker_url = "http+unix://%2Fvar%2Frun%2Fdocker.sock/v1.43" + conn = Connection.new(base_url: docker_url) + + image = Keyword.get(unquote(options), :image, nil) + {:ok, _} = + conn + |> Api.Image.image_create(fromImage: image) + + port = Keyword.get(unquote(options), :port, nil) + + {:ok, %Model.ContainerCreateResponse{Id: container_id}} = + conn + |> Api.Container.container_create( + %Model.ContainerCreateRequest{ + Image: image, + ExposedPorts: %{"#{port}" => %{}}, + HostConfig: %{ + PortBindings: %{"#{port}" => [%{"HostPort" => ""}]} + } + } + ) + + {:ok, _} = + conn + |> Api.Container.container_start(container_id) + + :ok = + case GenServer.whereis(Reaper) do + nil -> + {:ok, _} = conn |> Reaper.start_link() + Reaper.register({"id", container_id}) + + _ -> + Reaper.register({"id", container_id}) + + end + + :ok = Reaper.register({"id", container_id}) + + {:ok, container_id} + end + end +end diff --git a/lib/reaper.ex b/lib/reaper.ex index e3548df..72d7524 100644 --- a/lib/reaper.ex +++ b/lib/reaper.ex @@ -2,6 +2,9 @@ defmodule TestcontainersElixir.Reaper do use GenServer + alias DockerEngineAPI.Api + alias DockerEngineAPI.Model + @ryuk_image "testcontainers/ryuk:0.5.1" @ryuk_port 8080 @@ -25,12 +28,12 @@ defmodule TestcontainersElixir.Reaper do def init(connection) do {:ok, _} = connection - |> DockerEngineAPI.Api.Image.image_create(fromImage: @ryuk_image) + |> Api.Image.image_create(fromImage: @ryuk_image) - {:ok, %DockerEngineAPI.Model.ContainerCreateResponse{Id: container_id} = container} = + {:ok, %Model.ContainerCreateResponse{Id: container_id} = container} = connection - |> DockerEngineAPI.Api.Container.container_create( - %DockerEngineAPI.Model.ContainerCreateRequest{ + |> Api.Container.container_create( + %Model.ContainerCreateRequest{ Image: @ryuk_image, ExposedPorts: %{"#{@ryuk_port}" => %{}}, HostConfig: %{ @@ -45,7 +48,7 @@ defmodule TestcontainersElixir.Reaper do {:ok, _} = connection - |> DockerEngineAPI.Api.Container.container_start(container_id) + |> Api.Container.container_start(container_id) {:ok, socket} = connection @@ -77,14 +80,14 @@ defmodule TestcontainersElixir.Reaper do defp create_ryuk_socket( connection, - %DockerEngineAPI.Model.ContainerCreateResponse{Id: container_id} + %Model.ContainerCreateResponse{Id: container_id} ) do port_str = "#{@ryuk_port}/tcp" {:ok, - %DockerEngineAPI.Model.ContainerInspectResponse{ + %Model.ContainerInspectResponse{ NetworkSettings: %{Ports: %{^port_str => [%{"HostPort" => host_port} | _tail]}} - }} = connection |> DockerEngineAPI.Api.Container.container_inspect(container_id) + }} = connection |> Api.Container.container_inspect(container_id) :gen_tcp.connect(~c"localhost", String.to_integer(host_port), [ :binary, diff --git a/lib/testcontainers_elixir.ex b/lib/testcontainers_elixir.ex deleted file mode 100644 index e5dd2c1..0000000 --- a/lib/testcontainers_elixir.ex +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -defmodule TestcontainersElixir do - @moduledoc """ - Documentation for `TestcontainersElixir`. - """ - - alias TestcontainersElixir.Reaper - alias DockerEngineAPI.Connection - alias DockerEngineAPI.Api - - def hello do - docker_url = "http+unix://%2Fvar%2Frun%2Fdocker.sock/v1.43" - - conn = Connection.new(base_url: docker_url) - - # TODO create a container, gets its container id and pass it to the next line - - :ok = conn |> register_container("some_container_id") - - conn |> Api.Image.image_list() - end - - defp register_container(conn, container_id) when is_binary(container_id) do - case Reaper.ping() do - :ok -> - Reaper.register({"id", container_id}) - - :error -> - {:ok, _} = conn |> Reaper.start_link() - Reaper.register({"id", container_id}) - end - end -end diff --git a/test/simple_test.exs b/test/simple_test.exs new file mode 100644 index 0000000..b761daf --- /dev/null +++ b/test/simple_test.exs @@ -0,0 +1,9 @@ +defmodule SimpleTest do + use ExUnit.Case + import TestcontainersElixir.ExUnit + + test "creates and reapes container" do + {:ok, container_id} = container(image: "nginx:latest", port: 80) + assert is_binary(container_id) + end +end diff --git a/test/testcontainers_elixir_test.exs b/test/testcontainers_elixir_test.exs deleted file mode 100644 index 4cb611f..0000000 --- a/test/testcontainers_elixir_test.exs +++ /dev/null @@ -1,10 +0,0 @@ -defmodule TestcontainersElixirTest do - use ExUnit.Case - doctest TestcontainersElixir - - test "greets the world" do - {:ok, list} = TestcontainersElixir.hello() - assert is_list(list) - assert is_number(length(list)) - end -end