-module(testcontainer@wait). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/testcontainer/wait.gleam"). -export([none/0, log/1, log_times/2, port/1, http/2, http_with_status/3, health_check/0, command/1, all_of/1, any_of/1, with_timeout/2, with_poll_interval/2, base/1, timeout_ms/1, poll_interval_ms/1, describe/1]). -export_type([wait_strategy/0, wait_strategy_base/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -opaque wait_strategy() :: {wait_strategy, wait_strategy_base(), integer(), integer()}. -type wait_strategy_base() :: for_none | {for_log, binary(), integer()} | {for_port, integer()} | {for_http, integer(), binary(), integer()} | for_health_check | {for_command, list(binary()), integer()} | {all_of, list(wait_strategy())} | {any_of, list(wait_strategy())}. -file("src/testcontainer/wait.gleam", 32). -spec wrap(wait_strategy_base()) -> wait_strategy(). wrap(Base) -> {wait_strategy, Base, 60000, 1000}. -file("src/testcontainer/wait.gleam", 39). ?DOC( " \"No wait\" - succeeds immediately. This is the default when a\n" " `ContainerSpec` is built with `container.new/1` and no `wait_for/2`\n" " is set.\n" ). -spec none() -> wait_strategy(). none() -> wrap(for_none). -file("src/testcontainer/wait.gleam", 45). ?DOC( " Waits until the container's combined stdout/stderr stream contains the\n" " given message at least once.\n" ). -spec log(binary()) -> wait_strategy(). log(Message) -> wrap({for_log, Message, 1}). -file("src/testcontainer/wait.gleam", 50). ?DOC(" Like `log/1` but waits until the message appears at least `times` times.\n"). -spec log_times(binary(), integer()) -> wait_strategy(). log_times(Message, Times) -> wrap({for_log, Message, Times}). -file("src/testcontainer/wait.gleam", 55). ?DOC(" Waits until the given (TCP) container port accepts connections from the host.\n"). -spec port(integer()) -> wait_strategy(). port(Port) -> wrap({for_port, Port}). -file("src/testcontainer/wait.gleam", 61). ?DOC( " Waits until an HTTP GET to the given path on the given container port\n" " returns status 200.\n" ). -spec http(integer(), binary()) -> wait_strategy(). http(Port, Path) -> wrap({for_http, Port, Path, 200}). -file("src/testcontainer/wait.gleam", 66). ?DOC(" Like `http/2` but waits for a custom expected status code.\n"). -spec http_with_status(integer(), binary(), integer()) -> wait_strategy(). http_with_status(Port, Path, Status) -> wrap({for_http, Port, Path, Status}). -file("src/testcontainer/wait.gleam", 72). ?DOC( " Waits for Docker to report the container's HEALTHCHECK as `healthy`.\n" " The image must define a HEALTHCHECK for this to terminate.\n" ). -spec health_check() -> wait_strategy(). health_check() -> wrap(for_health_check). -file("src/testcontainer/wait.gleam", 77). ?DOC(" Runs a command inside the container and waits until it exits 0.\n"). -spec command(list(binary())) -> wait_strategy(). command(Cmd) -> wrap({for_command, Cmd, 0}). -file("src/testcontainer/wait.gleam", 82). ?DOC(" Composes strategies - succeeds when ALL inner strategies succeed.\n"). -spec all_of(list(wait_strategy())) -> wait_strategy(). all_of(Strategies) -> wrap({all_of, Strategies}). -file("src/testcontainer/wait.gleam", 87). ?DOC(" Composes strategies - succeeds as soon as ANY inner strategy succeeds.\n"). -spec any_of(list(wait_strategy())) -> wait_strategy(). any_of(Strategies) -> wrap({any_of, Strategies}). -file("src/testcontainer/wait.gleam", 93). ?DOC( " Sets the per-strategy timeout (default 60 s). Negative values are\n" " clamped to 0 (the strategy times out immediately).\n" ). -spec with_timeout(wait_strategy(), integer()) -> wait_strategy(). with_timeout(Strategy, Ms) -> Safe = case Ms < 0 of true -> 0; false -> Ms end, case Strategy of {wait_strategy, Base, _, Poll} -> {wait_strategy, Base, Safe, Poll} end. -file("src/testcontainer/wait.gleam", 105). ?DOC( " Sets the polling interval (default 1 s). Values <= 0 are clamped to 1\n" " to avoid a hot-spin loop.\n" ). -spec with_poll_interval(wait_strategy(), integer()) -> wait_strategy(). with_poll_interval(Strategy, Ms) -> Safe = case Ms < 1 of true -> 1; false -> Ms end, case Strategy of {wait_strategy, Base, Timeout, _} -> {wait_strategy, Base, Timeout, Safe} end. -file("src/testcontainer/wait.gleam", 118). ?DOC(false). -spec base(wait_strategy()) -> wait_strategy_base(). base(Strategy) -> case Strategy of {wait_strategy, B, _, _} -> B end. -file("src/testcontainer/wait.gleam", 125). ?DOC(" Returns the configured timeout in milliseconds.\n"). -spec timeout_ms(wait_strategy()) -> integer(). timeout_ms(Strategy) -> case Strategy of {wait_strategy, _, T, _} -> T end. -file("src/testcontainer/wait.gleam", 132). ?DOC(" Returns the configured poll interval in milliseconds.\n"). -spec poll_interval_ms(wait_strategy()) -> integer(). poll_interval_ms(Strategy) -> case Strategy of {wait_strategy, _, _, P} -> P end. -file("src/testcontainer/wait.gleam", 139). ?DOC(" Human-readable description used in `WaitTimedOut` / `WaitFailed` errors.\n"). -spec describe(wait_strategy()) -> binary(). describe(Strategy) -> case Strategy of {wait_strategy, Base, Timeout, Poll} -> Base_desc = case Base of for_none -> <<"none"/utf8>>; {for_log, Message, Times} -> <<<<<<<<"log("/utf8, Message/binary>>/binary, ", "/utf8>>/binary, (erlang:integer_to_binary(Times))/binary>>/binary, ")"/utf8>>; {for_port, Port} -> <<<<"port("/utf8, (erlang:integer_to_binary(Port))/binary>>/binary, ")"/utf8>>; {for_http, Port@1, Path, Status} -> <<<<<<<<<<<<"http("/utf8, (erlang:integer_to_binary(Port@1))/binary>>/binary, ", "/utf8>>/binary, Path/binary>>/binary, ", "/utf8>>/binary, (erlang:integer_to_binary(Status))/binary>>/binary, ")"/utf8>>; for_health_check -> <<"health_check"/utf8>>; {for_command, Cmd, Expected} -> <<<<<<<<"command("/utf8, (gleam@string:join(Cmd, <<" "/utf8>>))/binary>>/binary, ", "/utf8>>/binary, (erlang:integer_to_binary(Expected))/binary>>/binary, ")"/utf8>>; {all_of, Strats} -> <<<<"all_of("/utf8, (gleam@string:join( gleam@list:map(Strats, fun describe/1), <<", "/utf8>> ))/binary>>/binary, ")"/utf8>>; {any_of, Strats@1} -> <<<<"any_of("/utf8, (gleam@string:join( gleam@list:map(Strats@1, fun describe/1), <<", "/utf8>> ))/binary>>/binary, ")"/utf8>> end, <<<<<<<<<> end.