From f98cba2bb47834344d1544fd518659652d4acf35 Mon Sep 17 00:00:00 2001 From: Mohamed El Mrabet Date: Sun, 30 Aug 2026 08:59:21 +0100 Subject: [PATCH] Fail gracefully when a test directory is missing Previously chdir(realpath(...)) would chdir(false) silently if the target dev/tests directory did not exist, potentially running paratest in whatever the previous loop iteration's (or the process's original) working directory was instead of failing loudly. Also document why $commandArguments is intentionally passed through unescaped (mirrors Magento's own dev:tests:run, meant to carry multiple shell tokens; this is a local dev CLI, not fed untrusted remote input). --- Console/DevTestsRunCommand.php | 9 ++++++++ Test/Unit/Console/DevTestsRunCommandTest.php | 24 ++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/Console/DevTestsRunCommand.php b/Console/DevTestsRunCommand.php index 3250914..deacfbb 100644 --- a/Console/DevTestsRunCommand.php +++ b/Console/DevTestsRunCommand.php @@ -98,6 +98,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($runCommands as $key) { [$dir, $options] = $this->commands[$key]; $dirName = realpath(BP . '/dev/tests/' . $dir); + if ($dirName === false) { + $output->writeln('Test directory not found: ' . BP . '/dev/tests/' . $dir . ''); + $failures[] = 'missing directory: ' . $dir; + continue; + } chdir($dirName); // Build ParaTest command $command = sprintf( @@ -116,6 +121,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int $command .= ' ' . $commandArguments; } $this->logCommand($output, $dirName, $command); + // $commandArguments is passed through unescaped, same as Magento's native + // dev:tests:run: it is meant to carry multiple shell tokens (e.g. "--filter=Foo bar.php"), + // so escaping the whole string would break that. This command is a local dev CLI tool + // invoked directly by the developer, not fed untrusted input from a remote caller. // passthru() call have to be here. // phpcs:ignore Magento2.Security.InsecureFunction passthru($command, $returnVal); diff --git a/Test/Unit/Console/DevTestsRunCommandTest.php b/Test/Unit/Console/DevTestsRunCommandTest.php index 4413810..3dd4568 100644 --- a/Test/Unit/Console/DevTestsRunCommandTest.php +++ b/Test/Unit/Console/DevTestsRunCommandTest.php @@ -174,4 +174,28 @@ public function testProcessesCannotBeBelowOne() $tester->getDisplay() ); } + + public function testMissingTestDirectoryIsReportedAsFailure() + { + global $devTestsRunCommandTestResult; + $devTestsRunCommandTestResult = 0; + + $dir = BP . '/dev/tests/unit'; + rename($dir, $dir . '.bak'); + + try { + $tester = new CommandTester($this->command); + $tester->execute([DevTestsRunCommand::INPUT_ARG_TYPE => 'unit']); + + $output = $tester->getDisplay(); + $this->assertStringContainsString( + 'Test directory not found', + $output, + 'A missing test directory should be reported instead of chdir()-ing into it blindly' + ); + $this->assertStringContainsString('FAILED - ', $output); + } finally { + rename($dir . '.bak', $dir); + } + } }