-
Notifications
You must be signed in to change notification settings - Fork 439
chore(ci_visibility): move retry logic to pytest_runtest_protocol #13448
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
chore(ci_visibility): move retry logic to pytest_runtest_protocol #13448
Conversation
…raujo/SDTEST-1850/refactor-retry-logic-2
…raujo/SDTEST-1850/refactor-retry-logic-2
…raujo/SDTEST-1850/refactor-retry-logic-2
…tor-de-araujo/SDTEST-1850/refactor-retry-logic-2
…raujo/SDTEST-1850/refactor-retry-logic-2
|
Bootstrap import analysisComparison of import times between this PR and base. SummaryThe average import time from this PR is: 248 ± 4 ms. The average import time from base is: 248 ± 5 ms. The import time difference between this PR and base is: -0.4 ± 0.2 ms. The difference is not statistically significant (z = -1.99). Import time breakdownThe following import paths have shrunk:
|
BenchmarksBenchmark execution time: 2025-05-19 15:47:00 Comparing candidate commit dcc238e in PR branch Found 1 performance improvements and 0 performance regressions! Performance is the same for 495 metrics, 8 unstable metrics. scenario:iastdjangostartup-iast
|
…#13507) Remove `RetryTestReport` for good, as part of the effort to support `pytest-xdist`. Attempt-to-Fix was the only retry mechanism that still used it; this PR brings it in line with the recent EFD and ATR refactors (#13448 and #13288). As a bonus, this fixes the miscounting of active Attempt-to-Fix tests in the JUnit XML output. ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [x] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)
This is essentially #13376, recreated now that the fix in the unittest suite (#13445) has been merged, and with the previous
pytest_runtest_protocol
logic wrapped in a try/except to avoid breaking the pipeline in case of an internal error in CI Visibility.Currently we let pytest's builtin
pytest_runtest_protocol
hook to run the test, and we check whether to retry at the makereport stage. This has a number of consequences:makereport
, and we have to patch them and stash information around to keep state across each time we pass through the reports for a given test.FAILED
toATR INITIAL ATTEMPT FAILED
; this affects not only printing, but also the session exit status).PASSED
status was already logged by the time we patch it, so it showsPASSED
instead ofEFD INITIAL ATTEMPT PASSED
. Not only that, but we have to handle this case specially when generating the terminal summary.This PR moves the retry logic from the
pytest_runtest_makereport
hook to thepytest_runtest_protocol
hook. This means we replace pytest's ownpytest_runtest_protocol
with our own. We invoke pytest's internalruntestprotocol
function directly from our hook, so the behavior of our hook is similar to the pytest's own hook. The difference is that we call this function withlog=False
, so pytest doesn't log the setup, call, teardown reports as they are created. Instead, we collect all reports, patch them as needed, and then print them out. This means we can write the logic having full knowledge of the final status of a test run, instead of patching things as we see them during setup, call and teardown.For retries, the responsibility for logging the statuses is moved to the retry handlers themselves, so they can delay printing to after the reports have been patched. In principle, we could even decide to not print the retry results individually and only print the final status (which would make for a cleaner output), but this can come in a future version.
For EFD, the special final outcomes (
dd_efd_final_passed
, etc.) are replaced with plainpassed
,failed
,skipped
states, which xdist can handle, and the final states are only used inefd_get_teststatus
(called from thepytest_report_teststatus
hook).Future work:
EFD INITIAL ATTEMPT
for all atempts (not just the first one).Checklist
Reviewer Checklist