Problem/Motivation
In #2927806: Use PHPUnit 6 for testing when PHP version >= 7.2 we introduced a method to install PHPUnit 6 if you run composer install when you have PHP7.2 and dev dependencies installed. This is because the current locked version of PHPUnit 4.8 is not compatible with PHP 7.2. The way this works is by triggering a post install command that can run a composer upgrade command. I think this is exceptionally risky. It means that we change the root composer.lock file on a composer install which is very very unexpected.
Proposed resolution
- Don't do anything automatically on composer install.
- If a user runs tests via run-tests.sh try to update to PHPUnit 6 if the PHP Version >= 7.2 if not successful exit and tell user about the problem.
- If the user runs via ./vendor/bin/phpunit ensure the correct version of phpunit is being used.
Also considered was a solution similar to Symfony's where a completely separate version of phpunit is downloaded outside of vendor. We can't do this without removing PHPUnit as a dependency. This is because the PHPUnit classes Drupal's autoloader has access to would still be the 4.8 ones so this would be a complete mess.
Remaining tasks
User interface changes
None
API changes
None
Data model changes
None
Comment | File | Size | Author |
---|---|---|---|
#25 | 2937469-25.patch | 8.3 KB | alexpott |
#25 | 19-25-interdiff.txt | 944 bytes | alexpott |
#19 | 2937469-19.patch | 8.05 KB | alexpott |
#19 | 11-19-interdiff.txt | 847 bytes | alexpott |
#18 | 2937469-env-test.patch | 8.07 KB | alexpott |
Comments
Comment #2
alexpottHere's one idea. I still think we should go the Symfony route and just get a completely different PHPUnit executable when we need too. This way we won't affect the root composer.lock ever.
Comment #3
mxr576Can't we get rid of PHPUnit 4.8?
Can someone describe me why this old, unsupported PHPUnit version is the minimum required version in Drupal 8.5.x still? (I'd be thankful for a link to an issue/discussion about this. I have not found anything.)Because PHP 5.5 support :(Comment #4
alexpottComment #5
alexpottHere's a new patch that works as per the issue summary. As we can't test the failure modes this needs manual testing. One concern I have is that calling out to composer can cause errors like
This doesn't matter if not update is required. The test will run as expected but if one is the update won't work. And the user will get the message "run-tests.sh requires the PHPUnit testing framework version 6 or greater when running on PHP 7.2 or greater. Please use 'composer run-script drupal-phpunit-upgrade' to ensure that it is present."
This problem occurs because we often run tests as a different user than the one that owns the files - we normally have to run the tests as the same users running the webserver. One way we could avoid it is if we check PHP version in run-tests.sh.
Comment #7
alexpottAh we need the autoloader in place a little bit earlier.
Comment #8
alexpottAdding a check to try to determine if the composer command is going to work without emitting errors and also improved the error message. Local testing looks good for me.
Comment #9
alexpottSo the file owner trick doesn't work for DrupalCI.
Comment #10
alexpottWhat would I give for something similar to a .travis.yml file. So the approach in #9 does not work either. This should work. Ideally the testbot code would run a script provided by the package that can do things like run a composer package but we don';t have that yet.
I've also centralised the version checking to make it simpler to maintain.
Comment #11
alexpottRerolled
Comment #12
MixologicUltimately the issue here is that we need to eliminate the lockfile for core.
If you do not have control over the production platform that your software is going to run in, you should not ship a lock file.
The vast majority of users who are using composer to build sites are ignoring that lock file anyhow, because they're using scaffold templates like https://github.com/drupal-composer/drupal-project. The only time the lockfile comes into play is if they want the added safety of ensuring they're on a tested version and use https://packagist.org/packages/webflo/drupal-core-strict.
So, what, beyond minimum and maximum dependency testing, do we need to do in order to not ship with a lock file? Anything else? I can prioritize that min/max testing if it would help us get to where there is no lock file.
Comment #13
alexpott@Mixologic I totally agree. No lock file and highest / lowest dependency testing would be amazing. But we're not going to get there for 8.5.0 so rather than have the rather astonishing thing of doing a composer upgrade during a composer install I think we should just call composer upgrade from run-tests.sh under very special circumstances and inform users who run tests in PHP 7.2 what to do.
Comment #14
MixologicWhats the purpose of this block? i.e. is this really a drupalci feature request?
I'd definitely want to avoid guessing about whether or not we're on the testbot, as even that url has changed before. (also, I dont think drupaltestbot is in the dburl for sqlite)
Comment #15
alexpott@Mixologic well it kind of is a DrupalCI request. As we've talked about before core needs a way to reliably run set up commands like this prior to a test run. And we need to be able to ship changes to these commands with different releases. The problem with saying okay let's change DrupalCI to call composer run-script drupal-phpunit-upgrade-check is that this script is only available in Drupal 8.5.x and not in 8.4.x. And what happens when we add something else. Or want to remove it. This is why CI's like travis and circle CI work so well is that they allow you to change and ship these commands as your needs change. So I'd rather hack something janky into our already janky run-tests.sh that is brittle until we have a more generic way of doing these things. Because this is definitely better than what is in HEAD.
Comment #16
MixologicYou have that now, albeit "reliably" is arguable. run-tests.sh is the build script for running core's tests, and the testbots will happily execute anything thats in there. This is definitely the rightest place to put these sorts of things, despite run-tests.sh jankyness. The one caveat is that if its something that would conflict with contrib testing, then it should be configurable, such that it'd only happen for core.
My question above was more of a why are you running the drupal-phpunit-upgrade-check exclusively on the testbot, and not in all environments?
I confirmed that the sqlite url doesnt have the u:p in it:
--dburl "sqlite://localhost/sites/default/files/db.sqlite"
If you definitely need a reliable indicator that you're running in a testbot environment, I can definitely provide that directly, much like I added for the nightwatch testing: http://cgit.drupalcode.org/drupalci_testbot/tree/src/DrupalCI/Plugin/Bui...
(I should probably have that env be something like "BUILD_ENV" and use it universally)
The primary difference *there* is the poverty of being in a patch based workflow. Its hard to modify the build in a patch workflow as you almost have to double build, depending on what kinds of requirements changed. But theres nothing stopping us from doing whatever we want to the build, its just that it's always seemed like run-tests.sh was a thing we didnt want to touch.
Comment #17
alexpottWe can't run
drupal-phpunit-upgrade-check
because we can't guarantee that the test running user has permission to write files. Many users have to run tests as the user running the webserver and this user doesn't have the ability to write to vendor.Comment #18
alexpottLet's see if there are any existing env vars we can use.
Comment #19
alexpottHere's a more reliable way I think. Not as good as a specific CI variable but we could do this with a follow-up to use it once implemented.
Comment #20
alexpottAlso @Mixologic nice catch re sqlite db testing.
Comment #21
Mile23Make PHPUnit 4.8 the special case. Specify that core needs PHPUnit >=4.8 <7 (allow 4, 5, and 6). Put PHPUnit 6 in the lock file. Look for PHP versions < 7 and say composer update for those.
If we had a defined behavior for composer.json in modules, we'd be able to tell contrib to specify PHPUnit 4.8 if their tests aren't ready. But we can fake it because (IIRC) the testbot merges the facade's composer.json for the project, so it's almost the same. Contrib already has to deal with PHP 7.2+ so those projects should be updating their tests anyway.
I don't think we need to modify run-test.sh or anything, just flip the behavior of the composer script and then wait until we drop PHP <7. Then we just remove the special case from the composer script.
See also: https://github.com/sebastianbergmann/phpunit/releases/tag/7.0.0
Comment #22
Mile23Make PHPUnit 4.8 the special case. Specify that core needs PHPUnit >=4.8 <7 (allow 4, 5, and 6). Put PHPUnit 6 in the lock file. Look for PHP versions < 7 and say composer update for those.
If we had a defined behavior for composer.json in modules, we'd be able to tell contrib to specify PHPUnit 4.8 if their tests aren't ready. But we can fake it because (IIRC) the testbot merges the facade's composer.json for the project, so it's almost the same. Contrib already has to deal with PHP 7.2+ so those projects should be updating their tests anyway.
I don't think we need to modify run-test.sh or anything, just flip the behavior of the composer script and then wait until we drop PHP <7. Then we just remove the special case from the composer script.
See also: https://github.com/sebastianbergmann/phpunit/releases/tag/7.0.0
Comment #23
alexpottWe can't do #21/#22 because then
composer install
will fail in PHP 5. Also we're not going to move PHP7 to PHPUnit6 prior to 8.5.0 so can we please do this to fix the composer weirdness before 8.5.0 comes out and causes major headaches.Comment #24
catch#19 looks viable but I think we should add a @todo and a follow-up to remove it for when we drop PHP 5.5 support.
Comment #25
alexpottAdded @todos
Comment #26
MixologicWe definitely should avoid changing the results of composer.lock to avoid surprises. This is a much better way to accomplish this oddly required workaround until we can get a better system in place, and it works with the testbots as is.
LGTM.
Comment #29
catchCommitted/pushed to 8.6.x and cherry-picked to 8.5.x. Thanks!