-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
POC: lightweight subprocess isolation via pcntl_fork() #5751
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5751 +/- ##
============================================
- Coverage 90.13% 89.78% -0.36%
- Complexity 6631 6679 +48
============================================
Files 697 701 +4
Lines 20026 20175 +149
============================================
+ Hits 18051 18114 +63
- Misses 1975 2061 +86 ☔ View full report in Codecov by Sentry. |
Keep in mind that isolation is more important than performance. I mention this because I do not know how much global state (included files, declared constants, loaded classes, global variables, ...) carries over from the parent process into the child process when forking is used. |
In my understanding the goal of process isolation is to isolate the tests from each other. Is it also the goal to isolate phpunit from the test? |
No. |
perf comparison this PR fork@1dc7b80:
vs. main-branch@4303b9eb2
POC looks 7-8x faster |
src/Framework/TestRunner.php
Outdated
|
||
$test->setInIsolation(true); | ||
try { | ||
$test->run(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I need to check $runEntireClass
at this point and run only a single method. not sure how yet.
(in a similar way it is done in runInWorkerProcess()
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One problem with pcntl_fork()
is database connections. If the parent process has a connection to MySQL/PostgreSQL/etc, the child process will inherit that resource. When the child exits, the connection will be automatically closed, which means subsequent children will receive connection errors. More details at https://www.php.net/manual/en/function.pcntl-fork.php#70721
If a test creates a resource which needs isolation, said test needs to run in isolation. As soon as a single test runs in the main process with something which has sideeffects on other tests, things break. But thats not unique to forking. You have the same problem with worker processes, as soon as the test which requires isolation runs not in a worker |
@staabm You're correct that the current process-based isolation mechanism (which uses You could prevent breaking backwards compatibility by making this opt-in using a new config option or attribute, but this is a pretty big footgun. |
I see. Thanks for mentioning. I guess if this PR propsal will land, we will definitely need a opt-in until we get some decent real world battle test experience |
No problem. I'm happy to run any proposed changes on our codebase, which make heavy use of process isolation and would greatly benefit from any performance benefits. I came across this while doing my own research on optimizing such tests, but unfortunately I haven't found anything that helps without major caveats. |
8219df7
to
a47ff12
Compare
I have just added annotation support, so one can opt-in to fork based isolation via attribute. example test which uses fork based isolation:
the tbh I don't like bool attribute parameters, but I found it would be consistent with other attributes. this PR is also missing some more end-to-end tests, but I wanted to discuss the UX and design before going into full test-coverage I am open for feedback |
@sebastianbergmann any feedback on #5751 (comment) ? |
No new annotations are added since PHPUnit 10 came out.
I am not sure whether I like the boolean flag, I think I would prefer a separate attribute for this. Don't worry, I would implement the attribute and metadata-related changes after merging this. I think we should resolve #5230 / #5233 before working on this, though. What do you think? |
@staabm Heads-up: I have cleaned up the code a bit:
|
thanks for the groundwork. I am planning to bring this pctnl based process isolation into phpunit, if we find a way which is acceptable for you. I think it can be really useful to have a faster isolation alternative. |
Okay, then I'll try to find time ASAP to make this pluggable. I already how to do it, just need to do it. |
thanks. no hurry. pcntl based isolation is not a blocker for me... its just one item on my bucket list to make the world a bit better :-) |
As of 191477f, |
thx for your work. I tried rebasing the PR, but I am not sure yet, whether we have all pieces in the I need a way to run the job in the current process like I did in but it seems |
I doubt that you are missing something. The |
in a after forking
all the above - forking, main and child logic - would happen within the |
still work in progress..
refs #5749 (comment)