Problem/Motivation
run-tests.sh spawns subprocesses of itself, each one then running a single PHPUnit test class via PHPUnit, which itself spawns suprocesses for each test to be run in isolation. Maybe we can skip one level and let the main run-tests.sh process directly spawn PHPUnit subprocesses.
Done:
- #3497431: Deprecate TestDiscovery test file scanning, use PHPUnit API instead
- #3418267: Support PHPUnit 11 in Drupal 11
- #2905007: Allow run-tests.sh to report skipped/incomplete PHPUnit tests
- #3485069: [CI] Spin off Drupal Components tests in a job of their own, add test coverage metrics
Proposed resolution
- Make the 'main'
run-tests.shdirectly spin PHPUnit CLI subprocesses. - Adjust
PhpUnitTestRunnerin order to allow it to run the spawned subprocesses asynchronously, so to supportrun-tests.shconcurrency.
All @internal code refactoring.
Notes on related issues
This issue is blocking #3536964: run-tests.sh - segregate command line parsing and use Symfony Console classes, which itself is blocking #3549601: Allow --directory and @group to work together in run-tests.sh which is an important feature for contrib testing, because @group often fails during Test Discovery for errors introduced in the changes at core 11.2.
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Issue fork drupal-3515347
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3515347-reduce-run-tests.sh-complexity
changes, plain diff MR !11622
Comments
Comment #3
mondrakeComment #4
mondrakeComment #5
mondrakeComment #6
mondrakeComment #7
mondrakeComment #8
mondrakeComment #9
mondrakeAll blockers are in. Will be working on this one.
Comment #10
mondrakeComment #11
mondrakeComment #12
mondrakeComment #13
smustgrave commentedAppears to have merge conflicts
If you are another contributor eager to jump in, please allow the previous poster(s) at least 48 hours to respond to feedback first, so they have the opportunity to finish what they started!
Comment #14
mondrakeYes needs waiting for https://www.drupal.org/project/drupal/issues/3497431
Comment #15
mondrakeUnblocked, rebased.
Comment #16
smustgrave commentedRecommended way for testing?
Comment #17
mondrake#16 this is refactoring internal code, and no outside effects are expected. The only suggestion I would have is to compare test result logs from run-tests.sh, in core and contrib, before and after the change. They should be the same.
Comment #18
smustgrave commentedleft a comment on the MR but leaving in review for additional eyes,
Comment #19
mondrakegood catch. on that
Comment #20
mondrakeAdjusted the docblocks.
Comment #21
mondrakeSince run-tests.sh is no longer spawning subprocesses of run-tests.sh itself, we no longer need to persist the test result SQLite database on disk to allow parent-child processing. So, we can try using a
:memory:SQLite database within the main run-tests.sh process.Comment #22
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #23
mondrakeComment #24
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #25
mondrakerebased
Comment #26
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #27
mondrakerebased
Comment #29
jonathan1055 commented96 commits behind, tried to rebase, but needed a merge. It was all clean, no conflicts.
Updated IS with notes on the related issues.
Comment #30
mondrakeComment #31
smustgrave commentedAppeared to break phpstan?
Comment #32
mondrake#31 strange... fixed now.
Comment #33
longwaveCan we just default to
--sqlite :memory:now, but keep the switch in case anyone wants to inspect the database later?Comment #34
mondrakeSure, on that.
Comment #35
mondrakedone #34
Comment #36
mondrakeNeeds some tuning.
Comment #37
mondrakeWe cannot do #33, because undefined
--sqlitecurrently means "use the installed database". So latest commits fail Kernel tests because they try inserting into the SUT db and not on the test runner db.Comment #38
mondrakeComment #39
mondrakeneeds reroll
Comment #40
mondrakesolved merge conflicts
Comment #41
smustgrave commentedNot sure how to test this one :( but the pipeline is all green, let me see if I can get someone.
Comment #42
mondrakesee #17 for testing
Comment #43
smustgrave commentedSorry which logs do you mean? And not sure how to test contrib
Comment #44
mondrakeFor core, go to the MR, select Pipelines, then the first on the list, then pick one of the jobs. For instance, pick the DEFAULT child pipeline, then the first Kernel test job. This sequnce leads to https://git.drupalcode.org/issue/drupal-3515347/-/jobs/7716054.
This is the ‘job log’. You compare that with the one resulting from the same sequence in the HEAD branch, for instance the one running Daily.
For contrib, you need to run on a local environment tests for a module via run-tests.sh before and after applying the MR. See https://www.drupal.org/docs/develop/automated-testing/phpunit-in-drupal/...
Comment #45
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #46
mondrakeupdated fork
Comment #47
jonathan1055 commentedFor Contrib testing, I will try to use this MR as a patch in a Gitlab Templates CI pipeline. This does not replace the suggestion in #44, it's an extra. I am interested in getting this done, to unblock #3549601: Allow --directory and @group to work together in run-tests.sh
Comment #48
mondrakeComment #49
jonathan1055 commentedFollowing up my comment in #47 I have now tested this MR in a Contrib pipeline, which has quite a few phpunit tests, split over 6 parallel matrix streams. The patching worked on
run-tests.shok (ignore the fact that it failed on a few of the test files modifed here).https://git.drupalcode.org/issue/scheduler-3356800/-/jobs/8141884#L201
The tests ran, exactly as before. The log output is identical except for some formatting around
The new long line shows that it is running the modified run-tests.sh, because that is one of the changes in the patch. It is nice to see visible proof, to confirm that.
I know that running time was not the primary aim of this MR, but on a sample of one pipeline before and one after, five of the six parallel test groups were faster in the newer version, ranging from 5% to 14% quicker over tests taking 2 mins to 11 mins. One test was slower but this was 30s to 35s so not actually significant. This is only a sample of one, so not statistically definitive, but it is good. At least it seems that the modified script is producing the same outcomes as before
Comment #50
mondrakeThanks for #49.
Since each test class requires one less subprocess to be spawned, and a subprocess initiation can take up to 0.2 seconds (roughly), yes there can be some performance improvements. Especially in runs of many test classes whose individual execution time is small (typically, unit tests). Kernel and Functional test have quite some overhead of its own so it’s less visible there.
Comment #51
jonathan1055 commentedJust in case anyone else would like to try the same as I did on their contrib project, here is the
phpunit: before_scriptcustomisation I used.Comment #52
mondrakeComment #53
dcam commentedI did my best to study the code since I've never looked at it before. I found a few things and commented on them in the MR. I'm mostly setting the status to Needs Work because I think I found the potential for a fatal error with that
$testClassproperty.Comment #54
mondrakeThanks for diving into this code @dcam. Addressed your comments.
Comment #55
dcam commentedI diffed most of the tests from this MR versus another simple MR that I worked on today. There was effectively no difference between them, which I think is the point. For the most part, all the tests ran (or at least were reported) in the same groups in the exact same order. The Unit test (Core) summary sections showed the classes in different orders, but the details results sections were the ordered the same. I don't know if that's typical or not.
Anyway, it looks to me like all the tests are still running exactly as they should be after the change. I'm going to RTBC it.
Comment #56
mondrakeWell the order in the summary section depends on the efficiency of the parallelization (as reported in #49), and on the speed of the runner. Especially with unit tests that run many short lasting classes in parallel the resulting order may vary wildly. As long as the total count matches, it’s OK imho. Did not know the detailed report is comparable, good thing.
Comment #57
jonathan1055 commentedIn the MR you made the comment that PHPCS is not being run on
run-tests.shand I think the reason is that the core phpcs.xml.dist file does not include sh in the list of extensions, probably because in general .sh files are bash scripts not php. But it seems there was an attempt to include specific .sh files in the check. I don't know if this ever worked, but it certainly does nothing now, at least locally for me, because the list in "extensions" overrides any exceptions here.Maybe it is worth opening a separate issue for this? If you agree I will do that. The check can be done in a second separate call to phpcs with a custom list of extensions, if there is no appetite to add 'sh' into the extensions list in the file.
Comment #58
mondrake#57 makes a lot of sense, and yeah I think that belongs to a separate issue, thanks
Comment #59
jonathan1055 commentedI have opened #3568959: PHPCS ignores the attempt to check run-tests.sh
Also adding the meta issue as parent here.
Comment #60
catchLooks really good - net reduction in code, moves more logic out of run-tests.sh, unblocks more things later too.
Committed/pushed to main and 11.x, thanks!
Comment #65
jonathan1055 commentedThank you @catch.
Merging this has unblocked #3536964: run-tests.sh - segregate command line parsing and use Symfony Console classes