diff --git a/core/tests/Drupal/Tests/Component/Scaffold/Fixtures.php b/core/tests/Drupal/Tests/Component/Scaffold/Fixtures.php index d66d7802f9239ead0482da45250157c15c2b3689..05bb3da9603c492d644d1a4406458d113bafe7d3 100644 --- a/core/tests/Drupal/Tests/Component/Scaffold/Fixtures.php +++ b/core/tests/Drupal/Tests/Component/Scaffold/Fixtures.php @@ -19,6 +19,13 @@ */ class Fixtures { + /** + * Keep a persistent prefix to help group our tmp directories together. + * + * @var string + */ + protected static $randomPrefix = ''; + /** * Directories to delete when we are done. * @@ -167,7 +174,7 @@ public function sourcePath($project_name, $source) { * @see \Drupal\Component\Scaffold\ManageOptions::getLocationReplacements() */ public function getLocationReplacements() { - $destinationTmpDir = $this->mkTmpDir(); + $destinationTmpDir = $this->mkTmpDir('location-replacements'); $interpolator = new Interpolator(); $interpolator->setData(['web-root' => $destinationTmpDir, 'package-name' => 'fixtures/tmp-destination']); return $interpolator; @@ -237,29 +244,47 @@ public function destinationPath($destination, Interpolator $interpolator = NULL, /** * Generates a path to a temporary location, but do not create the directory. * - * @param string $extraSalt - * Extra characters to throw into the md5 to add to name. + * @param string $prefix + * A prefix for the temporary directory name. * * @return string * Path to temporary directory */ - public function tmpDir($extraSalt = '') { - $tmpDir = sys_get_temp_dir() . '/composer-scaffold-test-' . md5($extraSalt . microtime()); + public function tmpDir($prefix) { + $prefix .= static::persistentPrefix(); + $tmpDir = sys_get_temp_dir() . '/scaffold-' . $prefix . uniqid(md5($prefix . microtime()), TRUE); $this->tmpDirs[] = $tmpDir; return $tmpDir; } + /** + * Generates a persistent prefix to use with all of our temporary directories. + * + * The presumption is that this should reduce collisions in highly-parallel + * tests. We prepend the process id to play nicely with phpunit process + * isolation. + * + * @return string + * A random string that will remain the same for the entire process run. + */ + protected static function persistentPrefix() { + if (empty(static::$randomPrefix)) { + static::$randomPrefix = getmypid() . md5(microtime()); + } + return static::$randomPrefix; + } + /** * Creates a temporary directory. * - * @param string $extraSalt - * Extra characters to throw into the md5 to add to name. + * @param string $prefix + * A prefix for the temporary directory name. * * @return string * Path to temporary directory */ - public function mkTmpDir($extraSalt = '') { - $tmpDir = $this->tmpDir($extraSalt); + public function mkTmpDir($prefix) { + $tmpDir = $this->tmpDir($prefix); $filesystem = new Filesystem(); $filesystem->ensureDirectoryExists($tmpDir); return $tmpDir; @@ -342,28 +367,21 @@ public function runScaffold($cwd) { * The Composer command to execute (escaped as required) * @param string $cwd * The current working directory to run the command from. - * @param int $expectedExitCode - * The expected exit code; will throw if a different exit code is returned. * * @return string * Standard output and standard error from the command. */ - public function runComposer($cmd, $cwd, $expectedExitCode = 0) { + public function runComposer($cmd, $cwd) { chdir($cwd); $input = new StringInput($cmd); $output = new BufferedOutput(); $application = new Application(); $application->setAutoExit(FALSE); - try { - $exitCode = $application->run($input, $output); - if ($exitCode != $expectedExitCode) { - print "Command '{$cmd}' - Expected exit code: {$expectedExitCode}, actual exit code: {$exitCode}\n"; - } - } - catch (\Exception $e) { - print "Exception: " . $e->getMessage() . "\n"; - } + $exitCode = $application->run($input, $output); $output = $output->fetch(); + if ($exitCode != 0) { + throw new \Exception("Fixtures::runComposer failed to set up fixtures.\n\nCommand: '{$cmd}'\nExit code: {$exitCode}\nOutput: \n\n$output"); + } return $output; } diff --git a/core/tests/Drupal/Tests/Component/Scaffold/Functional/ManageGitIgnoreTest.php b/core/tests/Drupal/Tests/Component/Scaffold/Functional/ManageGitIgnoreTest.php index c27e3e2fdfe86bdf4a9dc6e446a1d0ec8b7828e1..ddba6f1a404d88d2beada2656f3c5d514a9b3605 100644 --- a/core/tests/Drupal/Tests/Component/Scaffold/Functional/ManageGitIgnoreTest.php +++ b/core/tests/Drupal/Tests/Component/Scaffold/Functional/ManageGitIgnoreTest.php @@ -169,6 +169,7 @@ public function testUnmanagedGitIgnoreWhenGitNotAvailable() { $this->assertFileNotExists($sut . '/docroot/sites/.gitignore'); // Confirm that 'git' is available (n.b. if it were not, createSutWithGit() // would fail). + $output = []; exec('git --help', $output, $status); $this->assertEquals(0, $status); // Modify our $PATH so that it begins with a path that contains an @@ -177,12 +178,44 @@ public function testUnmanagedGitIgnoreWhenGitNotAvailable() { // not need to restore the PATH when we are done. $unavailableGitPath = $this->fixtures->binFixtureDir('disable-git-bin'); chmod($unavailableGitPath . '/git', 0755); + $oldPath = getenv('PATH'); putenv('PATH=' . $unavailableGitPath . ':' . getenv('PATH')); // Confirm that 'git' is no longer available. + $output = []; exec('git --help', $output, $status); $this->assertEquals(127, $status); // Run the scaffold command. + $output = []; exec('composer composer:scaffold', $output, $status); + + putenv('PATH=' . $oldPath . ':' . getenv('PATH')); + + $expected = <<<EOT +0 + +Scaffolding files for fixtures/drupal-assets-fixture: + - Copy [web-root]/.csslintrc from assets/.csslintrc + - Copy [web-root]/.editorconfig from assets/.editorconfig + - Copy [web-root]/.eslintignore from assets/.eslintignore + - Copy [web-root]/.eslintrc.json from assets/.eslintrc.json + - Copy [web-root]/.gitattributes from assets/.gitattributes + - Copy [web-root]/.ht.router.php from assets/.ht.router.php + - Skip [web-root]/.htaccess: overridden in fixtures/drupal-composer-drupal-project + - Copy [web-root]/sites/default/default.services.yml from assets/default.services.yml + - Skip [web-root]/sites/default/default.settings.php: overridden in fixtures/scaffold-override-fixture + - Copy [web-root]/sites/example.settings.local.php from assets/example.settings.local.php + - Copy [web-root]/sites/example.sites.php from assets/example.sites.php + - Copy [web-root]/index.php from assets/index.php + - Skip [web-root]/robots.txt: overridden in fixtures/drupal-composer-drupal-project + - Copy [web-root]/update.php from assets/update.php + - Copy [web-root]/web.config from assets/web.config +Scaffolding files for fixtures/scaffold-override-fixture: + - Copy [web-root]/sites/default/default.settings.php from assets/override-settings.php +Scaffolding files for fixtures/drupal-composer-drupal-project: + - Skip [web-root]/.htaccess: disabled + - Copy [web-root]/robots.txt from assets/robots-default.txt +EOT; + $this->assertEquals($expected, $status . "\n\n" . implode("\n", $output)); $this->assertFileExists($sut . '/docroot/index.php'); $this->assertFileNotExists($sut . '/docroot/sites/default/.gitignore'); }