Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Setting error handler inside an isolated test may cause test failure on PHP 8.3 #5677

Open
wants to merge 4 commits into
base: 10.5
Choose a base branch
from

Conversation

siketyan
Copy link

@siketyan siketyan commented Jan 23, 2024

Related Issues

Summary

On PHP 8.3, calling set_error_handler in an isolated test (via #[RunInSeparateProcess]) may cause test failure, regardless of what the error handler does.

Some frameworks, including Laravel, enables their error handler on booting. After the test run, PHPUnit's temporary code tries to call rewind(STDOUT). This may cause an error when STDOUT is not rewindable, as the comment says; this is expected. The error handler set by the framework is called even though @ is prepended to the call.

After that PHPUnit\Runner\ErrorHandler is called somehow only on PHP 8.3; I don't know why this is called (a PHP bug?). ErrorHandler tries to find the call stack, but it's not possible. Then the test fails by ErrorHandler throwing NoTestCaseObjectOnCallStackException. In my application tests, this is shown as 'Test was run in child process and ended unexpectedly'.

This pull request sets a no-op error handler temporarily during doing fallible calls with @. This helps the tests calling set_error_handler but not calling restore_error_handler after the test.

Workaround

Call restore_error_handler on tearDown or tearDownAfterClass depending on the situation.

Signed-off-by: Natsuki Ikeguchi <me@s6n.jp>
…lure on PHP 8.3

Signed-off-by: Natsuki Ikeguchi <me@s6n.jp>
@siketyan siketyan changed the base branch from main to 10.5 January 23, 2024 11:42
@sebastianbergmann
Copy link
Owner

CC @mvorisek

@sebastianbergmann sebastianbergmann added the feature/test-runner CLI test runner label Jan 23, 2024
Signed-off-by: Natsuki Ikeguchi <me@s6n.jp>
Copy link

codecov bot commented Jan 23, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (0bd6637) 89.92% compared to head (a5f3908) 89.92%.

Additional details and impacted files
@@            Coverage Diff            @@
##               10.5    #5677   +/-   ##
=========================================
  Coverage     89.92%   89.92%           
  Complexity     6426     6426           
=========================================
  Files           680      680           
  Lines         20532    20532           
=========================================
  Hits          18463    18463           
  Misses         2069     2069           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@mvorisek
Copy link
Contributor

mvorisek commented Jan 23, 2024

What is the behaviour

before/after f38fc88 (PHPUnit 10.5.9)

and before/after #5619 (PHPUnit master (upcoming 11.x))?

On PHP 8.3, calling...

Is it somehow related with php/php-src@b3e33be?

@@ -66,6 +66,8 @@ function __phpunit_run_isolated_test()

ini_set('xdebug.scream', '0');

set_error_handler('__phpunit_error_handler');
Copy link
Contributor

@mvorisek mvorisek Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
set_error_handler('__phpunit_error_handler');
set_error_handler(static fn() => false);

use anonymous function

and return false to keep error_get_last() set, the PHP error handlers does not support nesting, @ should supress any PHP output

Copy link
Author

@siketyan siketyan Jan 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in a5f3908.

@siketyan
Copy link
Author

before/after f38fc88 (PHPUnit 10.5.9)

Nothing changed for the regression test.

before/after #5619 (PHPUnit master (upcoming 11.x))?

Before 93aa92b: Same as 10.5 branch.
After 93aa92b: Test succeeds but marked as a risky test:

PHPUnit 10.5.3-33-g5da503ce1 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.3.2

R                                                                   1 / 1 (100%)

Time: 00:00.069, Memory: 8.00 MB

There was 1 risky test:

1) PHPUnit\TestFixture\Issue5595Test::test
Test code or tested code did not remove its own error handlers

/Users/siketyan/.local/src/github.com/sebastianbergmann/phpunit/tests/end-to-end/regression/5595/Issue5595Test.php:25

OK, but there were issues!
Tests: 1, Assertions: 1, Risky: 1.

Is it somehow related with php/php-src@b3e33be?

It can be, I couldn't find which part of the change cause this.

Co-authored-by: Michael Voříšek <mvorisek@mvorisek.cz>
Signed-off-by: Natsuki Ikeguchi <me@s6n.jp>
@mvorisek
Copy link
Contributor

before/after #5619 (PHPUnit master (upcoming 11.x))?

Before 93aa92b: Same as 10.5 branch. After 93aa92b: Test succeeds but marked as a risky test:

If so, it seems the error handler is set during a test not during a bootstrap. Such issue is detected by PHPUnit master (upcoming 11.x) correctly and the proper fix is to never end a test with modified global handlers as advised in laravel/framework#49237 (comment) and like reasoned in #5619 (comment).

@siketyan
Copy link
Author

I'll submit a pull request to Laravel later. Are we not going to add this change for the temporary fix in PHPUnit 10 anyway?

@siketyan
Copy link
Author

To be clear: "bootstrapping" which I wrote in the description is of Laravel, not PHPUnit. It's called in setUp for each tests.

@mvorisek
Copy link
Contributor

mvorisek commented Jan 23, 2024

In PHPUnit 10.x is it only undetected, in (upcoming) PHPUnit 11.x is it detected. In PHPUnit 10.x the detection was not added for BC reasons. So I think there is nothing to fix.

https://github.com/sebastianbergmann/phpunit/blob/0647107202/tests/end-to-end/regression/5592/Issue5592Test.php test should be improved to test an error handler added in setUp/tearDown and /w process isolation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature/test-runner CLI test runner
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants