diff --git a/src/Framework/TestCase.php b/src/Framework/TestCase.php index 121a19795d9..08b8ab523c8 100644 --- a/src/Framework/TestCase.php +++ b/src/Framework/TestCase.php @@ -33,6 +33,7 @@ use function is_int; use function is_object; use function is_string; +use function is_writable; use function libxml_clear_errors; use function method_exists; use function ob_end_clean; @@ -1298,34 +1299,46 @@ private function runTest(): mixed $testArguments = array_merge($this->data, array_values($this->dependencyInput)); $capture = tmpfile(); - assert($capture !== false); if (ini_get('display_errors') === '0') { ShutdownHandler::setMessage('Fatal error: Premature end of PHP process. Use display_errors=On to see the error message.'); } - $errorLogPrevious = ini_set('error_log', stream_get_meta_data($capture)['uri']); + + if ($capture !== false) { + $capturePath = stream_get_meta_data($capture)['uri']; + + if (@is_writable($capturePath)) { + $errorLogPrevious = ini_set('error_log', $capturePath); + } else { + $capture = false; + } + } try { /** @phpstan-ignore method.dynamicName */ $testResult = $this->{$this->methodName}(...$testArguments); - $errorLogOutput = stream_get_contents($capture); + if ($capture !== false) { + $errorLogOutput = stream_get_contents($capture); - if ($this->expectErrorLog) { - $this->assertNotEmpty($errorLogOutput, 'Test did not call error_log().'); - } else { - if ($errorLogOutput !== false) { - // strip date from logged error, see https://github.com/php/php-src/blob/c696087e323263e941774ebbf902ac249774ec9f/main/main.c#L905 - print preg_replace('/\[.+\] /', '', $errorLogOutput); + if ($this->expectErrorLog) { + $this->assertNotEmpty($errorLogOutput, 'Test did not call error_log().'); + } else { + if ($errorLogOutput !== false) { + print $this->stripDateFromErrorLog($errorLogOutput); + } } + } elseif ($this->expectErrorLog) { + $this->markTestIncomplete('Could not create writable error_log file.'); } } catch (Throwable $exception) { - if (!$this->expectErrorLog) { - $errorLogOutput = stream_get_contents($capture); + if ($capture !== false) { + if (!$this->expectErrorLog) { + $errorLogOutput = stream_get_contents($capture); - if ($errorLogOutput !== false) { - // strip date from logged error, see https://github.com/php/php-src/blob/c696087e323263e941774ebbf902ac249774ec9f/main/main.c#L905 - print preg_replace('/\[.+\] /', '', $errorLogOutput); + if ($errorLogOutput !== false) { + print $this->stripDateFromErrorLog($errorLogOutput); + } } } @@ -1337,10 +1350,13 @@ private function runTest(): mixed return null; } finally { - ShutdownHandler::resetMessage(); - fclose($capture); + if ($capture !== false) { + ShutdownHandler::resetMessage(); + fclose($capture); - ini_set('error_log', $errorLogPrevious); + /** @phpstan-ignore variable.undefined (https://github.com/phpstan/phpstan/issues/12992) */ + ini_set('error_log', $errorLogPrevious); + } } $this->expectedExceptionWasNotRaised(); @@ -1348,6 +1364,12 @@ private function runTest(): mixed return $testResult; } + private function stripDateFromErrorLog(string $log): string + { + // https://github.com/php/php-src/blob/c696087e323263e941774ebbf902ac249774ec9f/main/main.c#L905 + return preg_replace('/\[\d+-\w+-\d+ \d+:\d+:\d+ [^\r\n[\]]+?\] /', '', $log); + } + /** * @throws ExpectationFailedException */ diff --git a/tests/end-to-end/generic/expect-error-log-fail-with-open_basedir.phpt b/tests/end-to-end/generic/expect-error-log-fail-with-open_basedir.phpt new file mode 100644 index 00000000000..a511ade932f --- /dev/null +++ b/tests/end-to-end/generic/expect-error-log-fail-with-open_basedir.phpt @@ -0,0 +1,42 @@ +--TEST-- +https://github.com/sebastianbergmann/phpunit/issues/6197 +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Runtime: %s + +I 1 / 1 (100%) + +Time: %s, Memory: %s + +Expect Error Log Fail (PHPUnit\TestFixture\ExpectNoErrorLog\ExpectErrorLogFail) + ∅ One + │ + │ Could not create writable error_log file. + + │ + +OK, but there were issues! +Tests: 1, Assertions: 1, Incomplete: 1. diff --git a/tests/end-to-end/generic/expect-error-log-with-open_basedir.phpt b/tests/end-to-end/generic/expect-error-log-with-open_basedir.phpt new file mode 100644 index 00000000000..d0218ba6558 --- /dev/null +++ b/tests/end-to-end/generic/expect-error-log-with-open_basedir.phpt @@ -0,0 +1,33 @@ +--TEST-- +https://github.com/sebastianbergmann/phpunit/issues/6197 +--FILE-- +run($_SERVER['argv']); +--EXPECTF-- +PHPUnit %s by Sebastian Bergmann and contributors. + +Runtime: %s + +logged a side effect +I 1 / 1 (100%) + +Time: %s, Memory: %s + +Expect Error Log (PHPUnit\TestFixture\ExpectErrorLog\ExpectErrorLog) + ∅ One + │ + │ Could not create writable error_log file. + + │ + +OK, but there were issues! +Tests: 1, Assertions: 1, Incomplete: 1.