Foundation for native parallel test execution#6753
Draft
sebastianbergmann wants to merge 4 commits into
Draft
Conversation
Extract a RunningJob handle that splits process spawning (proc_open()) from reaping (proc_close()), so that a single thread of control can drive several worker processes concurrently via stream_select(). JobRunner::run() keeps its existing synchronous behavior. A new JobRunner::start() spawns a long-running process whose standard input stays open as a control channel.
Generalize process isolation into a worker that boots PHPUnit once and then runs an arbitrary number of tests, each in response to a command on its control channel. Results are transported back using the same serialized envelope as process isolation, so ChildProcessResultProcessor reconstitutes them unchanged. Tests run by one worker share a process and therefore do not get per-test global-state isolation.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6753 +/- ##
============================================
+ Coverage 97.66% 97.67% +0.01%
- Complexity 8967 9011 +44
============================================
Files 881 883 +2
Lines 27551 27707 +156
============================================
+ Hits 26907 27063 +156
Misses 644 644 ☔ View full report in Codecov by Harness. |
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.
These are the first steps towards native parallel test execution in PHPUnit. Rather than introducing a new subsystem, this pull request generalizes the existing process isolation implementation which already runs a test in a separate process and faithfully reconstitutes its outcome in the parent, from "one synchronous child per test" toward "many concurrent, reusable workers."
This PR does not wire anything into the CLI. There is no scheduler, worker pool, or
--paralleloption here. Sequential execution remains the only behavior a user can trigger, and process isolation is unchanged.What's included
1.
JobRunnermade async-capable (src/Util/PHP/)RunningJobhandle that separates spawning (proc_open) from reaping (proc_close). It exposesreadableStreams()+ non-blockingconsume()so a single thread of control can multiplex several worker processes through onestream_select()loop, plus a blockingwait()for the synchronous case.JobRunner::run()is reimplemented on top of this split and is behaviorally identical to before.JobRunner::start()spawns a long-lived process whose stdin stays open as a control channel, the building block for the worker (and a future pool of workers).2. Persistent worker (
src/Runner/Parallel/)PersistentWorker+templates/worker.tpl: boots PHPUnit once, then loops reading newline-delimited JSON commands from its control channel, running each test via the sameinitForIsolation()event-collection path that process isolation uses, and writing the existing nonce-prefixed result envelope to a file.ChildProcessResultProcessor, so events, results, assertions, and code coverage reconstitute exactly as they do under process isolation. A worker that dies mid-test is reported as an error.Design notes / trade-offs
PassedTestsis shipped cumulatively, which is harmless because its import is idempotentproc_open()+stream_select()only, so there is no new runtime requirement beyond what process isolation already needs