Problem/Motivation

Improve readibility.

Get closer to allow converting the script to a Symfony console application command.

Proposed resolution

Introduce a Configuration class, and let it do the command line arguments parsing, via Symfony Console's components.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3536964

Command icon 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:

Comments

mondrake created an issue. See original summary.

mondrake’s picture

Title: [PP-4] Change run-tests.sh to use Symfony Console classes for command line parsing » [PP-3] Change run-tests.sh to use Symfony Console classes for command line parsing
Issue summary: View changes
mondrake’s picture

Title: [PP-3] Change run-tests.sh to use Symfony Console classes for command line parsing » [PP-2] Change run-tests.sh to use Symfony Console classes for command line parsing
Issue summary: View changes
mondrake’s picture

Title: [PP-2] Change run-tests.sh to use Symfony Console classes for command line parsing » [PP-1] Change run-tests.sh to use Symfony Console classes for command line parsing
Issue summary: View changes
jonathan1055’s picture

I've not done a full review, but the first thing that struck me were the many changes from $args('the-string') to $input->getOption('the-string'). In fact there are 73 of these, and I suggest it would be more readable if the $args array was retained, and simply built by the necessary calls to $input->getOption() but doing each only once. This would also reduce the compexity of the MR, and make it possible to print the entire $args array when doing debug. But having looked now at more of the changes, maybe my idea is not so important and stick with what you have done. But the diff is massive and needs a lot of checking. I can try to use this in a Contrib pipeline to test, but I expect the Core tests are doing enough to verify it already.

mondrake’s picture

Thank you. My final idea here would be to add a separate class holding all the configuration of the test runner - mimicking somehow what PHPUnit or Paratest are doing. That would include processing of the CLI arguments but also of the ENV varaibles that right now is spread in many places. But that would be even bigger change... so here it's a transitional state.

Anyway... sorry to bump you across the issue hierarchy, but #3515347: Reduce run-tests.sh complexity in spawning subprocesses would need to be done prior than this as that one will remove some of the CLI arguments and make this one simpler.

mondrake’s picture

Issue tags: +run-tests.sh
mondrake’s picture

Issue tags: +PHPUnit 11
mondrake’s picture

Title: [PP-1] Change run-tests.sh to use Symfony Console classes for command line parsing » [PP-1] run-tests.sh - segregate command line parsing and use Symfony Console classes
Issue summary: View changes
jonathan1055’s picture

Adding to meta parent

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

jonathan1055’s picture

Title: [PP-1] run-tests.sh - segregate command line parsing and use Symfony Console classes » run-tests.sh - segregate command line parsing and use Symfony Console classes
Issue summary: View changes
Status: Postponed » Needs work

Unblocking this, now that #3515347: Reduce run-tests.sh complexity in spawning subprocesses has been done. Thanks for workig on that one, it's good to have some progress.

mondrake’s picture

Status: Needs work » Needs review
jonathan1055’s picture

From #7

"#3515347: Reduce run-tests.sh complexity in spawning subprocesses" would need to be done prior ... as that will remove some of the CLI arguments and make this one simpler.

Is that what the most recent commit does?

I will also use this MR in a contrib test, but as I said in #6 if the Core tests run OK then that's probably enough?

mondrake’s picture

Issue tags: +Needs manual testing

Nope - it's diluted in the rest of the MR, and the merge swallowed the change. The change that happened in #3515347: Reduce run-tests.sh complexity in spawning subprocesses was that the internal --test-id and --execute-test options were removed, so we no longer have to take care of them in the MR here.

Actually I think there's other code that may be dead now, will try to check on it later today. But I assume that won't change the essence of the MR here.

Testing in contrib would be great - maybe it could be tested also in combination with using the --sqlite ":memory:" argument that was introduced in the parent.

Also some manual testing would be good - in CI contexts this is probably doing what expected, but the script itself has other options like --list, --list-files, --help etc etc. I did try myself and all seems to work OK, but the script here has no test coverage so one more hand would help.

jonathan1055’s picture

StatusFileSize
new547 bytes

I've tested this in a Contrib CI pipeline, using the diff from this MR to patch run-tests.sh. If anyone else would like to use this I have attached the addition for your .gitlab-ci.yml file. I think it needs to be used in the 'next minor' variant, which runs 11.4-dev as the patch might not apply in 11.3.2

Here's the pipeline, running one functional test, one functional javascript and one kernel test
https://git.drupalcode.org/issue/scheduler-3356800/-/pipelines/727371

I've compared the three logs with the regular non-patched version, and they are identical in output. The only change we see is that the php binary is now shown as /usr/bin/sudo wheras before it was /usr/local/bin/php

