-
Notifications
You must be signed in to change notification settings - Fork 50
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
Provide a @retry decorator to automatically retry Python functions in Checkbox jobs (new) #1453
Conversation
When a function is decorated with @Retry, it will be retried until it passes or until the maximum defined attempts have been reached: >>> from checkbox_support.helpers.retry import retry >>> result my_failing_test() KeyboardInterrupt >>> @Retry(max_attempts=2, max_delay=10) ... def my_failing_test(arg): ... return 1 / arg ... >>> result = my_failing_test(0) Attempt 1/2 =========== Attempt 1 failed: division by zero Waiting 2.22 seconds before retrying... Attempt 2/2 =========== Attempt 2 failed: division by zero All the attempts have failed! >>> @Retry(max_attempts=2, max_delay=10) ... def my_passing_test(arg): ... return 1 * arg ... >>> result = my_passing_test(0) Attempt 1/2 =========== >>> result 0
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1453 +/- ##
==========================================
+ Coverage 45.87% 46.23% +0.36%
==========================================
Files 367 368 +1
Lines 39156 39243 +87
Branches 6622 6636 +14
==========================================
+ Hits 17961 18144 +183
+ Misses 20504 20401 -103
- Partials 691 698 +7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicely done! I like this
A few changes, major I would like to see is the patch, it makes testing this easier (mocking decorators is tricky). Also, please don't change the exception, I see no upside to that tbh.
- Raise the encountered exception (instead of SystemExit) when all the attempts have been tried - Separate the actual retry code into its own function, `run_with_retry()`: this allows the retry command to be used without a decorator - Remove initial delay and backoff factor from function signatures: these are not modified often in practice, whereas max_attempts and delay are more useful - Make the decorator arguments mandatory: instead of using default values, let the test author decide how many attempts and what delay to use when using the @Retry decorator - Add a `fake_run_with_retry()` function to facilitate unit testing of code using the retry decorator
If test author try to use attempts or delay with a value less than 1, ValueError is raised.
Description
This PR does two things:
@retry
decorator that can be used on any Python functions to automatically re-run it several times with an added delay/backoff/jitter when it raises an exceptionnetworking_http.py
script to make use of thisMore info about the decorator:
When a function is decorated with
@retry
, it will be retried until itpasses or until the maximum defined attempts have been reached:
Resolved issues
https://warthogs.atlassian.net/browse/CHECKBOX-1543
Note: This PR implements the decorator, but it does not modify the WiFi tests to make use of it. This will be done in a separate PR.
Documentation
Documented in the commit messages. Since this is part of checkbox-support, it is not documented in the readthedocs documentation.
Tests
Unit tests are provided, and I also ran it on the
networking/http
job in Checkbox:The job works as before when everything is OK (it just adds an "Attempt 1/x" at the beginning of the outcome):
And it tries 5 times with a moving delay when failing (here, the HTTP URL to use has been left empty, so wget fails with an
Invalid host name
error):