Per-test known issues: green jobs for known failures, honest badges - #14
Open
yarikoptic wants to merge 7 commits into
Open
yarikoptic wants to merge 7 commits into
yarikoptic wants to merge 7 commits into
Conversation
Most of the matrix is red for reasons we already understand, which both hides new failures inside a red cell and leaves no way to notice when a known one goes away. Replace the hand-kept KNOWN_RED list (and its copy in GOTCHAS.md) with a single, validated source: - .github/known-issues.yaml: issues keyed by id, each naming backend globs x targets, the failing test ids (prove-style ranges allowed; "*" for a not-yet-narrowed whole cell), expect: fail|flaky, tags from a declared vocabulary (fs-limitation, fs-divergence, test-assumption, build-config, harness, fixed-upstream, needs-triage, ...), optional fixed-in, and links. Seeded from run 36050917994. - bin/ci/collect-results.py: per-test results.tsv from what each suite already emits -- TAP for git (.out/.exit), pjdfstest (prove -v) and stress-ng (our driver now prints TAP), tasty's console tree for git-annex -- each cross-checked against the suite's own totals so a drifting parser reports "incomplete" instead of hiding failures. - bin/ci/known_issues.py: validate; check one cell (job green iff every failure is covered, red on new failures or incomplete runs; notices for issues that no longer reproduce, warnings for stale patterns); regenerate GOTCHAS.md's "Known issues" section; draft stubs. - The badge/report keep telling the truth: "failing (known)" is still red, "N new failing", "incomplete", "+N fixed?". Seeding surfaced that both loop git-annex cells mostly fail on annex.diskreserve (100 MB default) vs the 100 MB loop image -- a harness issue, recorded as such rather than fixed here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8dGtiFfZ6gRt2bWj39Qv3
… fixes evals/ now holds the data describing which filesystem evaluations run (matrix.yaml) and how they are expected to come out (known-issues.yaml): neither is GitHub-specific -- bin/ci reads both locally and in the VM, and a future non-GitHub CI would share them. Shellcheck in CI: bin/ci/shellcheck.sh checks every tracked file whose first line is a sh/bash shebang (same discovery as improveit's shellcheckit), so provision/*.sh and bin/eval-under* are covered too; .github/workflows/shellcheck.yml runs it. CLAUDE.md and README point at it instead of a hand-written glob. Fixes from three independent reviews of the previous commit: - collect-results: prove pads the "(Wstat:" column, so no #exit rows were ever produced for pjdfstest; a repeated TAP number could turn a "not ok" into "ok" -- now the failure is kept and the cell reported incomplete. - known_issues: header lines must be "# key: value" (ids starting with '#' were dropped); reversed ranges are a validation error; draft emits ids validate accepts. - workflow: skip the check on cancelled runs (they were recorded as "incomplete"); dump failure logs after install failures again; validation is its own job so a stale GOTCHAS.md cannot stop the matrix; the output dir is defined once, in the job env. - run-under: chown the output dir up front (a killed run left it root- owned), and no recursive chown of an overridable path. - report/badges: XML-escape badge text; issue anchors prefixed to avoid colliding with cell anchors; cells without a verdict count as unexpected in the overall badge. - data: unconfirmed root causes (diskreserve on ext4, OsPath on BeeGFS) are tagged needs-triage and worded as hypotheses; the whole-cell loop issue names its two backends instead of loop-*. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8dGtiFfZ6gRt2bWj39Qv3
Master meanwhile gained .github/workflows/checks.yaml (shellcheck + bats, via bin/ci/run-checks.sh), so a separate shellcheck workflow would be a duplicate. Drop it; run-checks.sh now delegates to bin/ci/shellcheck.sh, which finds scripts by shebang instead of a fixed glob (24 today, including run-checks.sh and install-check-deps.sh), and honours the same SHELLCHECK override. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8dGtiFfZ6gRt2bWj39Qv3
Every git cell came out "incomplete" (duplicate TAP numbers in t0202-gettext-perl.sh), and both loop git-annex cells had tasty counts that did not add up. Both were the new cross-checks doing their job: - git: t0202 runs a Perl Test::More script inside a test, and --verbose-log records that script's own "ok 1 ..." lines in the .out file next to git's -- two numberings in one stream. Read per-test results from git's own --write-junit-xml output (t/out/TEST-*.xml), which test-lib writes from its bookkeeping, not from anything a test prints; keep the .out plan line and .exit only to report scripts that die. Verified against a local v2.55.0 build: 292/292 tests on a subset including t0202, plus failure, fixed-breakage, skip-all and died-midway scripts. - git-annex: run-under.sh merged stderr into the logged pipe, so git-annex's "not enough free space ..." landed between tasty's "retrieveKeyFile:" and its "OK". Log stdout only (every suite reports there; prove's bail-out message included), leaving stderr on its own stream as before this PR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8dGtiFfZ6gRt2bWj39Qv3
The JUnit switch (fb30f8c) turned every git cell "incomplete" again: git v2.55.0 (and master) calls an undefined write_junit_xml_testcase for scripts that skip everything, so --write-junit-xml garbles their TAP and fails `make prove`. The --verbose-log .out files are no alternative either: besides nested TAP (t0202), command output without a trailing newline glues onto the next "ok N" line ("Hello Worldok 12 - ..."). bin/ci/git-prove-exec.sh is a prove --exec hook that runs each script through git's own t/run-test.sh and tees its stdout -- exactly the TAP prove parses -- to test-results/<script>.tap; the git adapter reads those with the same TAP parser as the other suites. Verified on a local v2.55.0 build over the full t0*/t1* selection CI runs: 10359/10359 test points reconcile with prove, t0202 included, plus synthetic fail / fixed-breakage / open-breakage / skip-all / died scripts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8dGtiFfZ6gRt2bWj39Qv3
Code: - Fix status.json "version": the verdict's tool version overwrote the backend version, but only on re-run cells. - Drop features nobody uses yet: `fixed-in` (and the per-adapter version scraping behind it) and `expect: flaky`. - known_issues.py is the one home of the matrix naming rules (matrix_cells: slug, label) and the cell states; update-status.py and render-report.py import them instead of re-deriving them. - Issues are an `Issue` dataclass instead of dicts with private keys; one `gotchas` entry point, staleness checked by `validate --gotchas`. - collect-results.py: adapters dispatched from a table, no unused arguments or outputs; named constants for magic numbers. - git-prove-exec.sh writes <script>.exit itself, so git's #exit rows no longer depend on --verbose-log being passed. - render-report.py owns the badge wording; render-badge.sh maps states to colours. - New scripts use usage() heredocs (CLAUDE.md rule 4). Checks: - Unit tests for the parsers (trimmed real suite output in tests/data/) and the classifier, plus known-issues validation, now run from bin/ci/run-checks.sh in the fast `checks` workflow; the separate job in test.yaml is gone. Docs: each fact kept in one place -- the job-vs-badge semantics in the README table, the per-cell output files at cell_output_dir(), test id formats in the known-issues.yaml header -- and comments cut to the non-obvious why. Unconfirmed root causes are tagged needs-triage only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8dGtiFfZ6gRt2bWj39Qv3
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Most of the matrix is red for reasons we already understand. That hides new failures inside an already-red cell, and nothing notices when a known failure goes away (e.g. a git-annex daily build that fixes something). This PR records known failures per test and judges each cell against that list.
How a cell is judged
passingfailing (known), still redN new failingincomplete+N fixed?appendedWhat's in it
evals/replaces.github/as the home for these files.evals/matrix.yaml(moved from.github/) says what runs. The newevals/known-issues.yamlrecords what is expected to fail. Each issue has an id, backend globs × targets, test ids (with prove-style ranges likechown/00.t#107-108,118-120, or"*"for a whole cell not yet narrowed down),expect: fail|flaky, tags from a validated list (fs-limitation,fs-divergence,test-assumption,build-config,harness,fixed-upstream,needs-triage, …), an optionalfixed-in, and links. The initial list comes from run 36050917994.bin/ci/collect-results.pyturns each suite's own output into per-test results:test-results/<script>.tapby a small prove--exechook (bin/ci/git-prove-exec.sh) that wraps git's ownt/run-test.sh;prove -v, now the default) and stress-ng (the driver now prints TAP lines);git annex test. Upstream TODO for a TAP log: provide TAP protocol logging for 'annex test'.Each parse is cross-checked against the suite's own totals and exit code. A mismatch makes the cell incomplete (red), so a parser that drifts after a format change cannot silently drop failures.
bin/ci/known_issues.pyhas four subcommands:validatechecks the YAML against the matrix;checkjudges one cell and writesverdict.json, a step summary, and annotations;gotchasregenerates GOTCHAS.md's "Known issues" section, which replaces the hand-keptKNOWN_REDlist;draftprints issue stubs for new failures.Workflow (
test.yaml):continue-on-error, andbin/ci/check-cell.shdecides the job result.results.tsvandverdict.jsongo into the per-cell artifacts.update-status.pyandrender-report.pyshow states, which issues matched, new failures, and a Known-issues section.Shellcheck:
bin/ci/shellcheck.shfinds scripts by shebang, the same discovery as improveit'sshellcheckit, instead of a fixed glob. Master'schecksworkflow runs it viarun-checks.sh shellcheck. All 25 scripts are clean.Findings from building the initial list
git-remote-annex exporttree) that fail with a busy-device error on rename, identical on 7.4.6 and 8.1.0. Taggedbuild-config,fixed-upstreamandneeds-triage: the OsPath build is the working hypothesis.annex.diskreserve, so many tests log "not enough free space". This is recorded as a whole-cellharness+needs-triageissue and not fixed here. Until the image is enlarged or the reserve lowered, the ext4 control row can't catch a git-annex regression.Review
Three independent reviews covered the Python parsers and classifier, the shell and workflow wiring, and the data and docs. All findings were addressed in 539c110, including:
(Wstat:column, which meant no#exitrows were ever produced;not ok;What real CI runs caught
The cross-checks did their job: each problem marked the affected cells incomplete (red) rather than hiding a failure.
--verbose-log.outfiles): t0202 runs a Perl Test::More script, which adds a second TAP numbering to the.outfile. Command output lacking a trailing newline also glues onto the next result line (Hello Worldok 12 - …).--write-junit-xml): git v2.55.0, and still master, calls an undefinedwrite_junit_xml_testcasefor scripts that skip everything. That garbles their TAP and failsmake prove.t0*/t1*selection CI runs, all 10,359 test points reconcile with prove, t0202 included. It also handles synthetic scripts that fail, fix a known breakage, keep a known breakage, skip everything, or die midway.pjdfstest
-v(including vfat's bail-out) and the stress-ng TAP worked on the first run. Any failures the initial list missed will show up as named "new failures" in the step summary;known_issues.py draftprints stubs for them.Testing
fixed-in, timeout, never ran, exit-code/parse disagreement) were exercised on synthetic input.bin/ci/run-checks.sh(shellcheck + bats), codespell, andknown_issues.py validate --gotchaspass.🤖 Generated with Claude Code
https://claude.ai/code/session_01P8dGtiFfZ6gRt2bWj39Qv3