--------------------------------------------------------------
Drupal Version.......: 11.4-dev
PHP Version..........: 8.3.30
PHP Binary...........: /usr/bin/sudo
PHPUnit Version......: 11.5.50
PHPUnit configuration: /builds/project/scheduler/web/core
Database.............: MySQL, Percona Server, or equivalent
Database Version.....: 8.0.44
Working directory....: /builds/project/scheduler/web
--------------------------------------------------------------

I have also run it with the addition of --sqlite ":memory:" as requested.
Pipeline https://git.drupalcode.org/issue/scheduler-3356800/-/pipelines/728118 shows it is used in the command here. Again the three output logs are identical to before.

mondrake’s picture

#17 you may want to remove --php "/usr/local/bin/php" from the run-tests.sh command line. This is now irrelevant (I also marked it deprecated in the MR here), independently from this issue. Passing a PHP executable path was relevant before #3515347: Reduce run-tests.sh complexity in spawning subprocesses because that one PHP executable was used to spawn sub-processes of run-tests.sh itself. Since the commit of the parent this is no longer happening (run-tests.sh spawns PHPUnit CLI sub-processes directly), so the option and its processing is just dead code now, that this MR is removing.

mondrake’s picture

Assigned: Unassigned » mondrake
Status: Needs review » Needs work

Anyway,

PHP Binary...........: /usr/bin/sudo

in the initial output feels rather wrong, even if it's there just as info at this point. It's pointing to the sudo path under which the script is being run in the CI context, not the path to the actual PHP binary.

Maybe we can use PhpExecutableFinder from symfony/process to give us more accurate info.

mondrake’s picture

Assigned: mondrake » Unassigned
Status: Needs work » Needs review

Now using PhpExecutableFinder from symfony/process to determine PHP's executable path.

jonathan1055’s picture

Thanks for the info. The Gitlab CI job has --php "$(which php)" in the command line when executing run-tests.sh, so it sounds like this is redundant with this new chnage?. This part of the job template is used for all variants, so it may be the case that we leave it in for now, because these run-tests changes won't be back-ported to Drupal 10. Or we could check the core version and add that snippet conditionally, which might be a better solution.

I've tested the updated MR, and also removed the --php parameter, and now we get back the original
PHP Binary...........: /usr/local/bin/php
https://git.drupalcode.org/issue/scheduler-3356800/-/jobs/8289782#L593

mondrake’s picture

The Gitlab CI job has --php "$(which php)" in the command line when executing run-tests.sh, so it sounds like this is redundant with this new chnage?

Yes - the option is still accepted, but its a no-op.

now we get back the original
PHP Binary...........: /usr/local/bin/php

The endgame is the same, but behind the scenes it's no longer the input resulting from --php "$(which php)", it's the output of PhpExecutableFinder::find().

jonathan1055’s picture

StatusFileSize
new1.36 MB
new2.23 MB

The endgame is the same, but behind the scenes it's no longer the input resulting from --php "$(which php)", it's the output of PhpExecutableFinder::find()

Yes, that is what I meant. All's good.

You also asked for manual testing of --list and --list-files. They both give the results for all tests in all modules, as intended. But adding --directory=modules/mymodule does not reduce the output, we still get everything. This is not only very slow, but also (as reported elsewhere too) if any other 3rd-party contrib project causes deprecations due to missing classes, then the whole command fails. It would be great to have --directory= not ignored in these cases. But maybe that work will be done in #3549601: Allow --directory and @group to work together in run-tests.sh next, after this issue.

The --help formatting is greatly improved. Much better use of the screen give more info without scrolling. I have also checked the text changes, and apart from moving some options, and the extra info such as defaults, these are the differences:

  • new options --phpunit-configuration and --ci-parallel-node-total
  • deprecated --php
  • in --sqlite, removed:
    Note that ':memory:' cannot be used, because this script spawns sub-processes. However, you may use e.g. '/tmpfs/test.sqlite'
  • file option - removed the text This argument must be last on the command line.

So that all looks good.

smustgrave’s picture

@jonathan1055 would you say this one is ready?

jonathan1055’s picture

Status: Needs review » Needs work

I have done the Contrib testing, both in Gitlab pipelines and locally, and all seems OK. However, I don't pretend to understand the actual coding changes that Mondrake has made. I am assuming that if the core tests run, and contrib too, then in principle it is working.

