prop/test/microwaveprop/logger_format_test.exs
Graham McIntire b2b8ddc1c4
test: silence expected warnings/errors during test runs
Passes `capture_log: true` to ExUnit.start/1 so log output emitted
during a passing test stays in the per-test capture buffer instead of
stdout. Drops ~360 lines of noise from the suite: Postgrex teardown
disconnects, expected worker failures, NexradClient 404 stubs,
NotifyListener warm-skip messages, SNMP poll failures, PromEx tag-
drop warnings, and OTel-handler boot errors. Failing tests still
surface their full logs on report, so debugging is unchanged.

Side-effect fixes:
- LoggerFormatTest opts out via @moduletag capture_log: false — it
  patches the :default :logger handler and capture_log hot-swaps the
  same handler, so the setup lookup would 404.
- TelemetryTest.start_link/1 unlinks the supervisor before the brutal
  kill so the exit signal doesn't propagate to the test process.
- Drop unused `import Ecto.Query` in a top_hours mix-task test.
- Drop unused default-arg `attrs \\ %{}` on create_contact/1 in
  contact_map_live_test (every caller passes attrs explicitly).

Remaining noise is ~3 lines from oban_pro vendored-dep @impl warnings
(require an upstream patch) plus rare intermittent async teardowns.
2026-04-24 09:27:17 -05:00

65 lines
2.3 KiB
Elixir

defmodule Microwaveprop.LoggerFormatTest do
# async: false — we briefly swap the global :default :logger handler's
# formatter and forward its output to a self()-bound IO device so the
# test can capture the JSON-encoded output. Restored on exit.
#
# Opts out of the suite-wide capture_log flag — capture_log hot-swaps
# the :default handler for its own capture handler, so our direct
# :logger.get_handler_config(:default) lookup in setup would 404.
use ExUnit.Case, async: false
alias LoggerJSON.Formatters.Basic
require Logger
@moduletag capture_log: false
describe "structured JSON formatter" do
setup do
{:ok, handler_cfg} = :logger.get_handler_config(:default)
prev_formatter = handler_cfg.formatter
new_formatter =
Basic.new(metadata: [:request_id, :trace_id, :worker, :queue, :job_id])
:ok = :logger.update_handler_config(:default, :formatter, new_formatter)
on_exit(fn ->
:logger.update_handler_config(:default, :formatter, prev_formatter)
end)
{:ok, formatter: new_formatter}
end
test "Basic formatter encodes an info log as a valid JSON object",
%{formatter: {formatter_mod, formatter_cfg}} do
# Build a `:logger` log event the same shape the handler feeds the
# formatter, then assert the formatter's output is valid JSON with
# the expected message and metadata fields.
log_event = %{
level: :info,
msg: {:string, "hello-json"},
meta: %{
time: :os.system_time(:microsecond),
request_id: "abc-123",
worker: "TestWorker"
}
}
rendered = formatter_mod.format(log_event, formatter_cfg)
payload = rendered |> IO.iodata_to_binary() |> String.trim_trailing("\n")
assert {:ok, decoded} = Jason.decode(payload)
assert decoded["message"] == "hello-json"
assert get_in(decoded, ["metadata", "request_id"]) == "abc-123"
assert get_in(decoded, ["metadata", "worker"]) == "TestWorker"
end
test "swapping the :default handler formatter takes effect" do
# Smoke test that the setup actually attached our JSON formatter
# to the :default handler (i.e. the runtime.exs swap would land).
{:ok, cfg} = :logger.get_handler_config(:default)
assert match?({Basic, _}, cfg.formatter)
end
end
end