towerops/lib/towerops/http.ex
Graham McIntire 85dd821400 tests: disable Req retries in test env to eliminate ~7s-per-test delays
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.
2026-04-24 10:04:52 -05:00

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