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 for randomized retry interval format #624

Merged
merged 1 commit into from
May 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions queue_job/models/queue_job_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,12 @@
try:
# as json can't have integers as keys and the field is stored
# as json, convert back to int
retry_pattern = {
int(try_count): postpone_seconds
for try_count, postpone_seconds in self.retry_pattern.items()
}
retry_pattern = {}
for try_count, postpone_value in self.retry_pattern.items():
if isinstance(postpone_value, int):
retry_pattern[int(try_count)] = postpone_value
else:
retry_pattern[int(try_count)] = tuple(postpone_value)

Check warning on line 157 in queue_job/models/queue_job_function.py

View check run for this annotation

Codecov / codecov/patch

queue_job/models/queue_job_function.py#L157

Added line #L157 was not covered by tests
simahawk marked this conversation as resolved.
Show resolved Hide resolved
except ValueError:
_logger.error(
"Invalid retry pattern for job function %s,"
Expand Down Expand Up @@ -181,8 +183,9 @@
def _retry_pattern_format_error_message(self):
return _(
"Unexpected format of Retry Pattern for {}.\n"
"Example of valid format:\n"
"{{1: 300, 5: 600, 10: 1200, 15: 3000}}"
"Example of valid formats:\n"
"{{1: 300, 5: 600, 10: 1200, 15: 3000}}\n"
"{{1: (1, 10), 5: (11, 20), 10: (21, 30), 15: (100, 300)}}"
).format(self.name)

@api.constrains("retry_pattern")
Expand All @@ -195,12 +198,20 @@
all_values = list(retry_pattern) + list(retry_pattern.values())
for value in all_values:
try:
int(value)
self._retry_value_type_check(value)
except ValueError:
raise exceptions.UserError(
record._retry_pattern_format_error_message()
)

def _retry_value_type_check(self, value):
if isinstance(value, (tuple, list)):
if len(value) != 2:
raise ValueError
[self._retry_value_type_check(element) for element in value]
return
int(value)
Comment on lines 202 to +213
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
except ValueError:
raise exceptions.UserError(
record._retry_pattern_format_error_message()
)
def _retry_value_type_check(self, value):
if isinstance(value, (tuple, list)):
if len(value) != 2:
raise ValueError
[self._retry_value_type_check(element) for element in value]
return
int(value)
except ValueError as exc:
raise exceptions.UserError(
record._retry_pattern_format_error_message()
) from exc
def _retry_value_type_check(self, value):
if isinstance(value, (tuple, list)):
if len(value) != 2:
raise ValueError("Random retry pattern must be a tuple with 2 digits")
[self._retry_value_type_check(element) for element in value]
return
int(value)


def _related_action_format_error_message(self):
return _(
"Unexpected format of Related Action for {}.\n"
Expand Down
1 change: 1 addition & 0 deletions test_queue_job/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
from . import test_job
from . import test_job_auto_delay
from . import test_job_channels
from . import test_job_function
from . import test_related_actions
from . import test_delay_mocks
35 changes: 35 additions & 0 deletions test_queue_job/tests/test_job_function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import odoo.tests.common as common
from odoo import exceptions


class TestJobFunction(common.TransactionCase):
def setUp(self):
super(TestJobFunction, self).setUp()
self.test_function_model = self.env.ref(
"queue_job.job_function_queue_job__test_job"
)

def test_check_retry_pattern_randomized_case(self):
randomized_pattern = "{1: (10, 20), 2: (20, 40)}"
self.test_function_model.edit_retry_pattern = randomized_pattern
self.assertEqual(
self.test_function_model.edit_retry_pattern, randomized_pattern
)

def test_check_retry_pattern_fixed_case(self):
fixed_pattern = "{1: 10, 2: 20}"
self.test_function_model.edit_retry_pattern = fixed_pattern
self.assertEqual(self.test_function_model.edit_retry_pattern, fixed_pattern)

def test_check_retry_pattern_invalid_cases(self):
invalid_time_value_pattern = "{1: a, 2: 20}"
with self.assertRaises(exceptions.UserError):
self.test_function_model.edit_retry_pattern = invalid_time_value_pattern

invalid_retry_count_pattern = "{a: 10, 2: 20}"
with self.assertRaises(exceptions.UserError):
self.test_function_model.edit_retry_pattern = invalid_retry_count_pattern

invalid_randomized_pattern = "{1: (1, 2, 3), 2: 20}"
with self.assertRaises(exceptions.UserError):
self.test_function_model.edit_retry_pattern = invalid_randomized_pattern
Loading