From b8a5017e194e854b783534bfe83d65ce8fdc4662 Mon Sep 17 00:00:00 2001 From: Dave Long <dave@longwaveconsulting.com> Date: Fri, 2 Feb 2024 14:53:11 +0000 Subject: [PATCH] Issue #3417805 by mondrake: Use Symfony Process to spawn subprocesses in PhpUnitTestRunner --- .../Drupal/Core/Test/PhpUnitTestRunner.php | 40 +++++++------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php index 425f125aa87c..3f4072f92bf5 100644 --- a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php +++ b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php @@ -6,6 +6,7 @@ use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Process\PhpExecutableFinder; +use Symfony\Component\Process\Process; /** * Run PHPUnit-based tests. @@ -106,37 +107,36 @@ public function phpUnitCommand(): string { * (optional) The output by running the phpunit command. If provided, this * array will contain the lines output by the command. * - * @return string - * The results as returned by exec(). - * * @internal */ - public function runCommand(array $unescaped_test_classnames, string $phpunit_file, int &$status = NULL, array &$output = NULL): string { + public function runCommand(array $unescaped_test_classnames, string $phpunit_file, int &$status = NULL, array &$output = NULL): void { global $base_url; // Setup an environment variable containing the database connection so that // functional tests can connect to the database. - putenv('SIMPLETEST_DB=' . Database::getConnectionInfoAsUrl()); + $process_environment_variables = [ + 'SIMPLETEST_DB' => Database::getConnectionInfoAsUrl(), + ]; // Setup an environment variable containing the base URL, if it is available. // This allows functional tests to browse the site under test. When running // tests via CLI, core/phpunit.xml.dist or core/scripts/run-tests.sh can set // this variable. if ($base_url) { - putenv('SIMPLETEST_BASE_URL=' . $base_url); - putenv('BROWSERTEST_OUTPUT_DIRECTORY=' . $this->workingDirectory); + $process_environment_variables['SIMPLETEST_BASE_URL'] = $base_url; + $process_environment_variables['BROWSERTEST_OUTPUT_DIRECTORY'] = $this->workingDirectory; } $phpunit_bin = $this->phpUnitCommand(); $command = [ $phpunit_bin, '--log-junit', - escapeshellarg($phpunit_file), + $phpunit_file, ]; // Optimized for running a single test. if (count($unescaped_test_classnames) == 1) { $class = new \ReflectionClass($unescaped_test_classnames[0]); - $command[] = escapeshellarg($class->getFileName()); + $command[] = $class->getFileName(); } else { // Double escape namespaces so they'll work in a regexp. @@ -147,25 +147,15 @@ public function runCommand(array $unescaped_test_classnames, string $phpunit_fil $filter_string = implode("|", $escaped_test_classnames); $command = array_merge($command, [ '--filter', - escapeshellarg($filter_string), + $filter_string, ]); } - // Need to change directories before running the command so that we can use - // relative paths in the configuration file's exclusions. - $old_cwd = getcwd(); - chdir($this->appRoot . "/core"); - - // exec in a subshell so that the environment is isolated. - $ret = exec(implode(" ", $command), $output, $status); - - chdir($old_cwd); - putenv('SIMPLETEST_DB='); - if ($base_url) { - putenv('SIMPLETEST_BASE_URL='); - putenv('BROWSERTEST_OUTPUT_DIRECTORY='); - } - return $ret; + $process = new Process($command, \Drupal::root() . "/core", $process_environment_variables); + $process->setTimeout(300); + $process->run(); + $output = explode("\n", $process->getOutput()); + $status = $process->getExitCode(); } /** -- GitLab