test(sigint): assert the 45 inputs are DISTINCT, and stop claiming every stub carries the sentinel
Two closure gaps. 1. Both suites asserted only `cases.len() == 45`, so the exact 45-entries-over-43-distinct-inputs regression could recur unnoticed --- the one where X3 collapsed into 1/E/empty and X4 into 0/V/safe/bare, leaving two framing-specified cases silently unexercised. shared_cases() now asserts uniqueness over (status, stdout, stderr), inside the generator so no consumer can forget it. Verified by reverting both payloads to the sentinel: it fails naming X3. 2. Comments and ledger still said every stub emits the sentinel, which the explicit X3/X4 payloads had made false. They now say the BRANCH-DISCRIMINATING cases carry it while X3 and X4 deliberately carry their own --- X3 the canonical ignored wording with no token, X4 noise --- and that this is what makes them distinct inputs. The duplicated `self::`/`super::` explanation left over from the nesting fix is reduced to the correct one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai
This commit is contained in:
parent
fb8a904923
commit
b492426c69
|
|
@ -290,8 +290,9 @@ from #171 and #215.
|
|||
the shell needs them.
|
||||
- **Conformance vectors live in `tests/common/sigint_conformance.rs`**
|
||||
and are consumed by BOTH validators, so the two copies cannot drift
|
||||
while each still reports "45 cases". Every stub emits a **sentinel on
|
||||
stderr**, which is what separates `ValidatedError` from `Boundary` —
|
||||
while each still reports "45 cases". The **branch-discriminating** cases emit a
|
||||
sentinel on stderr, which is what separates `ValidatedError` from
|
||||
`Boundary` —
|
||||
they share exit 2, so comparing codes alone let a validator that
|
||||
accepted every status 2 pass the whole matrix. An `Outcome` enum
|
||||
(Safe / ValidatedIgnored / ValidatedError / Boundary) is asserted
|
||||
|
|
@ -319,9 +320,15 @@ from #171 and #215.
|
|||
`gate_validates_the_whole_shared_conformance_set`; token-to-stderr
|
||||
fails `sigint_helper_reports_safe_…`. An earlier entry said the
|
||||
status-2 mutation was caught only by the dedicated row — that was
|
||||
true of the pre-sentinel matrix and is **superseded**: every stub now
|
||||
emits a sentinel on stderr, so the matrix can see which branch
|
||||
produced the exit 2.
|
||||
true of the pre-sentinel matrix and is **superseded**: the
|
||||
branch-discriminating cases now carry a sentinel, so the matrix can
|
||||
see which branch produced the exit 2.
|
||||
- **X3 and X4 deliberately carry their OWN stderr payloads**, not the
|
||||
sentinel — X3 the canonical ignored wording with no token, X4 noise —
|
||||
which is what makes them distinct inputs. `shared_cases()` asserts
|
||||
uniqueness over `(status, stdout, stderr)`, so the earlier
|
||||
45-entries-over-43-inputs collapse cannot recur silently; reverting
|
||||
either payload now fails by name.
|
||||
- **Two PRE-EXISTING crdt-only failures found while gating properly:**
|
||||
`m4_24_bare_string_glob_stays_relative` and
|
||||
`m4_24_d3_fallback_base_is_the_smallest_attachment_dir`. They
|
||||
|
|
|
|||
|
|
@ -29,8 +29,16 @@ pub const TOKEN_SAFE: &[u8] = b"pmacs-sigint-v1:safe";
|
|||
pub const TOKEN_IGNORED: &[u8] = b"pmacs-sigint-v1:ignored";
|
||||
pub const TOKEN_ERROR: &[u8] = b"pmacs-sigint-v1:error";
|
||||
|
||||
/// Emitted on stderr by **every** stub, so a consumer's output can be
|
||||
/// searched for it: present ⇒ the child's stderr was surfaced.
|
||||
/// Emitted on stderr by the **branch-discriminating** cases — the
|
||||
/// cross-product rows and X1 — so a consumer's output can be searched
|
||||
/// for it: present ⇒ the child's stderr was surfaced.
|
||||
///
|
||||
/// **X3 and X4 deliberately carry their own payloads instead**, which
|
||||
/// is what makes them distinct inputs rather than duplicates of
|
||||
/// `1/E/empty` and `0/V/safe/bare`. An earlier revision gave every case
|
||||
/// this same sentinel and so shipped 45 entries over 43 distinct
|
||||
/// inputs; [`shared_cases`] now asserts uniqueness so that cannot
|
||||
/// recur silently.
|
||||
pub const SENTINEL: &str = "PMACS-CONFORMANCE-SENTINEL";
|
||||
|
||||
/// The canonical wording the helper uses for `ignored`. X3 emits it
|
||||
|
|
@ -50,7 +58,8 @@ pub struct Case {
|
|||
pub expect: Outcome,
|
||||
}
|
||||
|
||||
/// A `/bin/sh` stub reproducing one case, sentinel included.
|
||||
/// A `/bin/sh` stub reproducing one case exactly: its stdout bytes, its
|
||||
/// own stderr payload, and its status.
|
||||
#[must_use]
|
||||
pub fn stub_script(case: &Case) -> String {
|
||||
let octal = case.stdout.iter().fold(String::new(), |mut acc, b| {
|
||||
|
|
@ -185,5 +194,20 @@ pub fn shared_cases() -> Vec<Case> {
|
|||
stderr: "unrelated chatter on stderr".to_owned(),
|
||||
expect: Outcome::Safe,
|
||||
});
|
||||
// The set must be 45 DISTINCT inputs, not merely 45 entries. A
|
||||
// previous revision gave every case the same stderr, which silently
|
||||
// collapsed X3 into `1/E/empty` and X4 into `0/V/safe/bare` — 45
|
||||
// entries, 43 inputs, and two framing-specified cases quietly not
|
||||
// exercised. Asserted here rather than in each suite so no consumer
|
||||
// can forget it.
|
||||
let mut seen = std::collections::HashSet::new();
|
||||
for case in &out {
|
||||
assert!(
|
||||
seen.insert((case.status, case.stdout.clone(), case.stderr.clone())),
|
||||
"duplicate conformance input at {}: (status, stdout, stderr) already present",
|
||||
case.name
|
||||
);
|
||||
}
|
||||
assert_eq!(seen.len(), out.len(), "every case must be a distinct input");
|
||||
out
|
||||
}
|
||||
|
|
|
|||
|
|
@ -289,9 +289,6 @@ mod crdt {
|
|||
/// surfaces it, a boundary failure must not.
|
||||
#[test]
|
||||
fn rd_precondition_validates_the_whole_conformance_set() {
|
||||
// `self::` and NOT `crate::`: this file is ALSO compiled as a
|
||||
// nested module of `gpu_initial_target_acceptance.rs`, where
|
||||
// `crate::` is the outer test crate and has no `common`.
|
||||
// `super::` and NOT `crate::`: this file is ALSO compiled as a
|
||||
// nested module of `gpu_initial_target_acceptance.rs`, where
|
||||
// `crate::` is the outer test crate and has no `common`.
|
||||
|
|
|
|||
Loading…
Reference in New Issue