aprs.me/test/aprsme/telemetry/database_metrics_test.exs
Graham McIntire b86153cd27
Fix all mix credo --strict warnings (188 → 0)
- Replace apply/2 with direct fully-qualified calls in movement_test
- Fix assert_receive timeouts < 1000ms across 8 test files
- Move nested import statements to module-level scope
- Fix tests with no assertions and add missing doctest
- Replace weak type assertions with specific value checks
- Fix conditional assertions and length/1 expensive patterns
- Disable inappropriate Jump.CredoChecks.AvoidSocketAssignsInTest
- Fix tests not calling application code with credo:disable
- Add various credo:disable comments for legitimate patterns
2026-06-12 16:27:20 -05:00

131 lines
4.5 KiB
Elixir

defmodule Aprsme.Telemetry.DatabaseMetricsTest do
# Uses DataCase for a sandbox DB checkout — some metrics run live queries
# against pg_stat_* views. async: false because we mutate :aprsme :env
# in one test.
use Aprsme.DataCase, async: false
alias Aprsme.Telemetry.DatabaseMetrics
defp attach_collector(event, tag \\ to_string(System.unique_integer([:positive]))) do
test_pid = self()
handler_id = "test-#{tag}-#{Enum.join(event, ",")}"
:telemetry.attach(
handler_id,
event,
fn ^event, measurements, metadata, _ ->
send(test_pid, {:telemetry, event, measurements, metadata})
end,
nil
)
on_exit(fn -> :telemetry.detach(handler_id) end)
handler_id
end
describe "collect_postgres_metrics/0 in :test env" do
test "is a no-op returning :ok" do
original = Application.get_env(:aprsme, :env)
Application.put_env(:aprsme, :env, :test)
try do
assert DatabaseMetrics.collect_postgres_metrics() == :ok
after
Application.put_env(:aprsme, :env, original)
end
end
end
describe "collect_db_pool_metrics/0" do
test "emits [:aprsme, :repo, :pool] telemetry with pool_size from config" do
attach_collector([:aprsme, :repo, :pool])
DatabaseMetrics.collect_db_pool_metrics()
assert_receive {:telemetry, [:aprsme, :repo, :pool], measurements, _}, 1_000
assert Map.has_key?(measurements, :size)
assert Map.has_key?(measurements, :idle)
assert Map.has_key?(measurements, :busy)
assert Map.has_key?(measurements, :available)
assert Map.has_key?(measurements, :queue_length)
assert Map.has_key?(measurements, :total)
end
end
describe "collect_pgbouncer_metrics/0" do
test "is a no-op returning :ok" do
assert DatabaseMetrics.collect_pgbouncer_metrics() == :ok
end
end
describe "collect_db_pool_metrics/0 when Repo is not running" do
test "emits unavailable metrics when no Repo is registered" do
# Stop the Repo for this test — we need to restart it afterward to avoid
# breaking downstream tests.
repo_pid = Process.whereis(Aprsme.Repo)
if repo_pid do
# Temporarily unregister without stopping to avoid disrupting other tests.
:erlang.unregister(Aprsme.Repo)
on_exit(fn ->
if !Process.whereis(Aprsme.Repo) do
true = Process.register(repo_pid, Aprsme.Repo)
end
end)
end
attach_collector([:aprsme, :repo, :pool])
DatabaseMetrics.collect_db_pool_metrics()
assert_receive {:telemetry, [:aprsme, :repo, :pool], measurements, _}, 1_000
# The "unavailable" helper reports mostly zeros.
assert measurements.size == (Application.get_env(:aprsme, Aprsme.Repo)[:pool_size] || 10)
assert measurements.idle == 0
assert measurements.busy == 0
end
end
describe "to_number/1 and to_number/2 helpers (private — exercised through emit)" do
# to_number/1 has 4 heads (nil, %Decimal{}, number, fallback). to_number/2 has
# the same shape for the :integer overload. We exercise these via the public
# functions that build telemetry payloads from query results.
test "emits packets_table telemetry with Decimal values converted via to_number/1" do
attach_collector([:aprsme, :postgres, :packets_table])
original = Application.get_env(:aprsme, :env)
Application.put_env(:aprsme, :env, :prod)
try do
DatabaseMetrics.collect_postgres_metrics()
after
Application.put_env(:aprsme, :env, original)
end
# Values should always be plain numbers, not Decimals.
assert_receive {:telemetry, [:aprsme, :postgres, :packets_table], measurements, _}, 2_000
Enum.each(measurements, fn {_k, v} -> assert is_number(v) end)
end
end
describe "collect_postgres_metrics/0 outside :test env" do
test "emits connections and packets_table telemetry events" do
original = Application.get_env(:aprsme, :env)
Application.put_env(:aprsme, :env, :prod)
attach_collector([:aprsme, :postgres, :connections])
attach_collector([:aprsme, :postgres, :packets_table])
try do
DatabaseMetrics.collect_postgres_metrics()
after
Application.put_env(:aprsme, :env, original)
end
assert_receive {:telemetry, [:aprsme, :postgres, :connections], conn_metrics, _}, 2_000
assert Map.has_key?(conn_metrics, :total)
assert Map.has_key?(conn_metrics, :active)
assert Map.has_key?(conn_metrics, :idle)
end
end
end