Skip to content

Compliance: a SKIPPED case is not an executed one, and not a fixed one - #24933

Merged
PurHur merged 1 commit into
masterfrom
fix/executed-set-excludes-skipped
Jul 29, 2026
Merged

PurHur merged 1 commit into
masterfrom
fix/executed-set-excludes-skipped

Conversation

@PurHur

@PurHur PurHur commented Jul 29, 2026

Copy link
Copy Markdown
Owner

The executed set added in #24835 counted skips as executions, so the very confusion it was built to prevent survived in a second form.

The bug

PHPUnit emits testStarted for a skipped case and then testIgnored. The set was built from testStarted alone. Once --SKIPIF-- started being honoured (#24888), a case that became skipped left the failing set, stayed in the executed set, and read as FIXED.

How it surfaced

The first post-SKIPIF collect — runs 30472500277 / 30472527097 at 90c654c46:

before (a3f32662b) after
failing 428 370
executed 8,112 8,121
cases that stopped executing — 0

I predicted the ~19 SKIPIF false-failures would leave the executed set. They didn't — it went up. That mismatch is what exposed the defect; the 58 cases that stopped failing were skips wearing a fix.

Fix

shard-compliance.sh     writes <suite>-<i>-of-<N>.skipped from testIgnored,
                        and .executed becomes started MINUS ignored
compliance-baseline.sh  --diff splits FIXED / SKIPPED / DROPPED / NEWLY EXECUTED

SKIPPED and DROPPED are kept apart because they are different problems: a skipped case declares itself inapplicable to this host/profile; an unyielded case was gated out by VMTest::providePHPTests(). Both are coverage losses, neither is a repair, and a skip guard that started firing wrongly would look identical to a correct one.

The zero-executed guard deliberately still keys on testStarted — it means "the filter matched nothing", and a shard whose cases all legitimately skip is not that failure.

Verified

  • real mixed teamcity log: 4 started, 2 skipped, 2 ran, 1 failed — the two skips correctly excluded from "ran"; the old logic would have called all 4 executed
  • synthetic fixtures covering all four classifications
  • degrades conservatively: with no .skipped files present, a skipped case falls into DROPPED, never into FIXED

Note

This lands ahead of merge-base diffing (the agreed next structural change), because that will consume the same set logic and it needed to be correct first.

🤖 Generated with Claude Code

The executed set I added in #24835 counted skips as executions, so the very
confusion it was built to prevent survived in a second form.

PHPUnit emits testStarted for a skipped case AND then testIgnored. The set
was built from testStarted alone, so once --SKIPIF-- started being honoured
(#24888) a case that became skipped left the failing set, stayed in the
executed set, and read as FIXED.

Measured on the first post-SKIPIF collect (runs 30472500277 / 30472527097 at
90c654c): failing fell 428 -> 370, while executed ROSE 8112 -> 8121 and
exactly ZERO cases stopped executing. The 58 cases that stopped failing were
skips wearing a fix.

  shard-compliance.sh    writes <suite>-<i>-of-<N>.skipped from testIgnored,
                         and .executed is now started MINUS ignored
  compliance-baseline.sh --diff splits FIXED / SKIPPED / DROPPED / NEWLY
                         EXECUTED

SKIPPED and DROPPED are kept apart because they are different problems: a
skipped case declares itself inapplicable to this host/profile, an unyielded
case was gated out by VMTest::providePHPTests(). Both are coverage losses,
neither is a repair, and a skip guard that started firing wrongly would look
identical to a correct one.

The zero-executed guard deliberately still keys on testStarted: it means "the
filter matched nothing", and a shard whose cases all legitimately skip is not
that failure.

Verified on a real mixed teamcity log (4 started, 2 skipped, 2 ran, 1 failed
— the two skips correctly excluded from "ran"), and on synthetic fixtures for
all four classifications. Degrades conservatively: with no .skipped files a
skipped case falls into DROPPED, never into FIXED.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@PurHur
PurHur merged commit 21bf9c6 into master Jul 29, 2026
@PurHur
PurHur deleted the fix/executed-set-excludes-skipped branch July 30, 2026 00:44
PurHur added a commit that referenced this pull request Jul 30, 2026
)

The compiler gate has produced no master verdict at all. Measured over the 60
most recent runs of compiler-gate.yml:

  cancelled   31
  in flight   29
  completed    0

Every master push shared one concurrency group with cancel-in-progress, and
master takes ~12 commits/hour against a gate that needs ~25 min — so each run
was cancelled by the next merge before it could reach a conclusion. The gate
appeared to be running constantly and never reported anything.

That is the same failure as a check that reports without running, which this
repo has now hit four times (#24888 dead SKIPIF, #24726 quarantine from two
different commits, #24835 baseline that could not tell fixed from dropped,
#24933 skips counted as executions). Cancelled-forever is absence wearing a
busy spinner.

Master runs are now keyed on the SHA, so each merge gets its own verdict. PR
runs keep superseding each other on the ref, which is correct — once a branch
is pushed again the previous tree is nobody's concern.

Cost: master runs may overlap. With the paths filter (lib, ext, bin, patches,
the sweep scripts) and ~56% of commits touching lowering, that is roughly 7
runs/hour at ~25 min each, so ~3 concurrent. GitHub queues the excess.

Found while investigating why #24988 merged with a red gate. That failure was
`aot-smoke: 7 passed, 1 failed` — `echo` hitting rc=124, a 900s COMPILE
TIMEOUT under CI load, not a wrong result. Verified on current master
(e5bf674, which contains that patch): aot-smoke 8 passed, 0 failed locally,
including echo. So the red was infrastructure slowness, and master is intact —
but nobody could have known that from the gate, because it never finishes.

Co-authored-by: PurHur <tedyyyyy@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants