Packages
testcontainers
1.2.2
2.3.1
2.3.0
2.2.0
2.1.0
2.1.0-rc1
2.0.0
2.0.0-rc3
2.0.0-rc2
2.0.0-rc
1.14.1
1.14.0
1.13.5
1.13.4
1.13.3
1.13.2
1.13.1
1.13.0
1.12.0
1.11.8
1.11.7
1.11.6
1.11.5
1.11.4
1.11.3
1.11.2
1.11.1
1.11.0
1.10.5
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
1.9.0
1.8.4
1.8.3
1.8.2
1.8.1
1.8.0
1.7.0
1.6.0
1.5.1
1.5.0
1.4.2
1.4.1
1.4.0
1.3.1
1.3.0
1.2.11
1.2.10
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.3
1.1.2
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-beta.1
1.0.0-beta
0.9.3
0.9.2
0.9.1
0.9.0
Testcontainers is an Elixir library that supports ExUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
Current section
Files
Jump to
Current section
Files
lib/wait_strategy/log_wait_strategy.ex
# SPDX-License-Identifier: MIT
defmodule Testcontainers.WaitStrategy.LogWaitStrategy do
@moduledoc """
Considers the container as ready as soon as a specific log message is detected in the container's log stream.
"""
@retry_delay 500
defstruct [:log_regex, :timeout, retry_delay: @retry_delay]
@doc """
Creates a new LogWaitStrategy to wait until a specific log message, matching the provided regex, appears in the container's log.
"""
def new(log_regex, timeout \\ 5000, retry_delay \\ @retry_delay),
do: %__MODULE__{log_regex: log_regex, timeout: timeout, retry_delay: retry_delay}
defimpl Testcontainers.WaitStrategy do
alias Testcontainers.Connection
alias Testcontainers.WaitStrategy.LogWaitStrategy
alias Testcontainers.Utils
def wait_until_container_is_ready(%LogWaitStrategy{} = wait_strategy, id_or_name) do
case wait_for_log(
wait_strategy,
id_or_name,
current_time_millis()
) do
{:ok, :log_is_ready} ->
:ok
{:error, reason} ->
{:error, reason, wait_strategy}
end
end
defp wait_for_log(%LogWaitStrategy{} = wait_strategy, container_id, start_time)
when is_binary(container_id) and is_integer(wait_strategy.timeout) and
is_integer(start_time) do
if wait_strategy.timeout + start_time < current_time_millis() do
{:error, strategy_timed_out(wait_strategy.timeout, start_time)}
else
if log_comparison(container_id, wait_strategy.log_regex) do
{:ok, :log_is_ready}
else
delay = max(0, wait_strategy.retry_delay)
Utils.log(
"Logs in container #{container_id} didnt match regex #{inspect(wait_strategy.log_regex)}, retrying in #{delay}ms."
)
:timer.sleep(delay)
wait_for_log(wait_strategy, container_id, start_time)
end
end
end
defp log_comparison(container_id, log_regex) do
case Connection.stdout_logs(container_id) do
{:ok, stdout_log} when is_binary(stdout_log) ->
Regex.match?(log_regex, stdout_log)
_ ->
false
end
end
defp current_time_millis, do: System.monotonic_time(:millisecond)
defp strategy_timed_out(timeout, started_at)
when is_number(timeout) and is_number(started_at),
do:
{:log_wait_strategy, :timeout, timeout,
elapsed_time: current_time_millis() - started_at}
end
end