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:
parent
7fa13b592f
commit
33a7ca6118
5 changed files with 174 additions and 88 deletions
|
|
@ -140,33 +140,23 @@ let
|
|||
|
||||
agentHarness = machine: machine.systemd.services.hive-agent;
|
||||
|
||||
# Reads a journald receiver's rendered operator list back as a plain
|
||||
# `PRIORITY -> severity-name` function, so a case can ask what a given
|
||||
# priority actually maps to rather than matching on the shape of the config
|
||||
# that produces it. Shared because two tiers run that receiver — the agent
|
||||
# container over its own journal, the swarm collector over the host's — from
|
||||
# one imported mapping, and the case that says so has to reach both.
|
||||
# `null` for a receiver carrying no severity parser at all, which is the
|
||||
# state that mapping replaced.
|
||||
journaldSeverityOf =
|
||||
receiver: priority:
|
||||
let
|
||||
parser = lib.findFirst (o: o.type or null == "severity_parser") null (receiver.operators or [ ]);
|
||||
# The mapping is `severity-name -> value or list of values`; invert it
|
||||
# into `value -> severity-name` so a lookup is by priority.
|
||||
hits = lib.attrNames (lib.filterAttrs (_: v: lib.elem priority (lib.toList v)) parser.mapping);
|
||||
in
|
||||
if parser == null || hits == [ ] then null else lib.head hits;
|
||||
# The PRIORITY → severity operator both journald receivers attach, read
|
||||
# straight off the file that defines it. What each TIER's case then asks is
|
||||
# only whether its own receiver carries this exact value — the contents are
|
||||
# somebody else's case (./journald-severity.nix), asserted once.
|
||||
#
|
||||
# Here rather than in one of the suites because three of them want it: the
|
||||
# two tiers, to say they are wired to it, and the suite that reads what it
|
||||
# says. A parser rather than the whole list, so a tier that later grows an
|
||||
# unrelated operator of its own still passes the wiring case.
|
||||
journaldSeverityParser = lib.findFirst (o: o.type or null == "severity_parser") null (
|
||||
import ../journald-severity.nix
|
||||
);
|
||||
|
||||
# Whether that same parser rewrites the severity TEXT. Its own reader,
|
||||
# because it is a separate way for the mapping to be there and useless: see
|
||||
# the case that asserts it.
|
||||
journaldSeverityOverwritesText =
|
||||
receiver:
|
||||
let
|
||||
parser = lib.findFirst (o: o.type or null == "severity_parser") { } (receiver.operators or [ ]);
|
||||
in
|
||||
parser.overwrite_text or false;
|
||||
# Whether a given receiver is wired to it. One expression, used by both
|
||||
# tiers, so "this receiver carries the shared mapping" is spelled once and
|
||||
# the two tier cases differ only in which receiver they hand it.
|
||||
carriesJournaldSeverity = receiver: lib.elem journaldSeverityParser (receiver.operators or [ ]);
|
||||
|
||||
# The enables that switch owns. ⚠️ `otel` is the per-hive collector's own
|
||||
# option and is NOT under `deploy` — spelled at the wrong path it would be
|
||||
|
|
@ -225,8 +215,8 @@ in
|
|||
inherit baoSettings;
|
||||
inherit otelSettings;
|
||||
inherit agentHarness;
|
||||
inherit journaldSeverityOf;
|
||||
inherit journaldSeverityOverwritesText;
|
||||
inherit journaldSeverityParser;
|
||||
inherit carriesJournaldSeverity;
|
||||
inherit swarmServiceEnables;
|
||||
inherit runGroup;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue