module-eval: assert the severity table once, not once per tier

Both journald receivers import one PRIORITY mapping, and each tier's
suite was asserting the whole table against its own receiver. That checks
one file twice: invert the table and two cases fail saying the same
thing, which tells you nothing about which of the two possible defects
you have.

Split by subject instead. The table's contents — the inverted direction,
overwrite_text, parse_from/on_error — belong to the file that holds them,
so they get a suite of their own reading that file directly, with no
fixture at all. Each tier keeps a case, reduced to the question only it
can answer: does MY receiver carry the shared mapping.

Both tier cases stay. They cover different receivers over different
journals — the agent container's own and the swarm collector's host
journal — and one tier quietly losing its parser while the other keeps
one is exactly the half-fixed state worth catching.

Membership rather than equality of the whole operator list, so a tier
that later grows an unrelated operator of its own still passes.

Checked against seven defect scenarios: each fails exactly one case, and
names the right one.
This commit is contained in:
atlas 2026-09-20 13:32:00 +02:00 • committed by mara
commit 33a7ca6118
5 changed files with 174 additions and 88 deletions

View file

@ -18,8 +18,7 @@ let
;
})
hive
journaldSeverityOf
journaldSeverityOverwritesText
carriesJournaldSeverity
runGroup
otelSettings
;
@ -158,32 +157,17 @@ let
named != [ ] && lib.all (a: builtins.elem a s.service.extensions) named;
}
{
# The host-journal half of the mapping the agent tier's receiver carries
# (./agent-otel.nix holds the sibling case and the full reasoning). Both
# import one file, so this is what says the swarm collector still does —
# the receivers are otherwise unrelated config, and a drifted copy is
# silent: every line still arrives, labelled as the wrong thing.
# The host-journal sibling of ./agent-otel.nix's wiring case, which
# carries the full reasoning. Same question, different receiver: this
# one reads the HOST's journal rather than a container's, and the two
# are unrelated config — a fixed stanza there, a parameterised block
# inside `containers.swarm-otel` here — so one losing its parser while
# the other keeps one is a real and silent state.
#
# Asserted at both ends of the table because the direction is inverted
# and an inverted copy still maps every value to something.
name = "the swarm collector maps the host journal's PRIORITY the right way up";
ok =
let
sev = journaldSeverityOf (otelSettings otelNoStores).receivers.journald;
in
sev "0" == "fatal"
&& sev "3" == "error"
&& sev "4" == "warn"
&& sev "6" == "info"
&& sev "7" == "debug";
}
{
# Same reasoning as the agent tier's copy: without this the parser
# populates `severity_text` with the raw digit it matched, which passes
# any check asking whether severity is set and is not a level anything
# renders.
name = "the swarm collector writes a level name, not the raw priority digit";
ok = journaldSeverityOverwritesText (otelSettings otelNoStores).receivers.journald;
# Contents are not this case's business. The table both receivers import
# is asserted once, in ./journald-severity.nix.
name = "the swarm collector's journald receiver carries the shared PRIORITY mapping";
ok = carriesJournaldSeverity (otelSettings otelNoStores).receivers.journald;
}
];
in