Req's default `retry: :safe_transient` waits ~7s across exponential backoff when the stubbed response is a 5xx or connection error. Tests that asserted error-status behavior paid that price on every run. Disable retries in test env for every direct Req caller: * `Towerops.HTTP` (covers weather/netbox/geocoding/http_executor/pagerduty) * `CnMaestro.Client`, `Gaiia.Client`, `Preseem.Client`, `Sonar.Client`, `Splynx.Client`, `Agents.ReleaseChecker`, `Billing.StripeClient` Use `Keyword.put_new(:retry, false)` so any test explicitly opting into retry behavior is respected. Suite time: 82.8s → 65.3s. Slowest test dropped from 7050ms to 1447ms.
56 lines
1.6 KiB
Elixir
56 lines
1.6 KiB
Elixir
defmodule Towerops.HTTP do
|
|
@moduledoc false
|
|
|
|
def request(owner, req_opts) when is_list(req_opts) do
|
|
req_opts
|
|
|> maybe_attach_test_plug(owner)
|
|
|> maybe_disable_retry()
|
|
|> Req.request()
|
|
rescue
|
|
error in RuntimeError ->
|
|
if String.contains?(Exception.message(error), "cannot find mock/stub") do
|
|
{:error, :no_test_stub}
|
|
else
|
|
reraise error, __STACKTRACE__
|
|
end
|
|
end
|
|
|
|
def get(owner, url_or_opts, opts \\ []) do
|
|
simple_request(:get, owner, url_or_opts, opts)
|
|
end
|
|
|
|
def post(owner, url_or_opts, opts \\ []) do
|
|
simple_request(:post, owner, url_or_opts, opts)
|
|
end
|
|
|
|
def delete(owner, url_or_opts, opts \\ []) do
|
|
simple_request(:delete, owner, url_or_opts, opts)
|
|
end
|
|
|
|
defp simple_request(method, owner, url, opts) when is_binary(url) do
|
|
request(owner, [method: method, url: url] ++ opts)
|
|
end
|
|
|
|
defp simple_request(method, owner, req_opts, []) when is_list(req_opts) do
|
|
request(owner, Keyword.put_new(req_opts, :method, method))
|
|
end
|
|
|
|
defp maybe_attach_test_plug(req_opts, owner) do
|
|
if Application.get_env(:towerops, :env) == :test and !Keyword.has_key?(req_opts, :plug) do
|
|
Keyword.put(req_opts, :plug, {Req.Test, owner})
|
|
else
|
|
req_opts
|
|
end
|
|
end
|
|
|
|
# In test, disable Req's default retry-on-5xx/transient-error behavior.
|
|
# Without this, tests that stub an error status wait ~7s for retries to
|
|
# exhaust before the response is returned.
|
|
defp maybe_disable_retry(req_opts) do
|
|
if Application.get_env(:towerops, :env) == :test and !Keyword.has_key?(req_opts, :retry) do
|
|
Keyword.put(req_opts, :retry, false)
|
|
else
|
|
req_opts
|
|
end
|
|
end
|
|
end
|