test(ci): derive the hardware-docs guard from the workflows - #319
test(ci): derive the hardware-docs guard from the workflows#319volen-silo wants to merge 1 commit into
Conversation
The guard compared `docs/ci-hardware-testing.md` against a list of literals in the test source. Both sides were hand-maintained, so adding a lane changed neither and the test stayed green with the doc silently short a row. It only spoke up when someone edited one side without the other — failing the person fixing the docs rather than the person who made them wrong. Derive the expectations from the workflows instead. A new self-hosted lane now fails the build until the table, the runner labels, the canonical artifact list, the dispatch choices, and both prose enumerations follow it. Two of those surfaces were not checked against anything before. The runner-labels column was parsed and then dropped on the floor, and the dispatch-choices list had no guard at all. No documentation changes: every derived assertion already passes against the doc as it stands. The defect was the guard's inability to catch future drift, not a divergence sitting in the tree. Refs: #294 Signed-off-by: Eugene Volen <Eugene.Volen@amd.com>
|
I reviewed this PR (diff-only, plus building and running the affected xtask tests locally against the PR's actual worktree content) and didn't find anything blocking. What I checked in particular, since this is a CI guard whose whole point is not to pass silently when it shouldn't:
This is a diff-and-local-test read, not a substitute for CI or a maintainer's own pass — but from that read, this looks safe to merge once CI is green. |
r0x0r
left a comment
There was a problem hiding this comment.
This is a solid structural fix — deriving the expectations from the workflows is the right call, and the mutation table (especially "add a sixth lane, docs untouched" failing through each surface in turn) is convincing evidence the guard actually bites now rather than passing-while-wrong.
One forward-looking note on flattened_list_items: for the block form it splits the " - "-joined string that flattened_values produced back on " - ". That round-trip is lossy — it's safe for runner labels and the current dispatch options: values (none contain " - "), but now that flattened_values is generalized over arbitrary keys, a future derived value that legitimately contained " - " would mis-split silently. It's a reasonable assumption to make given the inputs; worth a one-line comment stating that the helper assumes label-like tokens with no embedded " - ", so the constraint is explicit for whoever reuses it next.
Everything else — scoping the job-id scan to top_level_block(text, "jobs"), hoisting uploaded_e2e_artifacts to shared with the body unchanged, and keeping runs_on_values as a thin wrapper so its existing guard still applies — reads well.
Part of #294 — acceptance criterion 4 ("adding a new lane without updating
docs/ci-hardware-testing.mdfails CI"). The drift fixes and the composite-action extraction follow separately.Summary
hardware_testing_docs_cover_all_self_hosted_platformsnow derives its expectations frome2e-selfhosted.yml/nightly.yml/ci.ymlinstead of comparing the doc against literals in the test source..map(|row| (row[0], row[2]))), and the dispatch-choices list, which had none.Why the old guard could not work
Both sides were hand-maintained. Adding a lane changed neither the doc nor the
vec!, so the test stayed green with the table silently short a row. It only fired when someone edited one side without the other — which fails the person fixing the docs, not the person who made them wrong. #278 shows the shape: the author had to update the workflow, the doc, the README and the test literals in lockstep, and the test went red mid-way through doing so.New assertions
Derived per self-hosted job, in workflow order: table rows, runner labels vs actual
runs-on, artifact list (viauploaded_e2e_artifactsacross all three workflows),workflow_dispatch.inputs.platform.optionsvs the documented choices, and both "the self-hosted jobs (…)" prose enumerations. ThePlatformcolumn stays free prose — it isn't derivable from YAML — and is asserted non-empty only.Correcting the issue on two points
The docs are not currently stale. #294 says adding a lane in #278 "left the doc table, the artifact list, two sentences and the dispatch-options list stale, with the test green throughout". #278 (
01ba5257) in fact updateddocs/ci-hardware-testing.md(22 lines),tests/e2e-cucumber/README.md(6) and the test literals (13) in the same commit. All six derived assertions pass against the doc exactly as it is onmain, which is why this PR touches no documentation. The defect is structural — hardcoded expectations cannot catch future drift — not a divergence sitting in the tree today."Three of those lanes" (
ci-hardware-testing.md:188) is not stale either. Exactly three lanes carrystrix-halo. Left alone.Non-obvious decisions
runs_on_valuesgeneralized toflattened_values(text, key)so the same continuation-joining logic can readoptions:.runs_on_valuesis now a wrapper and its existing extractor guard passes untouched.uploaded_e2e_artifactslived inside#[cfg(test)] mod testsine2e_report.rsand had to be hoisted to#[cfg(test)] pub(crate)to be shared. Body unchanged; both existing consumers still pass.top_level_block(text, "jobs"), sopush:/group:/contents:at the same indent cannot be mistaken for jobs. Covered by a dedicated extractor guard alongside the file's other helper tests.Verification
cargo fmt --all -- --check= 0 ·cargo clippy --workspace --all-targets -- -D warnings= 0 ·cargo test --workspace --all-targets= 0 ·python scripts/smoke_local.py= 0.A guard whose failure mode is "passes while wrong" proves nothing by passing, so it was mutation-tested. Each of these fails, and the tree restores byte-identical:
Runner labelscellPlatformcellLoad-bearing tests confirmed still passing:
ci_yml_schedules_no_self_hosted_job,workflows_use_distinct_concurrency_groups,self_hosted_workflow_owns_the_gpu_lanes, all four*_prebuilt_e2e_lanes_*, and both consumers ofuploaded_e2e_artifacts.Scope
CI/test-only; no CLI-observable behaviour changes, so no Gherkin scenario is required (AGENTS.md §3 exempts CI plumbing and tests).
One CI-visibility note worth stating:
xtask/src/affected.rsforces a full-workspace test run for any.github/workflows/change, so this test runs on PRs that touch the workflows. A docs-only PR selects nothing (is_ignorabledropsdocs/), so the doc half is enforced on push/merge_group and bywindows-build-and-testrather than on the PR itself.