Just a couple of points:

  1. From the discussison in #6 and #7 it would be good to get that follow-up issue created and linked from here.
  2. In #16 Mondrake said: "I think there's other code that may be dead now, will try to check on it later ..."
    It would be good not to lose sight of this. I don't know if that is a separate issue or not.
  3. I have made a couple of minor suggestions in the MR thread regarding text of the help. There were a few very long lines which wrapped and made it harder to read. I know we can't predict the terminal window size, but at least these few line-breaks will help.

NW for these things, but otherwise if Mondrake is confident then yes lets get this moving onwards :-)

mondrake’s picture

Status: Needs work » Needs review
Issue tags: -Needs manual testing

Thanks guys

#25.1 - it's done, it's the Configuration class introduced in https://git.drupalcode.org/project/drupal/-/merge_requests/12787/diffs?c... and then tuned later

#25.2 - it's done, in https://git.drupalcode.org/project/drupal/-/merge_requests/12787/diffs?c..., the --php option and finding the PHP executable is no longer necessary

#25.3 merged the suggestions

edit - removed the 'Needs manual testing' tag given the extensive tests done by @jonathan1055

jonathan1055’s picture

Thanks for the info and commit links, and for adopting my suggestions. The help looks good now.

I had not tested the --class option before, so now have done that. Two small observations

  1. I found that using just the final class name was not enough, it needs the full path. For example --class MigrateSchedulerDataTest fails to find the class, but --class 'Drupal\Tests\scheduler\Kernel\MigrateSchedulerDataTest' does work. If this is intended then maybe the help should state that?
  2. I also found that quotes are required around the class, which is OK, but the example in the help does not show quotes. Quotes are not needed when using the --file option. I've made a MR suggest for this.

Then let's call this RTBC. I presume it is only for 'main' and 11.x, so will affect 11.4.x but not 11.3.x ? Just want to know what audience this could impact if any problem has not been noticed.

mondrake’s picture

#27.1 this MR is not changing that behavior. Clarified that FQCNs must be indicated.

#27.2 I do not think quotes are necessary, rather blackslashes need to be escaped on the command line (i.e.
php ./core/scripts/run-tests.sh --url http://example.com/ --class Drupal\\Tests\\block\\Functional\\BlockTest
is ok,
php ./core/scripts/run-tests.sh --url http://example.com/ --class Drupal\Tests\block\Functional\BlockTest
is not. Also added a comment for that.

Finally, replaced text that indicated @group annotations with the new #[Group()] attributes instead. See #3556580: Remove remaining references to @group annotations from tests.

jonathan1055’s picture

Status: Needs review » Reviewed & tested by the community

Thank you for the clarifications in the help. Yes you are right, quotes are not specifically required, that was just my first attempt at solving it and it worked. But backslahes also work, so it's good you have that in the help.

I will be brave and mark this RTBC, but I really do not know if we've tested every option. I guess that may become apparent if things break.

Do you have a plan for which branches this will be merged into? re my last question on #27.

[edit: the last addition to help needs a linebreak. I have added that in a MR suggestion]

mondrake’s picture

Related issues:

#27/#29 that's a call for core committers. A related issue #3515347: Reduce run-tests.sh complexity in spawning subprocesses was committed to main and 11.x, I would be surprised if this one would get any further.

jonathan1055’s picture

I would be surprised if this one would get any further.

Good, that's what I was expecting.

longwave’s picture

Status: Reviewed & tested by the community » Needs work

Added some question/feedback, it's hard to know where we are done here, ideally one day this will be a fully fledged class implementation of a console command and this is a good step on the way.

mondrake’s picture

Status: Needs work » Needs review

Addressed @longwave feedback (thanks!) apart one point I was unclear about.

mondrake’s picture

We may want to move parts of simpletest_script_init() to the new Configuration class, but I would do that in a follow-up. I was already thinking we need to manage config keys independently from the args/options coming from the CLI - and enable configuration via a yml file.

longwave’s picture

Status: Needs review » Needs work

I read the docs and I think we can set the defaults once, see MR comments.

mondrake’s picture

Status: Needs work » Needs review
mondrake’s picture

OK, but if you do specify the option, without then indicating a value, it's a failure. So now the Build job fails because it does not indicate a parallel key and the corresponding $CI_NODE_INDEX and $CI_NODE_TOTAL env variables are missing so from the CLI there is no value associated with the option. It's a bug that we can fix adding the vars explicitly, but may impact scripts out there in the wild.

mondrake’s picture

Status: Needs review » Needs work

Needs to figure out what to do.

longwave’s picture

I think that's fine, it feels like an error to specify the option without a value anyway?

mondrake’s picture

Status: Needs work » Needs review
mondrake’s picture

Assigned: Unassigned » mondrake
Status: Needs review » Needs work

I see failures when run locally, working on it.

