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

tests(agent): Add tests that specifically exercise JIT. #715

Merged
merged 37 commits into from
Oct 22, 2023

Conversation

zsistla
Copy link
Contributor

@zsistla zsistla commented Aug 17, 2023

Convert forked PR branch to main repo branch so the ci/cd will run...

Please see original forked PR here: #583

@zsistla zsistla changed the title chore(tests): Convert forked PR branch to main repo branch. tests(agent): Add tests that specifically exercise JIT. Aug 17, 2023
@codecov-commenter
Copy link

codecov-commenter commented Aug 17, 2023

Codecov Report

Merging #715 (47469df) into oapi (2b9e3b4) will increase coverage by 0.05%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##             oapi     #715      +/-   ##
==========================================
+ Coverage   78.59%   78.65%   +0.05%     
==========================================
  Files         191      191              
  Lines       26629    26628       -1     
==========================================
+ Hits        20930    20944      +14     
+ Misses       5699     5684      -15     
Flag Coverage Δ
agent-for-php-7.0 77.37% <ø> (-0.01%) ⬇️
agent-for-php-7.1 77.09% <ø> (-0.01%) ⬇️
agent-for-php-7.2 77.60% <ø> (-0.01%) ⬇️
agent-for-php-7.3 77.62% <ø> (-0.01%) ⬇️
agent-for-php-7.4 77.36% <ø> (-0.01%) ⬇️
agent-for-php-8.0 77.23% <ø> (+0.06%) ⬆️
agent-for-php-8.1 77.18% <ø> (+0.06%) ⬆️
agent-for-php-8.2 76.78% <ø> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

see 2 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@zsistla zsistla added this to the OAPI Instrumentation milestone Aug 21, 2023
Comment on lines 36 to 39
/*EXPECT_ERROR_EVENTS
null
*/

Copy link
Member

Choose a reason for hiding this comment

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

Why was this removed? The 'baseline' for this test has this:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The original tests, which provided the prototype for this test, pass; however, these are not exact clones or they would be duplicate tests.

These tests have differences, namely:
https://github.com/newrelic/newrelic-php-agent/pull/715/files/acc7942cb672999fd87537be9aae508915bcc916#diff-61ae0ae768b1f2332109c0aad270b311e54933445589dc3249ce023b009b78eaR24-R26

So we are using PHP's native error handling in a slightly different way.
Because of the differences and how PHP handles errors, for PHP 8.0/8.1 it creates an error when it handles the uncaught exception and the agent create an error event with that error. However, PHP 8.2 handles an uncaught exception slightly differently and doesn't generate an error when it handles an uncaught exception.

Copy link
Member

Choose a reason for hiding this comment

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

The original tests, which provided the prototype for this test, pass; however, these are not exact clones or they would be duplicate tests.

Yes, they are not duplicates. The modify runtime execution of original tests, by:

  1. loading opcache module
  2. enabling opcache
  3. enabling JIT

However, the agent's behavior should persist regardless of this change in runtime. Yet, agent's behavior changes, and this code block:

/*EXPECT_ERROR_EVENTS
null
*/

exposes those behavior differences. I.e. ERROR_EVENTS are generated in PHPs 8.0 and 8.1 but are not generated in PHP 8.2.

Copy link
Member

Choose a reason for hiding this comment

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

If the behavior of the agent is supposed to be different depending on PHP version, then this test should be PHP version specific.

Copy link
Contributor Author

@zsistla zsistla Oct 16, 2023

Choose a reason for hiding this comment

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

This behavior differs between PHP 8.0/8.1 and PHP 8.2 because PHP used to accept less strongly typed error handlers without explicit parameters. Starting with PHP 8.2 WHEN opcache is enabled
, error handlers need to have explicit parameters.
As such, exceptions handled by old style error handlers will be correctly propagated for PHP 8.0/8.1,
but PHP 8.2 and above requires strongly typed error handlers otherwise the object it returns isn't explicitly recognizable as a Throwable.

The tests are split to accommodate the difference.

Please see: d139ac6 which does the following:

  • Split tests since PHP used to accept less strongly typed error handlers without explicit parameters.
    Starting with PHP 8.2, error handlers need to have explicit parameters.
    As such, exceptions handled by old style error handlers will be correctly propagated for PHP 8.0/8.1,
    but PHP 8.2 and above requires strongly typed error handlers otherwise the object it returns isn't explicitly recognizable as a Throwable.
    To cover both cases, there is now one test for PHP 8.0/8.1 with old style error handler and one test for PHP 8.0+ with new style handler.
  • Updated description to explicitly determine if error events are created since previous description only noted if span events were created.
  • Updated names to more accurately reflect test behavior.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think 38eb42d and d139ac6 is the right approach here. The crux of the issue is that nr_php_error_zval_is_exception in PHP 8.2 when opcache is enabled is not able to confirm that the zval it got is of Throwable type. According to https://www.php.net/manual/en/function.set-exception-handler.php#refsect1-function.set-exception-handler-parameters, the $callback should be a function that accepts exactly one parameter, which will be the Throwable object. The handler in the test is a closure that doesn’t expect and/or use any parameters. The incorrect PHP code leads to undefined behavior of the agent, which is what this issue is all about. To address this issue, the test code needs to be fixed in the first place. When the test code uses valid PHP code, the OAPI agent behaves the same for all PHP versions regardless if opcache is enabled or disabled and therefore the split between PHP versions is not needed. This PR #748 reverts 38eb42d and d139ac6 and fixes the PHP code in tests.

