{#- Test helper template for Elixir server-pattern HTTP fixtures
Spawns app_harness subprocess and exposes SUT_URL in environment
#}
# Start a named Finch pool before ExUnit configured to use HTTP/1 only.
# Tests pass `finch: AlefE2EFinch` on every Req call; the pool's protocol
# selection (via `pools.default.protocols: [:http1]`) is the canonical place
# to pin the wire protocol since Req rejects per-call `:connect_options` when
# `:finch` is set.
{:ok, _} = Finch.start_link(name: AlefE2EFinch, pools: %{:default => [protocols: [:http1]]})
ExUnit.start()
# Spawn app_harness subprocess and set SUT_URL
# If SUT_URL is already set, a parent process started a shared harness.
# Use it as-is and do NOT spawn our own.
unless System.get_env("SUT_URL") do
app_harness_bin = Path.expand("../app_harness.exs", __DIR__)
# Build elixir args with code paths so the harness can access compiled library modules
build_dir = Path.expand("../_build/dev/lib", __DIR__)
code_paths = if File.dir?(build_dir) do
lib_dirs = File.ls!(build_dir) |> Enum.map(&Path.join(build_dir, &1))
lib_dirs
|> Enum.flat_map(fn lib_path ->
ebin_path = Path.join(lib_path, "ebin")
if File.dir?(ebin_path), do: ["-pa", ebin_path], else: []
end)
else
[]
end
port = Port.open({:spawn_executable, System.find_executable("elixir")}, [
:binary,
{:line, 65_536},
args: code_paths ++ [app_harness_bin]
])
url = "http://{{ host }}:{{ port }}"
# Poll until the harness accepts TCP connections
deadline = :erlang.monotonic_time(:millisecond) + 15_000
{ready, url} =
Enum.reduce_while(1..150, {false, url}, fn _, {_, url_acc} ->
now = :erlang.monotonic_time(:millisecond)
if now > deadline do
{:halt, {false, url_acc}}
else
case :gen_tcp.connect(String.to_charlist("{{ host }}"), {{ port }}, [], 500) do
{:ok, socket} ->
:gen_tcp.close(socket)
{:halt, {true, url_acc}}
{:error, _} ->
Process.sleep(100)
{:cont, {false, url_acc}}
end
end
end)
unless ready do
Port.close(port)
raise "App harness did not become reachable on {{ host }}:{{ port }} within 15s"
end
System.put_env("SUT_URL", url)
end