Skip to content

[Testing] Use fresh single-file source locator under PHPUnit to avoid stale reflection - #8464

Merged
TomasVotruba merged 1 commit into
mainfrom
harness-fresh-source-locator
Sep 5, 2026
Merged

[Testing] Use fresh single-file source locator under PHPUnit to avoid stale reflection#8464
TomasVotruba merged 1 commit into
mainfrom
harness-fresh-source-locator

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Problem

Rule tests write each fixture to a throwaway temp file and delete it in tearDown(). The shared OptimizedSingleFileSourceLocatorRepository caches single-file locators by path for the whole worker and never evicts them. So a stale locator for a since-deleted fixture file can leak into a later test that runs in the same parallel worker.

Because fastunit groups tests into worker chunks by weight, whether this bites depends on how the chunks fall out - adding or removing test classes reshuffles the grouping. That makes it an intermittent, order-dependent failure: a test can go red not from its own change but from what it happens to share a worker with.

It reproduces reliably at a low worker count (matching CI's core count):

vendor/bin/fastunit -p 4 tests rules-tests utils/phpstan/tests

The symptom is a rule that resolves reflection (e.g. a parent property) suddenly seeing incomplete data - the parent property becomes invisible and the expected change is not applied - accompanied by hash_file(... /Fixture/fixture.php): Failed to open stream: No such file warnings from the stale locator.

Fix

Under PHPUnit, build a fresh single-file locator via OptimizedSingleFileSourceLocatorFactory::create() instead of the cached getOrCreate(). Production keeps the cached repository, where files are stable and caching is a performance win. The isPHPUnitRun guard already exists in provide() for the aggregate locator; this extends the same reasoning to the single-file locators.

Validation

Full suite green across worker counts that previously failed:

  • vendor/bin/fastunit -p 4 … -> OK
  • vendor/bin/fastunit -p 3 … -> OK

composer check-cs, composer phpstan, and composer rector pass on the changed file.

… stale reflection

Fixture files are written to throwaway temp paths and deleted in tearDown.
The shared OptimizedSingleFileSourceLocatorRepository caches locators by
path for the whole worker and never evicts them, so a stale locator for a
since-deleted file can leak into a later test running in the same parallel
worker. Depending on how fastunit groups tests into worker chunks, this
surfaces as an order-dependent reflection failure (e.g. a parent property
becoming invisible), reproducible with a low worker count such as -p 4.

Build a fresh locator per run under PHPUnit; keep the cached repository in
production where files are stable.
@TomasVotruba
TomasVotruba merged commit 8b1c4e2 into main Sep 5, 2026
43 checks passed
@TomasVotruba
TomasVotruba deleted the harness-fresh-source-locator branch September 5, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant