diff --git a/README.md b/README.md index 5fa9057..c354cc3 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,15 @@ Asynchronous dependency health checks library. ## Features * User defined dependencies checks with flexible settings. -* Dependencies checks functions are executed asynchronously as isolated processes. +* Dependencies checks functions are executed asynchronously. * Built-in `Plug` module providing customizable response for a http health-check endpoint. -* Checks states are stored in an ETS table, which means practically unlimited requests per second - processing capacity. +* Support for multiple independent `Existence` instances and associated health-checks + endpoints (example use case: separate Kubernetes readiness and liveness http probes). +* Checks states are stored and accessed using a dedicated ETS tables per `Existence` instance, + which means practically unlimited requests per second processing capacity. ## Installation -Add library to application dependencies: +Add `Existence` library to your application dependencies: ```elixir def deps do [ @@ -20,13 +22,19 @@ end ``` ## Usage -Start library child in your application supervisor: +Define dependencies checks functions MFA's and start `Existence` child with your application +supervisor ```elixir defmodule MyApp.Application do use Application def start(_type, _args) do - children = [Existence] + health_checks = [ + check_1: %{mfa: {MyApp.Checks, :check_1, []}}, + check_2: %{mfa: {MyApp.Checks, :check_2, []}} + ] + + children = [{Existence, checks: health_checks}] opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) @@ -34,18 +42,6 @@ defmodule MyApp.Application do end ``` -Configure dependencies checks in your application configuration file, for example: -```elixir -#config/config.exs -config :my_app, Existence, - check_1: %{ - mfa: {MyApp.Checks, :check_1, []} - }, - check_2: %{ - mfa: {MyApp.Checks, :check_2, []} - } -``` - Declare your dependencies checks functions: ```elixir defmodule MyApp.Checks do @@ -54,6 +50,16 @@ defmodule MyApp.Checks do end ``` +Configure your Phoenix router to respond to the `/healthcheck` endpoint requests using for example +`Plug.Router.forward/2`: +```elixir +defmodule MyAppWeb.Router do + use MyAppWeb, :router + + forward("/healthcheck", Existence.Plug) +end +``` + Get current overall health-check state: ```elixir iex> Existence.get_state() @@ -66,16 +72,6 @@ iex> Existence.get_checks() [check_1: :ok, check_2: :ok] ``` -Configure your Phoenix router to respond to the `/healthcheck` endpoint requests using for example -`Plug.Router.forward/2`: -```elixir -defmodule MyAppWeb.Router do - use MyAppWeb, :router - - forward("/healthcheck", Existence.Plug) -end -``` - ## TODO -- [ ] add `telemetry` event emitted on a health-check state change. +- [ ] add `telemetry` event emitted on an overall health-check state change. diff --git a/lib/existence.ex b/lib/existence.ex index ca7f9b6..def4206 100644 --- a/lib/existence.ex +++ b/lib/existence.ex @@ -7,72 +7,110 @@ defmodule Existence do Module is also used to start an `Existence` process as a part of an application supervision tree. `Existence` works by asynchronously spawning user defined dependencies checks functions. - Dependencies checks functions results are evaluated to establish overall health-check state. + Individual dependencies checks functions results are evaluated to establish an overall + health-check state. Overall health-check state is healthy only when all user defined dependencies checks are healthy. It is assumed that healthy state is represented by an `:ok` atom for both dependencies checks and - for an overall health-check. - Any other result in dependencies checks is associated with an unhealthy state. Unhealthy overall - health-check state is represented by the `:error` atom. + for the overall health-check. + Any other result in dependencies checks is associated with an unhealthy dependency check state. + Overall health-check unhealthy state is represented by an `:error` atom. - User provided dependencies checks functions are spawned as an isolated processes. - If dependency check function raises, throws an error, timeouts or fails in any other way it + User defined dependencies checks functions are spawned as monitored isolated processes. + If user dependency check function raises, throws an error, timeouts or fails in any way it doesn't have a negative impact on other processes, including user application. - Current checks results are stored in an ETS table. When user executes any of available getters, - `get_state/0` or `get_checks/0`, request is made against ETS table which has `:read_concurrency` - set to `true`. In practice it means that library can handle huge numbers of requests per second - without blocking process managing health-checks execution and evaluation. - You can start `Existence` using `start/2` in your application supervisor: + Current dependencies checks functions results and current overall health-check state are stored + in an ETS table. + Whenever user executes any of available state getters, `get_state/1` or `get_checks/1`, + request is made against ETS table which has `:read_concurrency` set to `true`. + In practice it means that library can handle huge numbers of requests per second + without blocking any other processes. + + Module provides two functions to access checks states: + * `get_state/1` to get overall health-check state, + * `get_checks/1` to get dependencies checks states. + + ## Usage + After defining dependencies checks parameters, `Existence` can be started using + your application supervisor: ```elixir #lib/my_app/application.ex def start(_type, _args) do + health_checks = [ + # minimal dependency check configuration: + check_1: %{ + mfa: {MyApp.Checks, :check_1, []} + }, + # complete dependency check configuration: + check_2: %{ + mfa: {MyApp.Checks, :check_2, []}, + initial_delay: 1_000, + interval: 30_000, + state: :ok, + timeout: 1_000 + } + ] + children = [ - {Existence, state: :ok} + {Existence, checks: health_checks, state: :ok} ] opts = [strategy: :one_for_one, name: MyApp.Supervisor] Supervisor.start_link(children, opts) end ``` - When `Existence` is started it has assigned by default initial state `:error`, - which means an unhealthy state. User can change initial health-check state using `:state` key. - Initial overall health-check is set to healthy in a code example above by setting: `state: :ok`. + When `Existence` is started it has assigned an initial overall health-check state, which + by default is equal to an `:error` atom, meaning an unhealthy state. + Initial overall health-check state can be changed with a `:state` key. In a code example above + initial overall health-check state is set to a healthy state with: `state: :ok`. - User defined dependencies checks are configured in the Elixir config, usually - `config/config.exs` file: + `Existence` supports starting multiple instances by using common Elixir child identifiers: + `:id` and `:name`, for example: ```elixir - #config/config.exs - config :my_app, Existence, - # minimal dependency check configuration: - check_1: %{ - mfa: {MyApp.Checks, :check_1, []} - }, - # complete dependency check configuration: - check_2: %{ - mfa: {MyApp.Checks, :check_2, []}, - initial_delay: 1_000, - interval: 30_000, - state: :ok, - timeout: 1_000 - } - + children = [ + {Existence, id: ExistenceReadiness, name: ReadinessCheck}, + {Existence, name: {:local, LivenessCheck}} + ] ``` - Dependencies checks are identified by their atom id's with configuration settings defined - as a map. + + ## Configuration + `Existence` startup options: + * `:id` - any term used to identify the child specification internally. Please refer to the + `Supervisor` "Child specification" documentation section for details on child `:id` key. + Default: `Existence`. + * `:name` - name used to start `Existence` `:gen_statem` process locally. If defined + as an `atom()` `:gen_statem.start_link/3` is used to start `Existence` process + without registration. + If defined as a `{:local, atom()}` tuple, `:gen_statem.start_link/4` is invoked and process is + registered locally with a given name. + Key value is used to select `Existence` instance when running `get_state/1` or `get_checks/1`. + Default: `Existence`. + * `:checks` - keyword list with user defined dependencies checks parameters, see description + below for details. Default: `[]`. + * `:state` - initial overall `Existence` instance health-check state. Default: `:error`. + + Dependencies checks are defined using a keyword list with configuration parameters defined + as a maps. Dependencies checks configuration options: - * `:mfa` - `{module, function, arguments}` tuple specifying user defined function to run when - spawning given check. Please refer to `Kernel.apply/3` for `mfa` pattern explanation. Required. + * `:mfa` - `{module, function, arguments}` tuple specifying user defined function to spawn when + executing given dependency check. Please refer to `Kernel.apply/3` documentation for + the MFA pattern explanation. Required. * `:initial_delay` - amount of time in milliseconds to wait before spawning a dependency check for the first time. Can be used to wait for a dependency process to properly initialize before - executing check function first time when application is started. Default: `100 msec`. + executing dependency check function first time when application is started. Default: `100`. * `:interval` - time interval in milliseconds specifying how frequently given check should be - executed. Default: `30_000 msec`. + executed. Default: `30_000`. * `:state` - initial dependency check state when starting `Existence`. Default: `:error`. * `:timeout` - after spawning dependency check function library will wait `:timeout` amount of - milliseconds for the check function result. If check function will do not complete within a given - timeout, check function process will be killed, and check state will be assigned `:killed` atom - value. Default: `5_000 msec`. + milliseconds for the dependency check function to complete. + If dependency check function will do not complete within a given timeout, dependency check + function process will be killed, and dependency check state will assume a `:killed` atom value. + Default: `5_000`. + + ## Dependencies checks + User defined dependencies checks functions must return an `:ok` atom for the healthy state. + Any other values returned by dependencies checks functions are considered as an unhealthy state. Example checks for two popular dependencies, PostgreSQL and Redis: ```elixir @@ -93,50 +131,276 @@ defmodule Existence do end end ``` - Please notice that checks commands in the code examples above are not wrapped in a - `try/1` blocks like in other similar libraries. - Checks functions are spawned as monitored processes. Whenever they will raise, parent - health-check process will be notified and will align checks statuses accordingly. - Using `try/1` is unnecessary. + Please notice that dependencies checks functions in the code example above are not wrapped in a + `try/1` blocks. + Dependencies checks functions are spawned as monitored processes. + Whenever check function will raise, parent health-check process will be notified with an `:info` + `:DOWN` message and dependency check status will be assigned a tuple containing an exception and + a stack trace, for example: + ```elixir + # def check_1(), do: raise("CustomError") + iex> Existence.get_checks() + [ + check_1: {%RuntimeError{message: "CustomError"}, [ # ... stack trace ]} + ] + iex> Existence.get_state() + :error + ``` + """ + @behaviour :gen_statem - Module provides two functions to access checks states: - * `get_state/0` to get overall health-check, - * `get_checks/0` to get dependencies checks states. - """ + @enforce_keys [:mfa] + defstruct [ + :mfa, + initial_delay: 100, + interval: 30_000, + state: :error, + timeout: 5_000, + spawn_proc: {nil, nil} + ] - alias Existence.GenCheck + # TODO decide if ets_exists?/1 should be executed on each get_* call + # def ets_exists?(table \\ @ets_table_name), do: :ets.whereis(table) != :undefined @doc """ Get dependencies checks states. - Returns a keyword list with checks functions results for the user configured dependencies checks. + Function gets current dependencies checks states for an `Existence` instance started with + a given `name`. + If `name` is not provided, checks states for instance with default `:name` (`Existence`) + are returned. + + Dependencies checks functions results are returned as a keyword list. + If no checks were defined function will return an empty list. - Returns an empty list if no checks were defined. + Dependency check function result equal to an `:ok` atom means healthy state, any other term is + associated with an unhealthy state. - Example: + Function will raise with an `ArgumentError` exception if `Existence` instance `name` + doesn't exist. + + ##### Example: ```elixir iex> Existence.get_checks() [check_1: :ok, check_2: :ok] ``` + + ``` + iex> Existence.get_checks(NotExisting) + ** (ArgumentError) errors were found at the given arguments: + ``` + """ - @spec get_checks() :: [] | [key: :ok | any()] - defdelegate get_checks(), to: GenCheck + @spec get_checks(name :: atom()) :: [] | [key: :ok | any()] + def get_checks(name \\ __MODULE__) do + name + |> ets_table_name() + |> :ets.select([{{{:check_state, :"$1"}, :"$2"}, [], [{{:"$1", :"$2"}}]}]) + end @doc """ Get an overall health-check state. - Returns `:ok` when overall health-check state is healthy, `:error` otherwise. + Function gets current overall health-check state for an `Existence` instance started with + a given `name`. + If `name` is not provided, overall health-check state for an instance with default `:name` + (`Existence`) is returned. + + Function returns an `:ok` atom when overall health-check state is healthy and an `:error` atom + otherwise. + Overall health-check state is healthy only when all dependencies health checks are healthy. + + Function will raise with an `ArgumentError` exception if `Existence` instance `name` + doesn't exist. - Example: + ##### Example: ```elixir iex> Existence.get_state() :ok ``` + + ```elixir + iex> Existence.get_state(NotExisting) + ** (ArgumentError) errors were found at the given arguments: + ``` """ - @spec get_state() :: :ok | :error - defdelegate get_state(), to: GenCheck + @spec get_state(name :: atom()) :: :ok | :error + def get_state(name \\ __MODULE__) do + [{:state, state}] = + name + |> ets_table_name() + |> :ets.lookup(:state) + + state + end + + @doc false + def child_spec(init_arg) do + {id, init_arg} = Keyword.pop(init_arg, :id, __MODULE__) + Supervisor.child_spec(%{id: id, start: {__MODULE__, :start_link, [init_arg]}}, []) + end + + @doc false + def start_link(init_arg) do + case Keyword.pop(init_arg, :name, __MODULE__) do + {name, init_arg} when is_atom(name) -> + init_arg = Keyword.put(init_arg, :ets_name, ets_table_name(name)) + :gen_statem.start_link(__MODULE__, init_arg, []) + + {{:local, name}, init_arg} when is_atom(name) -> + init_arg = Keyword.put(init_arg, :ets_name, ets_table_name(name)) + :gen_statem.start_link({:local, name}, __MODULE__, init_arg, []) + end + end + + @impl true + def init(args) do + Process.flag(:trap_exit, true) + ets_tab = Keyword.fetch!(args, :ets_name) + + :ets.new(ets_tab, [ + :set, + :named_table, + :public, + read_concurrency: true, + write_concurrency: false + ]) + + checks = + args + |> Keyword.get(:checks, []) + |> Enum.map(fn {check_id, params} -> {check_id, struct!(__MODULE__, params)} end) + + Enum.each(checks, fn {check_id, params} -> + set_check_state(%{ets_tab: ets_tab}, check_id, Map.fetch!(params, :state)) + Process.send_after(self(), {:spawn_check, check_id}, Map.fetch!(params, :initial_delay)) + end) + + data = %{checks: checks, ets_tab: ets_tab} + + case Keyword.get(args, :state, :error) do + :ok -> {:ok, :healthy, data} + _ -> {:ok, :unhealthy, data} + end + end + + @impl true + def callback_mode(), do: [:state_functions, :state_enter] + + @impl true + def terminate(_reason, _state, data), do: set_state(data, :terminate) + + # ________unhealthy + @doc false + def unhealthy(:enter, state, data) when state in [:healthy, :unhealthy] do + set_state(data, :unhealthy) + :keep_state_and_data + end + + def unhealthy(:info, {:check_result, result, check_id}, data) do + set_check_state(data, check_id, result) + + if is_ets_healthy?(data), + do: {:next_state, :healthy, data}, + else: {:keep_state, data} + end + + def unhealthy(:info, {:DOWN, ref, :process, pid, :normal}, data) do + find_check(pid, ref, data) + |> maybe_respawn_check() + :keep_state_and_data + end + + def unhealthy(:info, {:DOWN, ref, :process, pid, error}, data) do + {check_id, _check_params} = check = find_check(pid, ref, data) + maybe_respawn_check(check) + set_check_state(data, check_id, error) + + :keep_state_and_data + end + + def unhealthy(:info, {:spawn_check, check_id}, data), + do: {:keep_state, spawn_check(check_id, data)} + + # ________healthy @doc false - defdelegate child_spec(init_arg), to: GenCheck + def healthy(:enter, state, data) when state in [:healthy, :unhealthy] do + set_state(data, :healthy) + :keep_state_and_data + end + + def healthy(:info, {:check_result, result, check_id}, data) do + set_check_state(data, check_id, result) + + case result do + :ok -> {:keep_state, data} + _err -> {:next_state, :unhealthy, data} + end + end + + def healthy(:info, {:DOWN, ref, :process, pid, :normal}, data) do + find_check(pid, ref, data) + |> maybe_respawn_check() + + :keep_state_and_data + end + + def healthy(:info, {:DOWN, ref, :process, pid, error}, data) do + {check_id, _check_params} = check = find_check(pid, ref, data) + maybe_respawn_check(check) + set_check_state(data, check_id, error) + + {:next_state, :unhealthy, data} + end + + def healthy(:info, {:spawn_check, check_id}, data), + do: {:keep_state, spawn_check(check_id, data)} + + # ________helpers + defp ets_table_name(name), do: Module.concat(name, Table) + + defp find_check(pid, ref, %{checks: checks}), + do: Enum.find(checks, nil, fn {_check_id, params} -> {pid, ref} == params.spawn_proc end) + + defp maybe_respawn_check({check_id, check_params}), + do: Process.send_after(self(), {:spawn_check, check_id}, check_params.interval) + + defp maybe_respawn_check(_invalid_check), do: :ok + + defp spawn_check(check_id, %{checks: checks} = data) do + %{mfa: {m, f, a}, timeout: timeout} = params = Keyword.fetch!(checks, check_id) + from = self() + + {pid, ref} = + spawn_monitor(fn -> + :timer.kill_after(timeout, self()) + result = apply(m, f, a) + send(from, {:check_result, result, check_id}) + end) + + params = Map.put(params, :spawn_proc, {pid, ref}) + checks = Keyword.put(checks, check_id, params) + Map.put(data, :checks, checks) + end + + defp set_state(%{ets_tab: ets_tab}, state) do + case state do + :healthy -> :ets.insert(ets_tab, {:state, :ok}) + _ -> :ets.insert(ets_tab, {:state, :error}) + end + end + + defp set_check_state(%{ets_tab: ets_tab}, check_id, result), + do: :ets.insert(ets_tab, {{:check_state, check_id}, result}) + + defp is_ets_healthy?(%{ets_tab: ets_tab}) do + case :ets.select(ets_tab, [ + {{{:check_state, :"$1"}, :"$2"}, [{:"/=", :"$2", :ok}], [:"$2"]} + ]) do + [] -> true + _ -> false + end + end end diff --git a/lib/gen_check.ex b/lib/gen_check.ex deleted file mode 100644 index 50debf7..0000000 --- a/lib/gen_check.ex +++ /dev/null @@ -1,175 +0,0 @@ -defmodule Existence.GenCheck do - @moduledoc false - @behaviour :gen_statem - - @enforce_keys [:mfa] - defstruct [ - :mfa, - initial_delay: 100, - interval: 30_000, - state: :error, - timeout: 5_000, - spawn_proc: {nil, nil} - ] - - @ets_table_name Module.concat(__MODULE__, Table) - - # TODO decide if ets_exists?/1 should be executed on each get_* call - # def ets_exists?(table \\ @ets_table_name), do: :ets.whereis(table) != :undefined - - def get_state() do - [{:state, state}] = :ets.lookup(@ets_table_name, :state) - state - end - - def get_checks(), - do: :ets.select(@ets_table_name, [{{{:check_state, :"$1"}, :"$2"}, [], [{{:"$1", :"$2"}}]}]) - - def child_spec(init_arg), - do: Supervisor.child_spec(%{id: __MODULE__, start: {__MODULE__, :start_link, [init_arg]}}, []) - - def start_link(init_arg), do: :gen_statem.start_link(__MODULE__, init_arg, []) |> IO.inspect() - - @impl true - def init(args) do - Process.flag(:trap_exit, true) - - :ets.new(@ets_table_name, [ - :set, - :named_table, - :public, - read_concurrency: true, - write_concurrency: false - ]) - - data = - Mix.Project.config() - |> Keyword.fetch!(:app) - |> Application.get_env(Existence, []) - |> Enum.map(fn {check_id, params} -> {check_id, struct!(__MODULE__, params)} end) - - Enum.each(data, fn {check_id, params} -> - set_check_state(check_id, Map.fetch!(params, :state)) - Process.send_after(self(), {:spawn_check, check_id}, Map.fetch!(params, :initial_delay)) - end) - - case Keyword.get(args, :state, :error) do - :ok -> {:ok, :healthy, data} - _ -> {:ok, :unhealthy, data} - end - end - - @impl true - def callback_mode(), do: [:state_functions, :state_enter] - - @impl true - def terminate(_reason, _state, _data), do: set_state(:terminate) - - # ________unhealthy - def unhealthy(:enter, state, _data) when state in [:healthy, :unhealthy] do - set_state(:unhealthy) - :keep_state_and_data - end - - def unhealthy(:info, {:check_result, result, check_id}, data) do - set_check_state(check_id, result) - - if is_ets_healthy?(), - do: {:next_state, :healthy, data}, - else: {:keep_state, data} - end - - def unhealthy(:info, {:DOWN, ref, :process, pid, :normal}, data) do - find_check(pid, ref, data) - |> maybe_respawn_check() - - :keep_state_and_data - end - - def unhealthy(:info, {:DOWN, ref, :process, pid, error}, data) do - {check_id, _check_params} = check = find_check(pid, ref, data) - maybe_respawn_check(check) - set_check_state(check_id, error) - - :keep_state_and_data - end - - def unhealthy(:info, {:spawn_check, check_id}, data), - do: {:keep_state, spawn_check(check_id, data)} - - # ________healthy - def healthy(:enter, state, _data) when state in [:healthy, :unhealthy] do - set_state(:healthy) - :keep_state_and_data - end - - def healthy(:info, {:check_result, result, check_id}, data) do - set_check_state(check_id, result) - - case result do - :ok -> {:keep_state, data} - _err -> {:next_state, :unhealthy, data} - end - end - - def healthy(:info, {:DOWN, ref, :process, pid, :normal}, data) do - find_check(pid, ref, data) - |> maybe_respawn_check() - - :keep_state_and_data - end - - def healthy(:info, {:DOWN, ref, :process, pid, error}, data) do - {check_id, _check_params} = check = find_check(pid, ref, data) - maybe_respawn_check(check) - set_check_state(check_id, error) - - {:next_state, :unhealthy, data} - end - - def healthy(:info, {:spawn_check, check_id}, data), - do: {:keep_state, spawn_check(check_id, data)} - - # ________helpers - defp find_check(pid, ref, data), - do: Enum.find(data, nil, fn {_check_id, params} -> {pid, ref} == params.spawn_proc end) - - defp maybe_respawn_check({check_id, check_params}), - do: Process.send_after(self(), {:spawn_check, check_id}, check_params.interval) - - defp maybe_respawn_check(_invalid_check), do: :ok - - defp spawn_check(check_id, data) do - %{mfa: {m, f, a}, timeout: timeout} = params = Keyword.fetch!(data, check_id) - from = self() - - {pid, ref} = - spawn_monitor(fn -> - :timer.kill_after(timeout, self()) - result = apply(m, f, a) - send(from, {:check_result, result, check_id}) - end) - - params = Map.put(params, :spawn_proc, {pid, ref}) - Keyword.put(data, check_id, params) - end - - defp set_state(state) do - case state do - :healthy -> :ets.insert(@ets_table_name, {:state, :ok}) - _ -> :ets.insert(@ets_table_name, {:state, :error}) - end - end - - defp set_check_state(check_id, result), - do: :ets.insert(@ets_table_name, {{:check_state, check_id}, result}) - - defp is_ets_healthy?() do - case :ets.select(@ets_table_name, [ - {{{:check_state, :"$1"}, :"$2"}, [{:"/=", :"$2", :ok}], [:"$2"]} - ]) do - [] -> true - _ -> false - end - end -end diff --git a/lib/plug.ex b/lib/plug.ex index e6fba3c..2635844 100644 --- a/lib/plug.ex +++ b/lib/plug.ex @@ -1,18 +1,25 @@ defmodule Existence.Plug do @moduledoc """ - Plug sending information about a health-check state as a response. + Plug responding with a health-check state. + Plug sends a `text/plain` response depending on the `Existence` overall health-check state + returned by an `Existence.get_state/1` function. - Plug sends a plain text response dependent on the overall health-check state. + ## Configuration + Plug is configured with a keyword list. - Response http status code and body are configurable with the following keys: + Plug response http status code and body are configurable with the following keys: * `ok_status` - response status code for the healthy state. Default: `200`. * `ok_body` - response body for the healthy state. Default: `"OK"`. * `error_status` - response status code for the unhealthy state. Default: `503`. * `error_body` - response body for the unhealthy state. Default: `"Service Unavailable"`. + Additionally `Existence` instance can be selected with a `:name` key. + If `:name` key is not set, Plug will use a default instance: `name: Existence`. + Setting instance name is described in the `Existence` module documentation. - Example module use with `Plug.Router.get/3` inside `/` route scope with custom unhealthy + ## Usage + Example module use with a `Plug.Router.get/3` inside `/` route scope with a custom unhealthy state response: ```elixir defmodule MyAppWeb.Router do @@ -32,9 +39,9 @@ defmodule Existence.Plug do end ``` - Notice `alias: false` use to disable scoping on an external `Existence.Plug`. + Notice `alias: false` use to disable scoping on an external `Existence.Plug` in `get/3` function. - Above code example will produce following http responses: + Code example above will produce following http responses: * healthy state: ``` $> curl -i http://127.0.0.1:4000/healthcheck @@ -52,8 +59,8 @@ defmodule Existence.Plug do """ @behaviour Plug - import Plug.Conn - alias Existence.GenCheck + + import Plug.Conn, only: [put_resp_content_type: 2, send_resp: 3, halt: 1] @ok_status 200 @ok_body "OK" @@ -65,8 +72,14 @@ defmodule Existence.Plug do @doc false def call(conn, opts \\ []) do + health_check_state = + case Keyword.fetch(opts, :name) do + {:ok, name} -> Existence.get_state(name) + :error -> Existence.get_state() + end + {status, body} = - case GenCheck.get_state() do + case health_check_state do :ok -> {Keyword.get(opts, :ok_status, @ok_status), Keyword.get(opts, :ok_body, @ok_body)} diff --git a/test/existence_dynamic_test.exs b/test/existence_dynamic_test.exs new file mode 100644 index 0000000..69dd447 --- /dev/null +++ b/test/existence_dynamic_test.exs @@ -0,0 +1,51 @@ +defmodule Existence.DynamicTest do + use ExUnit.Case + + import ExistenceTest.Common + + def check_1(), do: :persistent_term.get(:check_1, :ok) + def check_2(), do: :persistent_term.get(:check_2, :ok) + + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + interval: 10 + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + interval: 10 + } + ] + ] + |> start() + end + + test "returns valid overall state and valid checks states on dynamic checks changes" do + assert :ok == Existence.get_state() + assert [check_1: :ok, check_2: :ok] == Existence.get_checks() |> Enum.sort() + + :persistent_term.put(:check_1, :error) + Process.sleep(20) + assert :error == Existence.get_state() + assert [check_1: :error, check_2: :ok] == Existence.get_checks() |> Enum.sort() + + :persistent_term.put(:check_2, :error) + Process.sleep(20) + assert :error == Existence.get_state() + assert [check_1: :error, check_2: :error] == Existence.get_checks() |> Enum.sort() + + :persistent_term.put(:check_1, :ok) + Process.sleep(20) + assert :error == Existence.get_state() + assert [check_1: :ok, check_2: :error] == Existence.get_checks() |> Enum.sort() + + :persistent_term.put(:check_2, :ok) + Process.sleep(20) + assert :ok == Existence.get_state() + assert [check_1: :ok, check_2: :ok] == Existence.get_checks() |> Enum.sort() + end +end diff --git a/test/existence_error_error_test.exs b/test/existence_error_error_test.exs new file mode 100644 index 0000000..1640548 --- /dev/null +++ b/test/existence_error_error_test.exs @@ -0,0 +1,1112 @@ +defmodule Existence.ErrorErrorTest do + use ExUnit.Case + + import ExistenceTest.Common + + def check_1(), do: :error + def check_2(), do: :error + @state :error + + describe "checks: defaults, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0 + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/default, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:ok, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:custom_error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/default, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:ok, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:custom_error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/default, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:ok, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:custom_error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: defaults, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0 + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/default, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:ok, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/default, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:ok, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/default, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:ok, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: defaults, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0 + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/default, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/default, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/default, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end +end diff --git a/test/existence_error_test.exs b/test/existence_error_test.exs new file mode 100644 index 0000000..6adeb5e --- /dev/null +++ b/test/existence_error_test.exs @@ -0,0 +1,217 @@ +defmodule Existence.ErrorTest do + use ExUnit.Case + + import ExistenceTest.Common + + def check(), do: :error + + describe "check: defaults, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :error] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :error] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :error] == Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :error] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :error] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :error] == Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :error] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :error] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :error] == Existence.get_checks() + end + end +end diff --git a/test/existence_kill_test.exs b/test/existence_kill_test.exs new file mode 100644 index 0000000..b1a00a6 --- /dev/null +++ b/test/existence_kill_test.exs @@ -0,0 +1,217 @@ +defmodule Existence.KillTest do + use ExUnit.Case + + import ExistenceTest.Common + + def check(), do: Process.exit(self(), :kill) + + describe "check: defaults, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end +end diff --git a/test/existence_ok_error_test.exs b/test/existence_ok_error_test.exs new file mode 100644 index 0000000..c75f3bd --- /dev/null +++ b/test/existence_ok_error_test.exs @@ -0,0 +1,1112 @@ +defmodule Existence.OkErrorTest do + use ExUnit.Case + + import ExistenceTest.Common + + def check_1(), do: :ok + def check_2(), do: :error + @state :error + + describe "checks: defaults, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0 + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/default, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:ok, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:custom_error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/default, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:ok, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:custom_error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/default, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:ok, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:custom_error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: defaults, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0 + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/default, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:ok, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/default, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:ok, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/default, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:ok, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: defaults, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0 + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/default, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/default, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/default, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end +end diff --git a/test/existence_ok_ok_test.exs b/test/existence_ok_ok_test.exs new file mode 100644 index 0000000..b57166c --- /dev/null +++ b/test/existence_ok_ok_test.exs @@ -0,0 +1,1112 @@ +defmodule Existence.OkOkTest do + use ExUnit.Case + + import ExistenceTest.Common + + def check_1(), do: :ok + def check_2(), do: :ok + @state :ok + + describe "checks: defaults, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0 + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/default, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:ok, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:custom_error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/default, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:ok, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:custom_error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/default, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:ok, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:custom_error, fsm_state: default" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: defaults, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0 + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/default, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:ok, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/default, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:ok, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/default, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:ok, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: defaults, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0 + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/default, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :ok/:custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :ok + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/default, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :error/:custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/default, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end + + describe "checks: :custom_error/:custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check_1: %{ + mfa: {__MODULE__, :check_1, []}, + initial_delay: 0, + state: :custom_error + }, + check_2: %{ + mfa: {__MODULE__, :check_2, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert @state == Existence.get_state() + end + + test "get_checks/0" do + assert [check_1: check_1(), check_2: check_2()] == Existence.get_checks() |> Enum.sort() + end + end +end diff --git a/test/existence_ok_test.exs b/test/existence_ok_test.exs new file mode 100644 index 0000000..1190bfb --- /dev/null +++ b/test/existence_ok_test.exs @@ -0,0 +1,217 @@ +defmodule Existence.OkTest do + use ExUnit.Case + + import ExistenceTest.Common + + def check(), do: :ok + + describe "check: defaults, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :ok == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :ok] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :ok == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :ok] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :ok == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :ok] == Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :ok == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :ok] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :ok == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :ok] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :ok == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :ok] == Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :ok == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :ok] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :ok == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :ok] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :ok == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :ok] == Existence.get_checks() + end + end +end diff --git a/test/plug_test.exs b/test/existence_plug_test.exs similarity index 96% rename from test/plug_test.exs rename to test/existence_plug_test.exs index be75582..2c64d5f 100644 --- a/test/plug_test.exs +++ b/test/existence_plug_test.exs @@ -37,7 +37,6 @@ defmodule Existence.PlugTest do describe "initial FSM state: :error" do setup do - Application.put_env(:existence, Existence, []) start_supervised!(Existence) :ok end @@ -73,7 +72,6 @@ defmodule Existence.PlugTest do describe "initial FSM state: :ok" do setup do - Application.put_env(:existence, Existence, []) start_supervised!({Existence, state: :ok}) :ok end diff --git a/test/existence_raise_test.exs b/test/existence_raise_test.exs new file mode 100644 index 0000000..b60231c --- /dev/null +++ b/test/existence_raise_test.exs @@ -0,0 +1,226 @@ +defmodule Existence.RaiseTest do + use ExUnit.Case + + import ExistenceTest.Common + + def check(), do: raise("check_raise") + + describe "check: defaults, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = + Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = + Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = + Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = + Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = + Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = + Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = + Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = + Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = + Existence.get_checks() + end + end +end diff --git a/test/existence_test.exs b/test/existence_test.exs index dacdd40..2522d19 100644 --- a/test/existence_test.exs +++ b/test/existence_test.exs @@ -1,1081 +1,330 @@ defmodule ExistenceTest do - use ExUnit.Case, async: true + use ExUnit.Case - def check_ok(), do: :ok - def check_error(), do: :error - def check_timeout(), do: Process.sleep(999_999_999) - def check_raise(), do: raise("check_raise") - def check_throw(), do: throw(:check_raise) - def check_kill(), do: Process.exit(self(), :kill) + import ExistenceTest.Common - # _____no checks - describe "no checks, fsm init state: :error" do - setup do - start_app([]) - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [] == Existence.get_checks() - end - end - - describe "no checks, fsm init state: :ok" do - setup do - start_app([], :ok) - end - - test "get_state/0" do - assert :ok == Existence.get_state() - end - - test "get_checks/0" do - assert [] == Existence.get_checks() - end - end - - # _____:ok check - describe "single :ok check, check init state :error, fsm init state: :error" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_ok, []}, - state: :error, - initial_delay: 0 - } - ] - |> start_app() - end + @ets_error "errors were found at the given arguments:\n\n * 1st argument: the table identifier does not refer to an existing ETS table\n" - test "get_state/0" do - assert :ok == Existence.get_state() + describe("child_spec/1") do + test "defaults are correct" do + assert %{id: Existence, start: {Existence, :start_link, [[]]}} == + Existence.child_spec([]) end - test "get_checks/0" do - assert [check: :ok] == Existence.get_checks() + test "custom :id" do + assert %{ + id: CustomID, + start: {Existence, :start_link, [[]]} + } == Existence.child_spec(id: CustomID) end - end - describe "single :ok check, check init state :error, fsm init state: :ok" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_ok, []}, - state: :error, - initial_delay: 0 - } - ] - |> start_app(:ok) + test "custom name: CustomName" do + assert %{ + id: Existence, + start: {Existence, :start_link, [[name: CustomName]]} + } == Existence.child_spec(name: CustomName) end - test "get_state/0" do - assert :ok == Existence.get_state() + test "custom name: {:local, CustomName}" do + assert %{ + id: Existence, + start: {Existence, :start_link, [[name: {:local, CustomName}]]} + } == Existence.child_spec(name: {:local, CustomName}) end - test "get_checks/0" do - assert [check: :ok] == Existence.get_checks() + test "custom :state" do + assert %{ + id: Existence, + start: {Existence, :start_link, [[{:state, :custom}]]} + } == + Existence.child_spec(state: :custom) end - end - describe "single :ok check, check init state :ok, fsm init state: :error" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_ok, []}, - state: :ok, - initial_delay: 0 - } - ] - |> start_app() - end - - test "get_state/0" do - assert :ok == Existence.get_state() - end - - test "get_checks/0" do - assert [check: :ok] == Existence.get_checks() - end - end - - describe "single :ok check, check init state :ok, fsm init state: :ok" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_ok, []}, - state: :ok, - initial_delay: 0 - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :ok == Existence.get_state() - end - - test "get_checks/0" do - assert [check: :ok] == Existence.get_checks() - end - end - - # _____:error check - describe "single :error check, check init state :error, fsm init state: :error" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_error, []}, - state: :error, - initial_delay: 0 - } - ] - |> start_app() - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check: :error] == Existence.get_checks() - end - end - - describe "single :error check, check init state :error, fsm init state: :ok" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_error, []}, - state: :error, - initial_delay: 0 - } - ] - |> start_app(:ok) + test "custom :id, name: CustomName and :state" do + assert %{ + id: CustomID, + start: {Existence, :start_link, [[{:name, CustomName}, {:state, :custom}]]} + } == + Existence.child_spec(id: CustomID, name: CustomName, state: :custom) end - test "get_state/0" do - assert :error == Existence.get_state() + test "custom :id, name: {:local, CustomName} and :state" do + assert %{ + id: CustomID, + start: + {Existence, :start_link, [[{:name, {:local, CustomName}}, {:state, :custom}]]} + } == + Existence.child_spec(id: CustomID, name: {:local, CustomName}, state: :custom) end - test "get_checks/0" do - assert [check: :error] == Existence.get_checks() + test "check is defined" do + assert %{ + id: Existence, + start: + {Existence, :start_link, + [ + [ + {:checks, [check_1: %{mfa: {HealthCheck.Checks, :check_1, []}}]} + ] + ]} + } == + Existence.child_spec( + checks: [ + check_1: %{ + mfa: {HealthCheck.Checks, :check_1, []} + } + ] + ) end end - describe "single :error check, check init state :ok, fsm init state: :error" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_error, []}, - state: :ok, - initial_delay: 0 - } - ] - |> start_app() + describe "Existence is not started" do + test "get_state/1" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state() end end - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check: :error] == Existence.get_checks() + test "get_checks/1" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_checks() end end end - describe "single :error check, check init state :ok, fsm init state: :ok" do + describe "all defaults" do setup do - [ - check: %{ - mfa: {__MODULE__, :check_error, []}, - state: :ok, - initial_delay: 0 - } - ] - |> start_app(:ok) + start([]) end - test "get_state/0" do + test "get_state/1, default name" do assert :error == Existence.get_state() end - test "get_checks/0" do - assert [check: :error] == Existence.get_checks() + test "get_checks/1, default name" do + assert [] == Existence.get_checks() end - end - # _____timeout check - describe "single timeout check, check init state :error, fsm init state: :error" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_timeout, []}, - initial_delay: 0, - state: :error, - timeout: 10 - } - ] - |> start_app(:error, 20) - end - - test "get_state/0" do - assert :error == Existence.get_state() + test "get_state/1, valid name" do + assert :error == Existence.get_state(Existence) end - test "get_checks/0" do - assert [check: :killed] == Existence.get_checks() + test "get_checks/1, valid name" do + assert [] == Existence.get_checks(Existence) end - end - describe "single timeout check, check init state :error, fsm init state: :ok" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_timeout, []}, - initial_delay: 0, - state: :error, - timeout: 10 - } - ] - |> start_app(:ok, 20) - end - - test "get_state/0" do - assert :error == Existence.get_state() + test "get_state/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end - test "get_checks/0" do - assert [check: :killed] == Existence.get_checks() + test "get_checks/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end end - describe "single timeout check, check init state :ok, fsm init state: :error" do + describe "custom :id" do setup do - [ - check: %{ - mfa: {__MODULE__, :check_timeout, []}, - initial_delay: 0, - state: :ok, - timeout: 10 - } - ] - |> start_app(:error, 20) - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check: :killed] == Existence.get_checks() + start(id: CustomID) end - end - describe "single timeout check, check init state :ok, fsm init state: :ok" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_timeout, []}, - initial_delay: 0, - state: :ok, - timeout: 10 - } - ] - |> start_app(:ok, 20) - end - - test "get_state/0" do + test "get_state/1, default name" do assert :error == Existence.get_state() end - test "get_checks/0" do - assert [check: :killed] == Existence.get_checks() - end - end - - # _____raise check - describe "single raise check, check init state :error, fsm init state: :error" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_raise, []}, - initial_delay: 0 - } - ] - |> start_app() - end - - test "get_state/0" do - assert :error == Existence.get_state() + test "get_checks/1, default name" do + assert [] == Existence.get_checks() end - test "get_checks/0" do - assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = - Existence.get_checks() + test "get_state/1, valid name" do + assert :error == Existence.get_state(Existence) end - end - describe "single raise check, check init state :error, fsm init state: :ok" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_raise, []}, - initial_delay: 0 - } - ] - |> start_app(:ok) + test "get_checks/1, valid name" do + assert [] == Existence.get_checks(Existence) end - test "get_state/0" do - assert :error == Existence.get_state() + test "get_state/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end - test "get_checks/0" do - assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = - Existence.get_checks() + test "get_checks/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end end - describe "single raise check, check init state :ok, fsm init state: :error" do + describe "custom name: CustomName" do setup do - [ - check: %{ - mfa: {__MODULE__, :check_raise, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app() + start(name: CustomName) end - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = - Existence.get_checks() - end - end - - describe "single raise check, check init state :ok, fsm init state: :ok" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_raise, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app(:ok) + test "get_state/1, default name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state() end end - test "get_state/0" do - assert :error == Existence.get_state() + test "get_checks/1, default name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state() end end - test "get_checks/0" do - assert [check: {%RuntimeError{message: "check_raise"}, _stacktrace}] = - Existence.get_checks() + test "get_state/1, valid name" do + assert :error == Existence.get_state(CustomName) end - end - # _____throw check - describe "single throw check, check init state :error, fsm init state: :error" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_throw, []}, - initial_delay: 0 - } - ] - |> start_app() + test "get_checks/1, valid name" do + assert [] == Existence.get_checks(CustomName) end - test "get_state/0" do - assert :error == Existence.get_state() + test "get_state/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end - test "get_checks/0" do - assert [check: {{:nocatch, :check_raise}, _stacktrace}] = Existence.get_checks() + test "get_checks/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end end - describe "single throw check, check init state :error, fsm init state: :ok" do + describe "custom name: {:local, CustomName}" do setup do - [ - check: %{ - mfa: {__MODULE__, :check_throw, []}, - initial_delay: 0 - } - ] - |> start_app(:ok) + start(name: {:local, CustomName}) end - test "get_state/0" do - assert :error == Existence.get_state() + test "get_state/1, default name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state() end end - test "get_checks/0" do - assert [check: {{:nocatch, :check_raise}, _stacktrace}] = Existence.get_checks() + test "get_checks/1, default name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state() end end - end - describe "single throw check, check init state :ok, fsm init state: :error" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_throw, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app() + test "get_state/1, valid name" do + assert :error == Existence.get_state(CustomName) end - test "get_state/0" do - assert :error == Existence.get_state() + test "get_checks/1, valid name" do + assert [] == Existence.get_checks(CustomName) end - test "get_checks/0" do - assert [check: {{:nocatch, :check_raise}, _stacktrace}] = Existence.get_checks() + test "get_state/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end - end - describe "single throw check, check init state :ok, fsm init state: :ok" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_throw, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check: {{:nocatch, :check_raise}, _stacktrace}] = Existence.get_checks() + test "get_checks/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end end - # _____kill check - describe "single kill check, check init state :error, fsm init state: :error" do + describe "custom state: :custom_error" do setup do - [ - check: %{ - mfa: {__MODULE__, :check_kill, []}, - initial_delay: 0 - } - ] - |> start_app() + start(state: :custom_error) end - test "get_state/0" do + test "get_state/1, default name" do assert :error == Existence.get_state() end - test "get_checks/0" do - assert [check: :killed] == Existence.get_checks() - end - end - - describe "single kill check, check init state :error, fsm init state: :ok" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_kill, []}, - initial_delay: 0 - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check: :killed] == Existence.get_checks() - end - end - - describe "single kill check, check init state :ok, fsm init state: :error" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_kill, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app() - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check: :killed] == Existence.get_checks() - end - end - - describe "single kill check, check init state :ok, fsm init state: :ok" do - setup do - [ - check: %{ - mfa: {__MODULE__, :check_kill, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check: :killed] == Existence.get_checks() - end - end - - # _____two :ok checks - describe "two :ok checks, check init states: :error and :error, fsm init state: :error" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :error - }, - check_2: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app() - end - - test "get_state/0" do - assert :ok == Existence.get_state() - end - - test "get_checks/0" do - assert [check_1: :ok, check_2: :ok] == Existence.get_checks() |> Enum.sort() + test "get_checks/1, default name" do + assert [] == Existence.get_checks() end - end - describe "two :ok checks, check init states: :ok and :error, fsm init state: :error" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app() - end - - test "get_state/0" do - assert :ok == Existence.get_state() + test "get_state/1, valid name" do + assert :error == Existence.get_state(Existence) end - test "get_checks/0" do - assert [check_1: :ok, check_2: :ok] == Existence.get_checks() |> Enum.sort() + test "get_checks/1, valid name" do + assert [] == Existence.get_checks(Existence) end - end - describe "two :ok checks, check init states: :ok and :ok, fsm init state: :error" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app() - end - - test "get_state/0" do - assert :ok == Existence.get_state() + test "get_state/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end - test "get_checks/0" do - assert [check_1: :ok, check_2: :ok] == Existence.get_checks() |> Enum.sort() + test "get_checks/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end end - describe "two :ok checks, check init states: :error and :error, fsm init state: :ok" do + describe "custom state: :ok" do setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :error - }, - check_2: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :ok == Existence.get_state() + start(state: :ok) end - test "get_checks/0" do - assert [check_1: :ok, check_2: :ok] == Existence.get_checks() |> Enum.sort() - end - end - - describe "two :ok checks, check init states: :ok and :error, fsm init state: :ok" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app(:ok) - end - - test "get_state/0" do + test "get_state/1, default name" do assert :ok == Existence.get_state() end - test "get_checks/0" do - assert [check_1: :ok, check_2: :ok] == Existence.get_checks() |> Enum.sort() - end - end - - describe "two :ok checks, check init states: :ok and :ok, fsm init state: :ok" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :ok == Existence.get_state() - end - - test "get_checks/0" do - assert [check_1: :ok, check_2: :ok] == Existence.get_checks() |> Enum.sort() - end - end - - # _____two :error checks - describe "two :error checks, check init states: :error and :error, fsm init state: :error" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :error - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app() - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check_1: :error, check_2: :error] == Existence.get_checks() |> Enum.sort() - end - end - - describe "two :error checks, check init states: :ok and :error, fsm init state: :error" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app() - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check_1: :error, check_2: :error] == Existence.get_checks() |> Enum.sort() - end - end - - describe "two :error checks, check init states: :ok and :ok, fsm init state: :error" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app() - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check_1: :error, check_2: :error] == Existence.get_checks() |> Enum.sort() - end - end - - describe "two :error checks, check init states: :error and :error, fsm init state: :ok" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :error - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check_1: :error, check_2: :error] == Existence.get_checks() |> Enum.sort() + test "get_checks/1, default name" do + assert [] == Existence.get_checks() end - end - describe "two :error checks, check init states: :ok and :error, fsm init state: :ok" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :error == Existence.get_state() + test "get_state/1, valid name" do + assert :ok == Existence.get_state(Existence) end - test "get_checks/0" do - assert [check_1: :error, check_2: :error] == Existence.get_checks() |> Enum.sort() + test "get_checks/1, valid name" do + assert [] == Existence.get_checks(Existence) end - end - describe "two :error checks, check init states: :ok and :ok, fsm init state: :ok" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :error == Existence.get_state() + test "get_state/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end - test "get_checks/0" do - assert [check_1: :error, check_2: :error] == Existence.get_checks() |> Enum.sort() + test "get_checks/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end end - # _____:ok and :error checks - describe ":ok and :error checks, check init states: :error and :error, fsm init state: :error" do + describe "custom :id, name: CustomName and state: :ok" do setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :error - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app() - end - - test "get_state/0" do - assert :error == Existence.get_state() + start(id: CustomID, name: CustomName, state: :ok) end - test "get_checks/0" do - assert [check_1: :ok, check_2: :error] == Existence.get_checks() |> Enum.sort() - end - end - - describe ":ok and :error checks, check init states: :ok and :error, fsm init state: :error" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app() - end - - test "get_state/0" do - assert :error == Existence.get_state() + test "get_state/1, default name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state() end end - test "get_checks/0" do - assert [check_1: :ok, check_2: :error] == Existence.get_checks() |> Enum.sort() + test "get_checks/1, default name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state() end end - end - describe ":ok and :error checks, check init states: :error and :ok, fsm init state: :error" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :error - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app() - end - - test "get_state/0" do - assert :error == Existence.get_state() + test "get_state/1, valid name" do + assert :ok == Existence.get_state(CustomName) end - test "get_checks/0" do - assert [check_1: :ok, check_2: :error] == Existence.get_checks() |> Enum.sort() + test "get_checks/1, valid name" do + assert [] == Existence.get_checks(CustomName) end - end - describe ":ok and :error checks, check init states: :ok and :ok, fsm init state: :error" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app() - end - - test "get_state/0" do - assert :error == Existence.get_state() + test "get_state/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end - test "get_checks/0" do - assert [check_1: :ok, check_2: :error] == Existence.get_checks() |> Enum.sort() + test "get_checks/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end end - describe ":ok and :error checks, check init states: :error and :error, fsm init state: :ok" do + describe "custom :id, name: {:local, CustomName} and state: :ok" do setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :error - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :error == Existence.get_state() + start(id: CustomID, name: {:local, CustomName}, state: :ok) end - test "get_checks/0" do - assert [check_1: :ok, check_2: :error] == Existence.get_checks() |> Enum.sort() + test "get_state/1, default name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state() end end - end - describe ":ok and :error checks, check init states: :ok and :error, fsm init state: :ok" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :error - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :error == Existence.get_state() + test "get_checks/1, default name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state() end end - test "get_checks/0" do - assert [check_1: :ok, check_2: :error] == Existence.get_checks() |> Enum.sort() + test "get_state/1, valid name" do + assert :ok == Existence.get_state(CustomName) end - end - describe ":ok and :error checks, check init states: :error and :ok, fsm init state: :ok" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :error - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :error == Existence.get_state() + test "get_checks/1, valid name" do + assert [] == Existence.get_checks(CustomName) end - test "get_checks/0" do - assert [check_1: :ok, check_2: :error] == Existence.get_checks() |> Enum.sort() + test "get_state/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end - end - describe ":ok and :error checks, check init states: :ok and :ok, fsm init state: :ok" do - setup do - [ - check_1: %{ - mfa: {__MODULE__, :check_ok, []}, - initial_delay: 0, - state: :ok - }, - check_2: %{ - mfa: {__MODULE__, :check_error, []}, - initial_delay: 0, - state: :ok - } - ] - |> start_app(:ok) - end - - test "get_state/0" do - assert :error == Existence.get_state() - end - - test "get_checks/0" do - assert [check_1: :ok, check_2: :error] == Existence.get_checks() |> Enum.sort() + test "get_checks/1, invalid name" do + assert_raise ArgumentError, @ets_error, fn -> Existence.get_state(Invalid) end end end - - defp start_app(config, state \\ :error, init_sleep \\ 10) do - Application.put_env(:existence, Existence, config) - start_supervised!({Existence, state: state}) - Process.sleep(init_sleep) - :ok - end end diff --git a/test/existence_throw_test.exs b/test/existence_throw_test.exs new file mode 100644 index 0000000..c25533c --- /dev/null +++ b/test/existence_throw_test.exs @@ -0,0 +1,217 @@ +defmodule Existence.ThrowTest do + use ExUnit.Case + + import ExistenceTest.Common + + def check(), do: throw(:check_throw) + + describe "check: defaults, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {{:nocatch, :check_throw}, _stacktrace}] = Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {{:nocatch, :check_throw}, _stacktrace}] = Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ] + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {{:nocatch, :check_throw}, _stacktrace}] = Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {{:nocatch, :check_throw}, _stacktrace}] = Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {{:nocatch, :check_throw}, _stacktrace}] = Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :ok + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {{:nocatch, :check_throw}, _stacktrace}] = Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0 + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {{:nocatch, :check_throw}, _stacktrace}] = Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {{:nocatch, :check_throw}, _stacktrace}] = Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error + } + ], + state: :custom_error + ] + |> start() + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: {{:nocatch, :check_throw}, _stacktrace}] = Existence.get_checks() + end + end +end diff --git a/test/existence_timeout_test.exs b/test/existence_timeout_test.exs new file mode 100644 index 0000000..34c4ca3 --- /dev/null +++ b/test/existence_timeout_test.exs @@ -0,0 +1,226 @@ +defmodule Existence.TimeoutTest do + use ExUnit.Case + + import ExistenceTest.Common + + def check(), do: Process.sleep(999_999_999) + + describe "check: defaults, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + timeout: 10 + } + ] + ] + |> start(20) + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok, + timeout: 10 + } + ] + ] + |> start(20) + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: default" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error, + timeout: 10 + } + ] + ] + |> start(20) + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + timeout: 10 + } + ], + state: :ok + ] + |> start(20) + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok, + timeout: 10 + } + ], + state: :ok + ] + |> start(20) + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :ok" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error, + timeout: 10 + } + ], + state: :ok + ] + |> start(20) + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: defaults, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + timeout: 10 + } + ], + state: :custom_error + ] + |> start(20) + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :ok, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :ok, + timeout: 10 + } + ], + state: :custom_error + ] + |> start(20) + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end + + describe "check: state: :custom_error, fsm_state: :custom_error" do + setup do + [ + checks: [ + check: %{ + mfa: {__MODULE__, :check, []}, + initial_delay: 0, + state: :custom_error, + timeout: 10 + } + ], + state: :custom_error + ] + |> start(20) + end + + test "get_state/0" do + assert :error == Existence.get_state() + end + + test "get_checks/0" do + assert [check: :killed] == Existence.get_checks() + end + end +end diff --git a/test/gen_check_test.exs b/test/gen_check_test.exs deleted file mode 100644 index 565b30c..0000000 --- a/test/gen_check_test.exs +++ /dev/null @@ -1,47 +0,0 @@ -defmodule Existence.GenCheckTest do - use ExUnit.Case, async: true - - alias Existence.GenCheck - - setup do - config = [ - check: %{ - mfa: {__MODULE__, :error_fun, []}, - initial_delay: 0 - } - ] - - Application.put_env(:existence, Existence, config) - start_supervised!(Existence) - Process.sleep(10) - :ok - end - - def error_fun(), do: :error - - test "get_state/0" do - assert :error == GenCheck.get_state() - end - - test "get_checks/0" do - assert [check: :error] = GenCheck.get_checks() - end - - test "child_spec/1" do - assert %{id: Existence.GenCheck, start: {Existence.GenCheck, :start_link, [[]]}} == - GenCheck.child_spec([]) - - assert %{id: Existence.GenCheck, start: {Existence.GenCheck, :start_link, [[state: :ok]]}} == - GenCheck.child_spec(state: :ok) - end - - test "unhealthy/3 :enter" do - assert :keep_state_and_data == GenCheck.unhealthy(:enter, :unhealthy, []) - assert :keep_state_and_data == GenCheck.unhealthy(:enter, :healthy, []) - end - - test "healthy/3 :enter" do - assert :keep_state_and_data == GenCheck.healthy(:enter, :unhealthy, []) - assert :keep_state_and_data == GenCheck.healthy(:enter, :healthy, []) - end -end diff --git a/test/test_helper.exs b/test/test_helper.exs index 6a0af57..0f4512f 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1 +1,9 @@ ExUnit.start(capture_log: true) + +defmodule ExistenceTest.Common do + def start(config, init_sleep \\ 10) do + _pid = ExUnit.Callbacks.start_supervised!({Existence, config}) + Process.sleep(init_sleep) + :ok + end +end