prop/test/microwaveprop/workers/propagation_grid_worker_test.exs
Graham McIntire 0d022392fe
fix(propagation): use map_size on grid_data telemetry count
The :score_band span was reading point_count via length(grid_data),
but grid_data is a %{{lat, lon} => profile} map. Every forecast-hour
job was crashing with ArgumentError before any scores landed, leaving
the map without current-hour forecasts. Swap to map_size/1.
2026-04-19 10:26:46 -05:00

69 lines
2.6 KiB
Elixir
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

defmodule Microwaveprop.Workers.PropagationGridWorkerTest do
@moduledoc """
Tests the chain-orchestration behavior of PropagationGridWorker.
The worker processes forecast hours f00f18 across the CONUS grid,
but a single full sweep takes ~2 hours of wall time — longer than a
typical pod restart window. To survive deploys, the worker processes
ONE forecast hour per `perform/1` call and enqueues the next hour as
a fresh Oban job. The tests here cover the dispatch + chain logic
without mocking the full HRRR / scoring stack.
"""
use Microwaveprop.DataCase, async: false
use Oban.Testing, repo: Microwaveprop.Repo
alias Microwaveprop.Workers.MrmsFetchWorker
alias Microwaveprop.Workers.PropagationGridWorker
alias Microwaveprop.Workers.PropagationPruneWorker
describe "queue priority" do
test "PropagationGridWorker runs at the highest priority on :propagation" do
assert PropagationGridWorker.__opts__()[:priority] == 0
end
test "MrmsFetchWorker and PropagationPruneWorker yield to the grid chain" do
# Same :propagation queue — must be lower priority so hourly chain
# steps jump ahead of a MRMS or pruner backlog.
assert MrmsFetchWorker.__opts__()[:priority] > 0
assert PropagationPruneWorker.__opts__()[:priority] > 0
end
end
describe "compute_scores_algorithm/3" do
test "accepts a map of {{lat, lon} => profile} without raising" do
# grid_data is a map keyed by {lat, lon}, not a list.
# A regression guard against using length/1 on the map.
valid_time = ~U[2026-04-19 15:00:00Z]
assert [] =
PropagationGridWorker.compute_scores_algorithm(
%{},
valid_time,
false
)
end
end
describe "perform/1 — chain seeding (empty args)" do
test "enqueues all 19 forecast-hour jobs at once, all pointing at the same run_time" do
Oban.Testing.with_testing_mode(:manual, fn ->
assert :ok = PropagationGridWorker.perform(%Oban.Job{args: %{}})
jobs = all_enqueued(worker: PropagationGridWorker)
assert length(jobs) == 19
fhs = jobs |> Enum.map(& &1.args["forecast_hour"]) |> Enum.sort()
assert fhs == Enum.to_list(0..18)
# Every child job shares the same run_time and it's normalized
# to top-of-hour UTC.
run_times = jobs |> Enum.map(& &1.args["run_time"]) |> Enum.uniq()
assert [rt] = run_times
{:ok, dt, _} = DateTime.from_iso8601(rt)
assert dt.minute == 0
assert dt.second == 0
assert DateTime.before?(dt, DateTime.utc_now())
end)
end
end
end