Problem/Motivation
Two problems:
1) Unit test requires a database
Running TestSiteApplicationTest in isolation reveals that it errors out.
That's because it uses the SIMPLETEST_DB environmental variable, which is intended for use by KernelTestBase tests.
$ ./vendor/bin/phpunit -c core/ --testsuite unit --filter TestSiteApplicationTest
PHPUnit 6.5.8 by Sebastian Bergmann and contributors.
Testing
EEESS. 6 / 6 (100%)
Time: 17.01 seconds, Memory: 136.00MB
There were 3 errors:
1) Drupal\Tests\Scripts\TestSiteApplicationTest::testInstallWithNonExistingFile
InvalidArgumentException: Minimum requirement: driver://host/database
/Users/paulmitchum/projects/drupal8/core/lib/Drupal/Core/Database/Database.php:460
/Users/paulmitchum/projects/drupal8/core/tests/Drupal/Tests/Scripts/TestSiteApplicationTest.php:267
/Users/paulmitchum/projects/drupal8/core/tests/Drupal/Tests/Scripts/TestSiteApplicationTest.php:47
This can be mitigated by setting the SIMPLETEST_DB variable in phpunit.xml, but this ruins the isolation between unit and kernel tests.
2) This test is never run by run-tests.sh
Since it lives in core/tests/Scripts, the test is not discovered when run-tests.sh runs tests.
You can see evidence of this in this recent HEAD test. See the actual tests that were run which does not include TestSiteApplicationTest: https://dispatcher.drupalci.org/job/php7_mysql5.5/5506/artifact/jenkins-...
Versus the test list generated for that same build which lists TestSiteApplicationTest: https://dispatcher.drupalci.org/job/php7_mysql5.5/5506/artifact/jenkins-...
Here's an issue about fixing that discrepancy: #2878269: Modify TestDiscovery so the testbot runs all the tests
Proposed resolution
#2878269: Modify TestDiscovery so the testbot runs all the tests is in, so the test has been running.
Convert the test to the new build test framework. This takes it out of the unit testsuite, which helps avoid the need for a database. Also, this test case is much better suited to a build test which can modify the file system to perform site installs in isolation.
This includes changing \Drupal\BuildTests\Framework\BuildTestBase::executeCommand to use env variable 'COLUMNS' set to PHP_INT_MAX, so that the command output is one line. This allows assertions on the text to work as one would expect.
Remaining tasks
Review
Commit
User interface changes
API changes
Data model changes
| Comment | File | Size | Author |
|---|---|---|---|
| #118 | 2962157-118.patch | 19.57 KB | gauravvvv |
| #116 | 2962157-nr-bot.txt | 86 bytes | needs-review-queue-bot |
| #112 | 2962157-112.patch | 20.99 KB | quietone |
| #112 | interdiff-109-112.txt | 755 bytes | quietone |
| #109 | 2962157-109.patch | 21 KB | quietone |
Comments
Comment #2
alexpottLet's just mark the test skipped if it is not present. If we want to test our test infrastructure we need to allow these types of tests.
Comment #3
mile23Thanks.
This gets back to #2242947-111: Integrate Symfony Console component to natively support command line operations and #2242947-96: Integrate Symfony Console component to natively support command line operations: We really need a base class for this kind of stuff. It can't be a KernelTestBase test, but we also shouldn't reinvent the wheel every time.
Since we're normalizing on symfony/console, we could use their app tester for many things. We can also follow the example of the testbot: https://cgit.drupalcode.org/drupalci_testbot/tree/tests/DrupalCI/Tests/D...
Also, we have to be careful with the results of this patch's test runs, because we don't yet have #2905007: Allow run-tests.sh to report skipped/incomplete PHPUnit tests
But that's all out of scope here.
Comment #4
mile23OK, so the last test didn't run TestSiteApplicationTest.
But then again neither did HEAD.
That's because of the long-standing false-positive bug: #2878269: Modify TestDiscovery so the testbot runs all the tests
I only found the bug this issue addresses because I used phpunit and not run-tests.sh.
This leaves us with two options: Fix the real bug that fooled core maintainers when they committed TestSiteApplicationTest, or just move TestSiteApplicationTest to Drupal\Tests\Core\Scripts.
The patch here moves the test with a @todo about moving it back when #2878269: Modify TestDiscovery so the testbot runs all the tests is fixed.
Comment #6
mile23I can't repro the fails, so I think it's some state left over from initializing the db on the testbot.
Also, run-tests.sh can't report skipped tests so I'm left guessing if the tests passed or skipped locally when they should skip (3 seconds is a short time.. I guess.) #2905007: Allow run-tests.sh to report skipped/incomplete PHPUnit tests
Comment #7
mile23Comment #8
mile23Comment #9
alexpottNice find @Mile23 and woah not fair testbot.
Comment #11
alexpottSo the counts in the tests where we're not doing an install are impossible in a concurrent test env where the db is shared so lets remove them.
Comment #13
alexpottWhat #11 should have been.
Comment #15
alexpottMore instrumentation.
Comment #16
mile23Moves tests of
TestSiteInstallCommandtoTestSiteInstallCommandTestwhere they're unit tested and don't requireSIMPLETEST_DBor separate processes.Note that we have to use vfsStream to work around an almost-bug in the installer command where it can only evaluate files that haven't loaded yet.
Will need to add in the changes from #15.
edit: Didn't mean to hide any files... d.o did that.
Comment #19
alexpott#15 was about finding out what was wrong! No need to include that :)
Comment #20
alexpottThis might fix it.
Comment #21
mile23Moving all the dependencies to
setUp()is the best solution.RTBC from me, but I contributed code.
Comment #22
borisson_RTBC++
Comment #24
mile23Yay, preventing technical debt by not taking out the loan! Pretty sure this fail is coming off of #2961691: Change SYMFONY_DEPRECATIONS_HELPER back to strict
It seems that passing the environmental array to
Process::run()is the way to go, rather than during construction.Comment #25
alexpottWhy not just call inheritEnvironmentVariables() like it tells us to?
The additional env variables for start and run are just when you want to change the default environment you've set it up with. Constructing and running with the same $env is wrong.
See https://github.com/symfony/symfony/blob/bb4bde3bba9a8f8cd209855cb5589d10...
and https://github.com/symfony/symfony/blob/bb4bde3bba9a8f8cd209855cb5589d10...
Comment #26
alexpottThe other option here is to not pass $this->env to the constructor. But personally I don't like looking at
$process->run(NULL, $this->env);. But's that's a taste thing.Comment #27
mile23Well, ostensibly
$this->envis there for a reason, so we shouldn't inherit environment variables. However, looking atsetUp()I see it isn't there for a reason. It only copiesSIMPLETEST_BASE_URLif it exists, which will be sent to the child process anyway.So here we remove
$this->envand act like it never existed.Comment #28
alexpott@Mile23 I think we'll find this is not that simple because of how PHPUnit.xml.dist configures environment variables especially in PHPUnit 4.
Comment #29
mile23Fails under PHPUnit 6 anyway.
I'm out for the afternoon so if you feel inspired...
Comment #31
alexpottSo looking at Process again here's a patch that just passes the environment on to
Process::run()I'm not a huge fan of$process->run(NULL, $this->env);but calling Process::inheritEnvironmentVariables() also seems silly because in symfony 4 that method is totally redundant. So this feels the best way to not use deprecated functionality.Comment #32
mile23I feel safe with RTBC-ing this issue even though I contributed because it's a superficial change after @borrison_'s RTBC in #22.
Running the testbot at PHP 5.5 which should un-RTBC if it fails.
Comment #33
mile23PHP 5.5 says:
/frownyface
Comment #34
mile23The error log says:
So therefore we need the compatibility layer.
Comment #35
Anonymous (not verified) commentedPHP 5.5 problem fixed. So back to RTBC again.
Comment #36
larowlanout of scope/merge conflict?
phpcs nit: these should be wrapped because > 80
Comment #37
mile23Thanks!
All the changes from #36.
Comment #38
Anonymous (not verified) commentedProbably not the best time for RTBC (while all test runs fail). But anyway.
Comment #40
mile23@mixologic put out the fire, so we can go back to RTBC.
Comment #41
neclimdulExplains why I can't test core with phpunit.
Comment #42
neclimdulComing back to this, why isn't it just moving the test into the kernel namespace where the database requirement is explicit? No unit tests should require a database even if one exists. That's the core of the test suite separation.
Comment #43
alexpottAnother "core of the test separation" is that kerneltest etc... install Drupal for you. Using a unit test allows us to prove that this CLI command has 0 dependency on a Drupal-ized test environment.
Comment #44
mile23Added that conversation to the docblock.
Comment #45
neclimdulnot convert it to a kernel test, move it to the kernel namespace. i.e. put it in the kernel test suite.
Comment #46
neclimdulNot sure what's going on but I've run out of ideas for debugging this. Surely something archaic.
Locally I can run the tests in the patch just fine. Tried with ubuntu's php, official php containers, and Lando's containers and its fine. On a server I use for automated patch testing though I consistently get the following error for both php 7.2 and php 5.6. Same command that's roughly just
php ./vendor/bin/phpunit -c ./core --testsuite unitComment #47
neclimdulgoing to NW this since its failing for me. Going to see if I can isolate what is special about the environment its failing in but any ideas would be appreciated.
Comment #48
neclimdulSpent a lot of time going down rabbit holes thinking it might be something directory related because jenkins does some weird directory names which lead me to figure out #2979150: vfs: directory created during unit tests finally but it wasn't. It was PhpUnit 6 causing this issue, seems providers run different and the VFS trick wasn't working.
Split the VFS test to a separate test.
Comment #49
neclimdulbah, accidentally included the phpunit 6 composer change in that patch. sorry.
Comment #50
mile23+1.
My only nit is:
There are a bunch of these with no message. I suggest adding
$process->getErrorOutput()as a message because it's a pain figuring out whether you're reviewing a failing test or a misconfigured local dev environment. :-)I'd RTBC if I hadn't contributed code.
Comment #51
borisson_RTBC based on #50, I don't think the problem with the misconfigured env will be a big problem, as that will make other tests fail as well.
Comment #52
alexpottNow everything is in setUp() how about we remove the other places we skip. Less stuff to maintain. Also I think this patch would be simpler just to add the new setUp().
For me there's way too many different unrelated things going on in the same patch.
Comment #53
neclimdulA good point. Also, we don't currently skip l tests that require SIMPLETEST_X, we fail. That's something I've been trying to fix for a long long time now. #2714555: Regression in SIMPLETEST environment skipping
Why aren't we just moving this to the functional test suite that requires a database connection? This is a functional test after all.
Comment #55
neclimdulmaybe? simplest solution for now.
Comment #57
neclimdulderp... have to change the namespace. Wish the Test Bot error was better when the class doesn't match the file...
Comment #59
mile23It's actually a functional test, if we're just going to put it in a different namespace.
Comment #61
neclimdulTook another look at this and I think the failures are just that this test is broken.
Specifically there is this code at the top of the test:
And we see testbot creating and granting permissions to the simpletest directory after unit tests and moving into kernel tests.
To confirm this I setup all the SIMPLETEST requirements locally and ran the test without the patch and it failed exactly the same way.
Comment #62
mile23I think we might be able to move this test to a build test after #3031379: Add a new test type to do real update testing
Comment #63
neclimdulEven if that would be a better place, the test can run just fine in the kernel suite as demonstrated by the failures actually catching the broken test. There's no reason to block this imho.
Comment #64
mile23After #2878269: Modify TestDiscovery so the testbot runs all the tests
TestSiteApplicationTestis marked as incomplete, leading to this issue.We have #3031379: Add a new test type to do real update testing in the works, but it seems to have run out of momentum.
So we need to: a) Fix this test so it passes, since it hasn't been running under the testbot since it was committed to core. b) Figure out how to mitigate the need for a database and other such dependencies.
Comment #65
andypostMaybe add
getDatabaseStub()to\Drupal\Tests\UnitTestCase(there's already few stub methods)In related issue this particular test is not covered
Comment #67
mile23I converted some of the methods on TestSiteApplicationTest to be build tests. I was also curious if testUserLogin() fails on the testbot because I couldn't repro a fail locally.
Comment #68
andypostComment #70
mile23Finishes the conversion to build test.
testUserLogin()is still marked incomplete, linking to #2949229: SQLite findTables Returns Empty Array on External DB., only because @andypost mentioned it. Might need a different follow-up.If you remove the
markTestIncomplete()line, and also comment out the 'Set-Cookie' line,testUserLogin()will pass, probably with a false positive.Interdiff included for completeness, but it's much easier to review the patch.
Comment #71
mile23See also: #2905007: Allow run-tests.sh to report skipped/incomplete PHPUnit tests
That change would allow us to see that this test is marked incomplete.
Comment #73
andypostBlocks #2613044: Requests are pushed onto the request stack twice, popped once
Comment #74
longwave#70 no longer applies to 9.1.x.
Comment #75
msutharsWorking on it.
Comment #76
andypostIt could use another re-roll after #3172537: Passing a command as string when creating a "Symfony\Component\Process\Process" instance is deprecated since Symfony 4.2, pass it as an array of its arguments instead, or use the "Process::fromShellCommandline()" constructor if you need features provided
Comment #77
msuthars@andypost Thanks for the info. Will re-roll after that.
Comment #78
andypostNeeds work for reroll as #3172537: Passing a command as string when creating a "Symfony\Component\Process\Process" instance is deprecated since Symfony 4.2, pass it as an array of its arguments instead, or use the "Process::fromShellCommandline()" constructor if you need features provided just commited
Comment #79
anushrikumari commentedComment #80
anushrikumari commentedRerolled the patch for 9.1.x
Please review
Comment #82
longwaveStrange, can't reproduce this same fail locally - the error output is the same as the expected message. However the output seems to depend on the window width, as the second assertion fails for me - the formatting breaks the message in a different place.
Fixing the coding standards issue, let's see what happens here.
Comment #86
quietone commentedRerolled.
Locally (ddev) I get the error reported in #82.
Comment #87
daffie commentedThere are some PHPCBF errors with the patch that need to be fixed. For that only is the issue for a novice.
Comment #88
quietone commentedI have been forgetting to run commit-code-check lately,
Comment #90
dhirendra.mishra commentedI am working on it
Comment #91
dhirendra.mishra commentedPFA files,
Comment #92
longwaveThe patch just deletes a test now, this isn't right.
Comment #93
dhirendra.mishra commentedOh...thanks..Let me re-work on this
Comment #94
dhirendra.mishra commentedComment #95
longwaveThis still isn't right, I think we need to start again from #88.
Comment #96
dhirendra.mishra commentedKindly ignore my previous patches.
I believe this time it will be helpful.
Comment #98
mradcliffeI am removing the Novice tag from this issue because I do not think this is a good Novice issue anymore based on @daffie's comments.
Also interestingly, this might be why I ran into issues trying to write tests for #2894476: [PP-1] Provide commands which are helpful for core development.
Comment #103
quietone commentedJust a reroll. I started from #88 because of comment #95 and the latest patch, #96, is adding an interface without explanation.
Comment #105
quietone commentedThe failing test is testInstallWithNonSetupClass which I take to mean a test script without a setup method. So, I made such a class and used that in the test. That avoided the error message about
The class SebastianBergmann\Versionand gave instead one about the new test class. But the assertions were failing because the command output gets outputs with a small width. To get around that I changed \Drupal\BuildTests\Framework\BuildTestBase::executeCommand to use a width of PHP_INT_MAX (as in the original test) and now the test passes.Comment #106
andypostThis test failed randomly on PHP 8.3 in #3375693: Fix deprecated assert_options() function usage for PHP 8.3
Ref https://dispatcher.drupalci.org/job/drupal_patches/195199/testReport/jun...
Comment #107
spokjeThis looks really great!
Ony tiny nit I stumbled over whilst doing a review:
We removed the use of
@requires externalCommandin #3362083: '@requires externalCommand' is not parsed in PHPUnit 10 since it will be dropped in PHPUnit 10.By the looks of it the two occurrences of this can be safely removed from the patch.
Comment #108
quietone commented@Spokje, thanks!
I have removed the two lines per #107. I also sorted the 'use' statements.
Comment #109
quietone commentedRestore drupalci
Comment #110
spokjeThanks @quietone, for me the changes look good now, let's see what Yer Fellow Core Commiters think, RTBC.
Comment #111
longwaveIf this test is a false positive due to #2949229: SQLite findTables Returns Empty Array on External DB....
...don't other tests here that assert the number of tables have the same problem?
If this is SQLite only should we just skip these all these tests on SQLite?
Comment #112
quietone commentedHere is the result of my research.
First, in this issue findTables is used successfully.
So skipping issues based on that is not right.
The skip in testUserLogin was first added in #2878269: Modify TestDiscovery so the testbot runs all the tests, where it pointed to this issue.
That was changed in #70 changed it to point to #2949229: SQLite findTables Returns Empty Array on External DB.. But that testUserLogin does not use findTables, so that is the wrong message. There are two todos later in the test which explain that testing user login can't be done successfully. And local testing confirms that the test fails when testing the user login.
Therefore, I have made a new issue for fixing the userLogin test and updated the
markTestIncompletemessage accordingly.Comment #114
longwaveRandom fail? in QuickStartTest, requeued.
Comment #115
smustgrave commentedTests are all green. was previously RTBC in 110 and the feedback from 111 appears to be addressed from what I can tell. Going to remark it.
Comment #116
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 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 #117
kostyashupenkoComment #118
gauravvvv commentedRerolled patch #112, as it no longer applies. Removed needs-roll tag. please review
Comment #120
larowlanThis is making things harder for us on gitlab CI