mondrake’s picture

Assigned: mondrake » Unassigned
Status: Needs work » Needs review

The local failures are unrelated - that will be another issue. Rebased and back to NR.

mondrake’s picture

rebased

longwave’s picture

This is interesting because it might converge with #3453474: CLI entry point in Drupal Core soon...

mondrake’s picture

#45 yes!

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new1.27 KB

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. 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.

mondrake’s picture

Status: Needs work » Reviewed & tested by the community

rebased

amateescu’s picture

Status: Reviewed & tested by the community » Needs review

Reviewed the MR, found a bug and a minor improvement that can be ignored if not desired. Feel free to self-RTBC afterwards.

mondrake’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, done as suggested and actually made the help text be displayed when no arguments are in the command line. Self-RTBCing per #49.

  • amateescu committed afcf2016 on main
    feat: #3536964 run-tests.sh - segregate command line parsing and use...
amateescu’s picture

Status: Reviewed & tested by the community » Fixed

Committed afcf201 and pushed to main. Thanks!

Not sure whether this one should go into 11.x as well. I see that the related issues were backported, so I'll ask around.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

amateescu’s picture

Version: main » 11.x-dev
Status: Fixed » Patch (to be ported)

Discussed with release managers and we think it should be backported to 11.x.

mondrake’s picture

Status: Patch (to be ported) » Needs review

11.x port.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Seems like a good rebase.

amateescu’s picture

Status: Reviewed & tested by the community » Fixed

Committed 45c8034 and pushed to 11.x. Thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

longwave’s picture

Status: Fixed » Reviewed & tested by the community

Looks like the push didn't make it to 11.x.

  • amateescu committed 45c80347 on 11.x
    feat: #3536964 run-tests.sh - segregate command line parsing and use...
amateescu’s picture

Status: Reviewed & tested by the community » Fixed

Oops :)

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

jonathan1055’s picture

Thank you for porting this back to 11.x. It is used in the 'Next Minor' Gitlab pipeline varaint, which uses 11.4-dev, so the changes will get used and tested for real.

I did notice something in the help, which might be a typo, or it might be my mis-understanding. The help for --suppress-deprecations says

Stops tests from failing if deprecation errors are triggered. If this is not set the value specified in the SYMFONY_DEPRECATIONS_HELPER environment variable, or the value specified in core/phpunit.xml (if it exists) will be used. The default is that any unexpected silenced deprecation error will fail tests.

In that last line, should it be "any unexpected unsilenced deprecation error will fail tests". If the deprecation is silenced then I would not want the test to fail. It's the unsilenced ones that we need to be alerted of. At least, that's my understanding. Please correct me if I'm wrong.

mondrake’s picture

#66 assuming that we mean

silenced deprecation === @trigger_error(..., E_USER_DEPRECATED);, and
unsilenced deprecation === trigger_error(..., E_USER_DEPRECATED);

then I think that currently that does not make any difference in PHPUnit 12. This is somehow a text that dates back to when the Symfony PHPUnit bridge was in and deprecation reporting was managed there.

What the option does now is managed in PhpUnitTestRunner::prepareCommand(), and how this interacts with the PHPUnit CLI command spawned by run-tests.sh:

--suppress-deprecations is specified => PHPUnit CLI is spawned with env variable 'SYMFONY_DEPRECATIONS_HELPER' = 'disabled' and NO fail switches for failing on deprecation. This essentially means deprecations may be reported in raw logs, but they are not failing the test overall.

--suppress-deprecations is NOT specified => PHPUnit CLI is spawned with env variable 'SYMFONY_DEPRECATIONS_HELPER' inheriting from parent, and with --fail-on-deprecation and --fail-on-phpunit-deprecation fail switches specified. This essentially means deprecations lead to test failure UNLESS they are ignored by the patterns in the .deprecation-ignore.txt indicated by the SYMFONY_DEPRECATIONS_HELPER variable.

To complicate things:

  • SYMFONY_DEPRECATIONS_HELPER is disabled and --suppress-deprecations is NOT specified: this means ALL deprecations are failing tests;
  • PHPUNIT_FAIL_ON_PHPUNIT_DEPRECATION env variable is set to TRUE and --suppress-deprecations is NOT specified: this means PHPUnit own deprecations (those that PHPUnit itself is throwing) are not failing tests.

We probably need to sort this out a bit - the confusion IMHO is driven by the fact that PHPUnit's options are positive (i.e. need to be set to FAIL tests) whereas run-tests.sh one is negative (i.e. needs to be set to PASS tests).

EDIT - sorry I was initially swapping silenced with unsilenced

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.