- ivnish Kazakhstan
Patch #48 works with Drupal 9.5
Run tests of my module without this patch: Time: 01:27.310
Run tests of my module with this patch: Time: 00:36.736
tyler36, you need to add BROWSERTEST_CACHE_DB=1 before phpunit exec. In my case this is
fin exec BROWSERTEST_CACHE_DB=1 vendor/bin/phpunit --testsuite=my_module
- ๐ฏ๐ตJapan tyler36 Osaka
@ivnish Thank you for pointing out the
BROWSERTEST_CACHE_DB
requirement.Tested #48 on Drupal 10.0.9 one existing project with mixture of unit, kernel and functional tests (32 tests, 280 assertions).
Time went from 02:28 => 1:13. Multiple runs averaged about 50 second saved. - ๐ฏ๐ตJapan tyler36 Osaka
I think the environmental variable should be added to
core/phpunit.xml.dist
. This allows it to be the "default" setting.<php> ... <env name="BROWSERTEST_CACHE_DB" value="1"/> </php>
- ๐ช๐ธSpain fjgarlin
#55 is a good suggestion. I'd add it to the list of changes requested in #35
- ivnish Kazakhstan
I have a lot of bugs with DB cache. For example "unknown schema" and "route not found". Be careful
- First commit to issue fork.
- Assigned to kaustavbagchi
- ๐ฎ๐ณIndia kaustavbagchi
This is an updated version of 2900208-48.patch which is now compatible with Drupal 10.1.x version.
- ๐ฎ๐ณIndia kaustavbagchi
This is an updated version of 2900208-59.patch with whitespaces removed, compatible with Drupal 10.1.x version.
- last update
about 1 year ago Custom Commands Failed - last update
about 1 year ago Custom Commands Failed - Status changed to Needs review
about 1 year ago 10:26am 26 October 2023 - last update
about 1 year ago 29,676 pass - last update
about 1 year ago 30,438 pass - ivnish Kazakhstan
I manually compared patch #48 and patch #59 and #60. Patches #59 and #60 are garbage patches without any changes. Only code style was broken
Patch #61 added one new change
/** * The "#1" admin user. * * @var \Drupal\TestSite\Commands\TestSiteInstallCommand */ protected $dumpFile;
- ๐ฌ๐งUnited Kingdom catch
It would be useful to see if this makes a difference on gitlab ci. We'd need an MR, with the environment variable shortcutted (or set in the gitlab YAML).
- Status changed to Needs work
about 1 year ago 5:43pm 26 October 2023 - ๐บ๐ธUnited States smustgrave
gitlab would make sense. and #60 would be good to explain why you added a new change.
- ๐บ๐ธUnited States dave reid Nebraska USA
Dave Reid โ made their first commit to this issueโs fork.
- Merge request !5744Improve performance of functional tests by caching Drupal installations โ (Open) created by dave reid
- ๐บ๐ธUnited States dave reid Nebraska USA
I found an issue using the latest version on 10.2 where
$connection_info['default']['driver']
is nowDrupal\mysql\Driver\Database\mysql
instead ofmysql
. Opened an official MR for better visibility and GitLab CI testing. - ๐บ๐ธUnited States GuyPaddock
So far, I've been able to fix the concurrency issues and improve performance by reworking the methods as follows:
/** * Installs Drupal into the Simpletest site. */ public function installDrupal() { if (getenv('BROWSERTEST_CACHE_DB')) { $this->initDumpFile(); $lock_file = $this->dumpFile . '.lock'; $this->runWithLockFile($lock_file, function () use (&$install_from_dump) { if (file_exists($this->dumpFile)) { $install_from_dump = TRUE; } else { $this->installDrupalFromProfile(); $this->dumpDatabase(); $install_from_dump = FALSE; } }); // The check for the dump file happens inside the critical section to // ensure it blocks while a dump is being created, but the installation // happens outside the critical section so that multiple tests can use the // same dump file concurrently. if ($install_from_dump) { $this->installDrupalFromDump(); } } else { $this->installDrupalFromProfile(); } } /** * Determines a proper file name for SQL dump. */ protected function initDumpFile() { $class = get_class($this); $modules = []; while ($class) { if (property_exists($class, 'modules')) { $modules = array_merge($modules, $class::$modules); } $class = get_parent_class($class); } sort($modules); array_unique($modules); $temp_dir = sys_get_temp_dir(); $cache_dir = getenv('BROWSERTEST_CACHE_DIR') ?: $temp_dir . '/test_dumps/' . \Drupal::VERSION; $this->dumpFile = $cache_dir . '/' . md5(implode('-', $modules)) . '.sql'; // Create a folder to contain the test database dumps, if it does not // already exist. Only one test is allowed to create this at a time. $lock_file = sprintf("%s/test_dumps-%s.lock", $temp_dir, \Drupal::VERSION); $this->runWithLockFile($lock_file, function () use ($cache_dir) { if (!is_dir($cache_dir)) { mkdir($cache_dir, 0777, TRUE); } }); } /** * Acquires an exclusive lock on the specified file and runs the given code. * * This is used to ensure that only one test is executing the same code at the * same time on the same runner. The lock is released after the critical code * returns. * * @param string $lock_file_path * The path to the lock file. * @param callable $critical_code * The code to invoke only once the lock is obtained. */ private function runWithLockFile(string $lock_file_path, callable $critical_code) { $locked = FALSE; $lock_handle = fopen($lock_file_path, 'w'); try { if (($lock_handle !== FALSE) && flock($lock_handle, LOCK_EX)) { $locked = TRUE; $critical_code(); } else { $this->fail('Failed to acquire lock: ' . $lock_file_path); } } finally { // Delete the lock file before unlocking it to ensure we don't delete a // lock created by another process. if (file_exists($lock_file_path)) { @unlink($lock_file_path); } if ($locked) { @flock($lock_handle, LOCK_UN); } if ($lock_handle !== FALSE) { @fclose($lock_handle); } } }
An interdiff (against #48) is attached for the changes above, but I was curious about feedback on this approach before I apply them to the MR.
- ๐ง๐ชBelgium wim leers Ghent ๐ง๐ช๐ช๐บ
If a full install + module installs are no longer needed, but just a
drush site:install --existing-config
, then that would already speed up things considerably.Which means that ๐ Configuration being imported by the ConfigImporter sometimes has stale original data Fixed (which just landed) should also help with this.
- ๐ท๐บRussia lexbritvin
The provided patches don't consider install profile and default theme.
Here is a small enhancement to the patch. - Issue was unassigned.
- Status changed to Needs review
5 months ago 8:43am 8 August 2024 - ๐ฌ๐งUnited Kingdom jonathan1055
There is a call-out on slack asking for help to test this
https://drupal.slack.com/archives/C223PR743/p1723469165431189Can someone update the issue summary here to explain how you would like this tested, how to run it, what info you want, with & without the change. Thanks.
- ๐ซ๐ทFrance andypost
btw Sqlite just needs to copy DB-file after install
- ๐ฌ๐งUnited Kingdom catch
Would be good to see how this affects test run times once the MR is green but also we should check it against the times on ๐ Add the ability to install multiple modules and only do a single container rebuild to ModuleInstaller Active which significantly improves performance of the installer.
- Status changed to Needs work
4 months ago 2:47pm 17 August 2024 - ๐ฌ๐งUnited Kingdom jonathan1055
I have rebase the MR, it was 110 commits behind.
The MR is red because of a couple of PHPStan failures----- -------------------------------------------------------------------------- Line core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php (in context of class Drupal\TestSite\Commands\TestSiteInstallCommand) ------ -------------------------------------------------------------------------- 830 Access to an undefined property Drupal\TestSite\Commands\TestSiteInstallCommand::$dumpFile. ๐ก Learn more: https://phpstan.org/blog/solving-phpstan-access-to-undefined-property 852 Access to an undefined property Drupal\TestSite\Commands\TestSiteInstallCommand::$dumpFile. ๐ก Learn more: https://phpstan.org/blog/solving-phpstan-access-to-undefined-property
These are in the new functions dumpDatabase() and restoreDatabase(), but the critical bit I think is
in context of class Drupal\TestSite\Commands\TestSiteInstallCommand
as that uses this trait, see
https://git.drupalcode.org/project/drupal/-/blob/11.x/core/tests/Drupal/... - Status changed to Needs review
4 months ago 10:09am 19 August 2024 - ๐ฌ๐งUnited Kingdom jonathan1055
I moved the definition of
dumpFile
from BrowserTestBase to FunctionalTestSetupTrait. - ๐ฌ๐งUnited Kingdom jonathan1055
The MR pipeline now runs green :-)
I am testing this locally, but I get
PHPUnit\Framework\Exception: mysqldump: [Warning] Using a password on the command line interface can be insecure.
and this halts the tests and gives "This test did not perform any assertions"
What's the bet way around this? There are multipe ways to do it, maybe we want to adust the two new mysql commands to use a file for the credentials? - ๐ฉ๐ชGermany FeyP
> [Warning] Using a password on the command line interface can be insecure.
Last time I looked, drush created a temporary file using
tmpfile()
with the login data and passed that to mysqdump / mysql via--defaults-extra-file
. Given that the temporary file is deleted by PHP at the end of the execution of the process and we're only using this during testing and not in production, this might be sufficiently secure, at least more secure than passing this on the command line or using environment variables (on the other hand, I guess we're already using env vars during testing anyway, so nothing gained over using env vars?). We could also re-check drush sql commands before we start implementing this, maybe there is now another solution that is even better? - ๐ฌ๐งUnited Kingdom jonathan1055
@feyp I don't think there is anything to do with drush here. This is a core issue, and drush is not used to execute these commands.
I was not asking from the point of security (others will have an opinion on that). I just wanted to know how I can test this locally. Some other devs have reported being able to run this locally. Maybe the warning can be suppressed so that the tests continue?
- ๐ฉ๐ชGermany FeyP
@feyp I don't think there is anything to do with drush here. This is a core issue, and drush is not used to execute these commands.
Yes, I know that, of course. I was referring to the implementation of drush sql commands, which also call mysqldump, as a reference implementation on how to suppress this warning in code and was suggesting to do something similar here so that you don't run into this warning when running the tests locally.
- ๐ซ๐ทFrance andypost
That's because CI images using specific config and predefined users https://git.drupalcode.org/project/drupalci_environments/-/blob/dev/db/m...
- ๐ฌ๐งUnited Kingdom jonathan1055
I have this working locally now using the method @feyp suggested - writing the user and password to a temporary file then using
--defaults-extra-file=$user_credentials_file
instead of the-u$user -p$pass
arguments. If this is an acceptable solution I will tidy it up and push it here for comments. But if this is a non-starter I will discard it. - ๐บ๐ธUnited States smustgrave
Dumb question but good way to test this one?
- ๐ฌ๐งUnited Kingdom catch
I just kicked off a pipeline to check if it's still green and try to see what the timings look like.
Another way would be to run a test that is likely to benefit from the change locally before/after and record the times - although probably need to do middle of three to account for variations.
- ๐บ๐ธUnited States smustgrave
Seems to have some test failures
But left some comments/questions on the MR.
- ๐ณ๐ฟNew Zealand quietone
Changing to the DX special tag defined on Issue tags -- special tags โ .
- Status changed to Needs work
15 days ago 11:13am 7 December 2024 - ivnish Kazakhstan
For Drupal 11 needs to remove
\Drupal::configFactory()->getEditable('system.file') ->set('path.temporary', $this->tempFilesDirectory) ->save();
because path.temporary is deprecated