However, #748 will expose a different issue: when DT is enabled, OAPI agent generates error_events and pre-OAPI agent does not generate error_events (tests/integration/span_events/test_span_events_are_created_upon_caught_exception.php fails for OAPI agent because it has this expectation). This behavior difference is caused by this code difference:

  • pre-oapi agent checks if nr_txn_should_create_span_events(NRPRG(txn)) here and generates error_event only when current request will not cause spans to be created
  • oapi agent does not check if current request will or will not cause spans to be created here and and generates error_event unconditionally.

To address this issue we need to answer this question: "Which behavior is correct: pre-OAPI agent or OAPI agent?"

Copy link
Member

Choose a reason for hiding this comment

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

After further discussion it was determined that:

  • this PR changes tests in tests/integratio/jit subtree only, and therefore the signature of user exception handler in tests/integration/span_events/test_span_events_are_created_upon_caught_exception.php is not going to be fixed by this PR. tests: fix user exception and error handler implementation #748 will be re-purposed to address fixing invalid test code in tests outside tests/integratio/jit subtree.
  • it is ok to leave test_span_events_are_created_upon_uncaught_exception.php -> test_span_events_are_created_upon_uncaught_unhandled_exception.php and test_span_events_are_created_upon_caught_exception.php -> {test_span_events_are_created_upon_uncaught_handled_exception.php and test_span_events_are_created_upon_uncaught_handled_exception_invalid_handler.php} file renames in this PR
  • the behavior in oapi agent of generating error events unconditionally is the correct behavior; either re-purposed tests: fix user exception and error handler implementation #748 or new PR will address this behavior change and update/split test_span_events_are_created_upon_caught_exception.php and/or other tests that have this issue depending on PHP version.

…ormation.

* Split tests since:
Unlike the case of
PHP 8.0/8.1 where PHP OAPI additionally passes exception information in the
zend_execute_data for the agent to use to create an error_event, PHP 8.2
passes no additional information for the error event to be recorded.
* Updated description to explicitly determine if error events are created since previous description only cared if span events were created.
* Updated names to more accurately reflect test behavior.
* Changed tests that verify behavior when an uncaught exception is handled by an exception handler to use correct PHP syntax. Incorrect syntax (without explicitly typing the parameter name and type) had been used previously. For oapi+opcache, this resulted in error events for PHP 8.0 and 8.1, but none for PHP 8.2.
* Corrected the syntax of the exception handler definition to have an explicit parameter results in error events for all PHP 8+ versions.
* Corrected name of test.
* Added an _old_ test to for historical completeness only and not intended for future development.
* Changed tests to add error_event detection since oapi agent is now correctly generating error events in the case of uncaught exceptions handled by exception handlers.
Copy link
Member

@lavarou lavarou left a comment

Choose a reason for hiding this comment

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

I have a few 'cosmetic' updates which, hopefully, improve test descriptions as well as test expectations.

zsistla and others added 19 commits October 18, 2023 14:32
…on_uncaught_handled_exception.php

Co-authored-by: Michal Nowacki <[email protected]>
…on_uncaught_old_handled_exception.php

Co-authored-by: Michal Nowacki <[email protected]>
…on_uncaught_old_handled_exception.php

Co-authored-by: Michal Nowacki <[email protected]>
…on.php to test_span_events_are_created_upon_uncaught_handled_exception_invalid_handler.php
…on.php to test_span_events_are_created_upon_uncaught_handled_exception_invalid_handler
…nvalid_handler to test_span_events_are_created_upon_uncaught_handled_exception_invalid_handler.php
…n_uncaught_handled_exception.php

Co-authored-by: Michal Nowacki <[email protected]>
…n_uncaught_handled_exception.php

Co-authored-by: Michal Nowacki <[email protected]>
…on_uncaught_unhandled_exception.php

Co-authored-by: Michal Nowacki <[email protected]>
Copy link
Contributor

@ZNeumann ZNeumann left a comment

Choose a reason for hiding this comment

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

Great work and very thorough conversations!

@zsistla zsistla merged commit 8bcd5ca into oapi Oct 22, 2023
52 checks passed
@zsistla zsistla deleted the ads/oapi-jit-tests branch September 13, 2024 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants