iker-python-common 1.0.65__tar.gz → 1.0.66__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/PKG-INFO +1 -1
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/config.py +2 -2
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/retry.py +35 -48
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/shutils.py +0 -3
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker_python_common.egg-info/PKG-INFO +1 -1
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/retry_test.py +10 -12
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/.editorconfig +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/.github/workflows/pr.yml +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/.github/workflows/push.yml +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/.gitignore +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/MANIFEST.in +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/README.md +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/VERSION +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/pyproject.toml +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/config/config.cfg +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/csv/data.csv +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/csv/data.tsv +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.baz/file.bar.baz +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.baz/file.foo.bar +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.baz/file.foo.baz +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.foo/file.bar +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.foo/file.baz +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.foo/file.foo +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/setup.cfg +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/setup.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/__init__.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/__init__.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/argutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/csv.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/dbutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/dtutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/funcutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/iterutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/jsonutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/logger.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/numutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/randutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/span.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/strutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/testutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker/common/utils/typeutils.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker_python_common.egg-info/SOURCES.txt +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker_python_common.egg-info/dependency_links.txt +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker_python_common.egg-info/not-zip-safe +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker_python_common.egg-info/requires.txt +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker_python_common.egg-info/top_level.txt +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/__init__.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/argutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/config_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/csv_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/dbutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/dtutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/funcutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/iterutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/jsonutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/logger_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/numutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/randutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/shutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/span_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/strutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/testutils_test.py +0 -0
- {iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/typeutils_test.py +0 -0
|
@@ -31,7 +31,7 @@ class Config(object):
|
|
|
31
31
|
self.config_parser.read(self.config_path, encoding="utf-8")
|
|
32
32
|
return True
|
|
33
33
|
except IOError as e:
|
|
34
|
-
logger.exception("Failed to restore config from file
|
|
34
|
+
logger.exception("Failed to restore config from file '%s'", self.config_path)
|
|
35
35
|
return False
|
|
36
36
|
|
|
37
37
|
def persist(self) -> bool:
|
|
@@ -42,7 +42,7 @@ class Config(object):
|
|
|
42
42
|
self.config_parser.write(fh)
|
|
43
43
|
return True
|
|
44
44
|
except IOError as e:
|
|
45
|
-
logger.exception("Failed to persist config to file
|
|
45
|
+
logger.exception("Failed to persist config to file '%s'", self.config_path)
|
|
46
46
|
return False
|
|
47
47
|
|
|
48
48
|
def has_section(self, section: str) -> bool:
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import abc
|
|
2
|
-
import random
|
|
3
2
|
import time
|
|
3
|
+
from collections.abc import Callable
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
5
6
|
from iker.common.utils import logger
|
|
6
7
|
from iker.common.utils.dtutils import dt_utc_now
|
|
8
|
+
from iker.common.utils.randutils import randomizer
|
|
7
9
|
|
|
8
10
|
__all__ = [
|
|
9
11
|
"Attempt",
|
|
@@ -68,12 +70,9 @@ class Retry(abc.ABC):
|
|
|
68
70
|
class RetryWrapper(object):
|
|
69
71
|
def __init__(
|
|
70
72
|
self,
|
|
71
|
-
|
|
73
|
+
target: Callable[..., Any] | Retry,
|
|
72
74
|
wait: int = None,
|
|
73
|
-
|
|
74
|
-
wait_exponent_max: int = None,
|
|
75
|
-
wait_random_min: int = None,
|
|
76
|
-
wait_random_max: int = None,
|
|
75
|
+
wait_func: Callable[[int], int] = None,
|
|
77
76
|
retrials: int = None,
|
|
78
77
|
timeout: int = None,
|
|
79
78
|
):
|
|
@@ -81,21 +80,15 @@ class RetryWrapper(object):
|
|
|
81
80
|
Retry executor that wraps a callable or ``Retry`` instance, providing flexible retry strategies including fixed,
|
|
82
81
|
exponential, and random waits.
|
|
83
82
|
|
|
84
|
-
:param
|
|
83
|
+
:param target: The target callable or ``Retry`` instance to execute.
|
|
85
84
|
:param wait: Fixed wait time (in seconds) between retrials.
|
|
86
|
-
:param
|
|
87
|
-
:param wait_exponent_max: Maximum wait time for exponential backoff.
|
|
88
|
-
:param wait_random_min: Minimum wait time for random backoff.
|
|
89
|
-
:param wait_random_max: Maximum wait time for random backoff.
|
|
85
|
+
:param wait_func: Function to determine wait time based on attempt number.
|
|
90
86
|
:param retrials: Maximum number of retrials (``None`` for unlimited).
|
|
91
87
|
:param timeout: Maximum total time (in seconds) allowed for all attempts (``None`` for unlimited).
|
|
92
88
|
"""
|
|
93
|
-
self.
|
|
89
|
+
self.target = target
|
|
94
90
|
self.wait = wait
|
|
95
|
-
self.
|
|
96
|
-
self.wait_exponent_max = wait_exponent_max
|
|
97
|
-
self.wait_random_min = wait_random_min
|
|
98
|
-
self.wait_random_max = wait_random_max
|
|
91
|
+
self.wait_func = wait_func
|
|
99
92
|
self.retrials = retrials
|
|
100
93
|
self.timeout = timeout
|
|
101
94
|
|
|
@@ -107,9 +100,9 @@ class RetryWrapper(object):
|
|
|
107
100
|
:param kwargs: Keyword arguments for the operation.
|
|
108
101
|
:return: The result of the operation.
|
|
109
102
|
"""
|
|
110
|
-
return self.
|
|
103
|
+
return self.run(*args, **kwargs)
|
|
111
104
|
|
|
112
|
-
def
|
|
105
|
+
def next_wait(self, attempt_number: int):
|
|
113
106
|
"""
|
|
114
107
|
Determines the wait time before the next retry attempt based on the configured strategy.
|
|
115
108
|
|
|
@@ -118,16 +111,13 @@ class RetryWrapper(object):
|
|
|
118
111
|
"""
|
|
119
112
|
if attempt_number <= 0:
|
|
120
113
|
return None
|
|
121
|
-
|
|
114
|
+
if self.wait is not None:
|
|
122
115
|
return self.wait
|
|
123
|
-
|
|
124
|
-
return
|
|
125
|
-
|
|
126
|
-
return random.randint(self.wait_random_min, self.wait_random_max)
|
|
127
|
-
else:
|
|
128
|
-
return 0
|
|
116
|
+
if self.wait_func is not None:
|
|
117
|
+
return self.wait_func(attempt_number)
|
|
118
|
+
return 0
|
|
129
119
|
|
|
130
|
-
def
|
|
120
|
+
def check_timeout(self, start_ts: float) -> tuple[bool, float]:
|
|
131
121
|
"""
|
|
132
122
|
Checks if the retry operation has exceeded the configured timeout.
|
|
133
123
|
|
|
@@ -139,7 +129,7 @@ class RetryWrapper(object):
|
|
|
139
129
|
return True, current_ts
|
|
140
130
|
return current_ts < start_ts + self.timeout, current_ts
|
|
141
131
|
|
|
142
|
-
def
|
|
132
|
+
def run(self, *args, **kwargs):
|
|
143
133
|
"""
|
|
144
134
|
Runs the retry loop, invoking the wrapped callable or ``Retry`` instance until success, retrials exhausted, or
|
|
145
135
|
timeout reached.
|
|
@@ -156,31 +146,30 @@ class RetryWrapper(object):
|
|
|
156
146
|
while self.retrials is None or attempt_number <= self.retrials:
|
|
157
147
|
attempt_number += 1
|
|
158
148
|
|
|
159
|
-
check_result, check_ts = self.
|
|
149
|
+
check_result, check_ts = self.check_timeout(start_ts)
|
|
160
150
|
if not check_result:
|
|
161
151
|
break
|
|
162
152
|
|
|
163
153
|
attempt = Attempt(
|
|
164
154
|
attempt_number,
|
|
165
|
-
self.
|
|
166
|
-
self.
|
|
155
|
+
self.next_wait(attempt_number - 1),
|
|
156
|
+
self.next_wait(attempt_number),
|
|
167
157
|
start_ts,
|
|
168
158
|
check_ts,
|
|
169
159
|
last_exception,
|
|
170
160
|
)
|
|
171
161
|
try:
|
|
172
|
-
if isinstance(self.
|
|
173
|
-
self.
|
|
174
|
-
return self.
|
|
162
|
+
if isinstance(self.target, Retry):
|
|
163
|
+
self.target.on_attempt(attempt)
|
|
164
|
+
return self.target.execute(*args, **kwargs)
|
|
175
165
|
else:
|
|
176
|
-
return self.
|
|
166
|
+
return self.target(*args, **kwargs)
|
|
177
167
|
except Exception as e:
|
|
178
|
-
logger.exception("Function target
|
|
168
|
+
logger.exception("Function target '%s' failed on attempt '%d'", self.target, attempt_number)
|
|
179
169
|
last_exception = e
|
|
180
|
-
time.sleep(self.
|
|
170
|
+
time.sleep(self.next_wait(attempt_number))
|
|
181
171
|
|
|
182
|
-
raise RuntimeError(
|
|
183
|
-
"failed to execute function target <%s> after <%d> attempts" % (self.__wrapped, attempt_number))
|
|
172
|
+
raise RuntimeError(f"failed to execute function target '{self.target}' after '{attempt_number}' attempts")
|
|
184
173
|
|
|
185
174
|
|
|
186
175
|
def retry(wait: int = None, retrials: int = None, timeout: int = None):
|
|
@@ -199,12 +188,12 @@ def retry(wait: int = None, retrials: int = None, timeout: int = None):
|
|
|
199
188
|
return wrapper
|
|
200
189
|
|
|
201
190
|
|
|
202
|
-
def retry_exponent(
|
|
191
|
+
def retry_exponent(wait_init: int, wait_max: int, retrials: int = None, timeout: int = None):
|
|
203
192
|
"""
|
|
204
193
|
Decorator to apply exponential backoff retry logic to a function or callable.
|
|
205
194
|
|
|
206
|
-
:param
|
|
207
|
-
:param
|
|
195
|
+
:param wait_init: Initial wait time for exponential backoff.
|
|
196
|
+
:param wait_max: Maximum wait time for exponential backoff.
|
|
208
197
|
:param retrials: Maximum number of retrials (``None`` for unlimited).
|
|
209
198
|
:param timeout: Maximum total time (in seconds) allowed for all attempts (``None`` for unlimited).
|
|
210
199
|
:return: A decorated function with retry logic.
|
|
@@ -213,8 +202,7 @@ def retry_exponent(wait_exponent_init: int, wait_exponent_max: int, retrials: in
|
|
|
213
202
|
def wrapper(target):
|
|
214
203
|
return RetryWrapper(
|
|
215
204
|
target,
|
|
216
|
-
|
|
217
|
-
wait_exponent_max=wait_exponent_max,
|
|
205
|
+
wait_func=lambda x: min(wait_init * (2 ** (x - 1)), wait_max),
|
|
218
206
|
retrials=retrials,
|
|
219
207
|
timeout=timeout,
|
|
220
208
|
)
|
|
@@ -222,12 +210,12 @@ def retry_exponent(wait_exponent_init: int, wait_exponent_max: int, retrials: in
|
|
|
222
210
|
return wrapper
|
|
223
211
|
|
|
224
212
|
|
|
225
|
-
def retry_random(
|
|
213
|
+
def retry_random(wait_min: int, wait_max: int, retrials: int = None, timeout: int = None):
|
|
226
214
|
"""
|
|
227
215
|
Decorator to apply random wait retry logic to a function or callable.
|
|
228
216
|
|
|
229
|
-
:param
|
|
230
|
-
:param
|
|
217
|
+
:param wait_min: Minimum wait time for random backoff.
|
|
218
|
+
:param wait_max: Maximum wait time for random backoff.
|
|
231
219
|
:param retrials: Maximum number of retrials (``None`` for unlimited).
|
|
232
220
|
:param timeout: Maximum total time (in seconds) allowed for all attempts (``None`` for unlimited).
|
|
233
221
|
:return: A decorated function with retry logic.
|
|
@@ -236,8 +224,7 @@ def retry_random(wait_random_min: int, wait_random_max: int, retrials: int = Non
|
|
|
236
224
|
def wrapper(target):
|
|
237
225
|
return RetryWrapper(
|
|
238
226
|
target,
|
|
239
|
-
|
|
240
|
-
wait_random_max=wait_random_max,
|
|
227
|
+
wait_func=lambda x: randomizer().next_int(wait_min, wait_max),
|
|
241
228
|
retrials=retrials,
|
|
242
229
|
timeout=timeout,
|
|
243
230
|
)
|
|
@@ -3,7 +3,6 @@ import os
|
|
|
3
3
|
import shutil
|
|
4
4
|
from typing import Protocol
|
|
5
5
|
|
|
6
|
-
from iker.common.utils import logger
|
|
7
6
|
from iker.common.utils.iterutils import last, last_or_none, tail_iter
|
|
8
7
|
from iker.common.utils.strutils import is_empty
|
|
9
8
|
|
|
@@ -212,7 +211,6 @@ def run(cmd: str) -> bool:
|
|
|
212
211
|
:param cmd: Command to run.
|
|
213
212
|
:return: ``True`` if the command has been successfully run, ``False`` otherwise.
|
|
214
213
|
"""
|
|
215
|
-
logger.debug("Running command: %s", cmd)
|
|
216
214
|
return os.system(cmd) == 0
|
|
217
215
|
|
|
218
216
|
|
|
@@ -224,7 +222,6 @@ def execute(cmd: str, strip: bool = True) -> str:
|
|
|
224
222
|
:param strip: If ``True``, the contents will be stripped.
|
|
225
223
|
:return: The content from standard output.
|
|
226
224
|
"""
|
|
227
|
-
logger.debug("Executing command: %s", cmd)
|
|
228
225
|
if strip:
|
|
229
226
|
return os.popen(cmd).read().strip()
|
|
230
227
|
return os.popen(cmd).read()
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/retry_test.py
RENAMED
|
@@ -125,11 +125,10 @@ class RetryTest(unittest.TestCase):
|
|
|
125
125
|
|
|
126
126
|
@ddt.idata(data_retry_exponent)
|
|
127
127
|
@ddt.unpack
|
|
128
|
-
def test_retry_exponent(self, content,
|
|
128
|
+
def test_retry_exponent(self, content, wait_init, wait_max, retrials):
|
|
129
129
|
result = []
|
|
130
130
|
|
|
131
|
-
@retry.retry_exponent(
|
|
132
|
-
retrials=retrials)
|
|
131
|
+
@retry.retry_exponent(wait_init=wait_init, wait_max=wait_max, retrials=retrials)
|
|
133
132
|
def callee(text):
|
|
134
133
|
result.append(text)
|
|
135
134
|
raise ValueError("dummy value error")
|
|
@@ -147,7 +146,7 @@ class RetryTest(unittest.TestCase):
|
|
|
147
146
|
|
|
148
147
|
@ddt.idata(data_retry_exponent__on_retry_instance)
|
|
149
148
|
@ddt.unpack
|
|
150
|
-
def test_retry_exponent__on_retry_instance(self, content,
|
|
149
|
+
def test_retry_exponent__on_retry_instance(self, content, wait_init, wait_max, retrials):
|
|
151
150
|
result = []
|
|
152
151
|
|
|
153
152
|
class Callee(retry.Retry):
|
|
@@ -164,11 +163,10 @@ class RetryTest(unittest.TestCase):
|
|
|
164
163
|
callee = Callee()
|
|
165
164
|
|
|
166
165
|
with self.assertRaises(RuntimeError):
|
|
167
|
-
retry.retry_exponent(
|
|
166
|
+
retry.retry_exponent(wait_init, wait_max, retrials)(callee)(content)
|
|
168
167
|
|
|
169
168
|
self.assertEqual([content for _ in range(retrials + 1)], result)
|
|
170
|
-
self.assertTrue(all(
|
|
171
|
-
a.next_wait == min(wait_exponent_init * (2 ** (a.number - 1)), wait_exponent_max) for a in callee.attempts))
|
|
169
|
+
self.assertTrue(all(a.next_wait == min(wait_init * (2 ** (a.number - 1)), wait_max) for a in callee.attempts))
|
|
172
170
|
|
|
173
171
|
data_retry_random = [
|
|
174
172
|
("dummy-content", 1, 4, 3),
|
|
@@ -178,10 +176,10 @@ class RetryTest(unittest.TestCase):
|
|
|
178
176
|
|
|
179
177
|
@ddt.idata(data_retry_random)
|
|
180
178
|
@ddt.unpack
|
|
181
|
-
def test_retry_random(self, content,
|
|
179
|
+
def test_retry_random(self, content, wait_min, wait_max, retrials):
|
|
182
180
|
result = []
|
|
183
181
|
|
|
184
|
-
@retry.retry_random(
|
|
182
|
+
@retry.retry_random(wait_min=wait_min, wait_max=wait_max, retrials=retrials)
|
|
185
183
|
def callee(text):
|
|
186
184
|
result.append(text)
|
|
187
185
|
raise ValueError("dummy value error")
|
|
@@ -199,7 +197,7 @@ class RetryTest(unittest.TestCase):
|
|
|
199
197
|
|
|
200
198
|
@ddt.idata(data_retry_random__on_retry_instance)
|
|
201
199
|
@ddt.unpack
|
|
202
|
-
def test_retry_random__on_retry_instance(self, content,
|
|
200
|
+
def test_retry_random__on_retry_instance(self, content, wait_min, wait_max, retrials):
|
|
203
201
|
result = []
|
|
204
202
|
|
|
205
203
|
class Callee(retry.Retry):
|
|
@@ -216,7 +214,7 @@ class RetryTest(unittest.TestCase):
|
|
|
216
214
|
callee = Callee()
|
|
217
215
|
|
|
218
216
|
with self.assertRaises(RuntimeError):
|
|
219
|
-
retry.retry_random(
|
|
217
|
+
retry.retry_random(wait_min, wait_max, retrials)(callee)(content)
|
|
220
218
|
|
|
221
219
|
self.assertEqual([content for _ in range(retrials + 1)], result)
|
|
222
|
-
self.assertTrue(all(
|
|
220
|
+
self.assertTrue(all(wait_min <= a.next_wait <= wait_max for a in callee.attempts))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/config/config.cfg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.foo/file.bar
RENAMED
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.foo/file.baz
RENAMED
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/resources/unittest/shutils/dir.foo/file.foo
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker_python_common.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker_python_common.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/src/iker_python_common.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/config_test.py
RENAMED
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/csv_test.py
RENAMED
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/dbutils_test.py
RENAMED
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/dtutils_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/logger_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/shutils_test.py
RENAMED
|
File without changes
|
{iker_python_common-1.0.65 → iker_python_common-1.0.66}/test/iker_tests/common/utils/span_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|