Skip to content

Commit 4cd0160

Browse files
committed
update
1 parent 7c430fe commit 4cd0160

File tree

1 file changed

+158
-40
lines changed

1 file changed

+158
-40
lines changed

tests/test_retries.py

Lines changed: 158 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import pytest
55

66
from databricks.sdk.errors import NotFound, ResourceDoesNotExist
7-
from databricks.sdk.retries import poll, retried, RetryError
7+
from databricks.sdk.retries import RetryError, poll, retried
88
from tests.clock import FakeClock
99

1010

@@ -79,38 +79,156 @@ def foo():
7979
@pytest.mark.parametrize(
8080
"scenario,attempts,result_value,exception_type,exception_msg,timeout,min_time,max_time",
8181
[
82-
pytest.param("success", 1, "immediate", None, None, 60, 0.0, 0.0,
83-
id="returns string immediately on first attempt with no sleep"),
84-
pytest.param("success", 2, 42, None, None, 60, 1.05, 1.75,
85-
id="returns integer after 1 retry with ~1s backoff"),
86-
pytest.param("success", 3, {"key": "val"}, None, None, 60, 3.10, 3.90,
87-
id="returns dict after 2 retries with linear backoff (1s+2s)"),
88-
pytest.param("success", 5, [1, 2], None, None, 60, 10.25, 11.75,
89-
id="returns list after 4 retries with linear backoff (1s+2s+3s+4s)"),
90-
pytest.param("success", 1, None, None, None, 60, 0.0, 0.0,
91-
id="returns None as valid result immediately (None is acceptable)"),
92-
pytest.param("success", 5, "ok", None, None, 200, 10.2, 13.0,
93-
id="verifies linear backoff increase over 4 retries"),
94-
pytest.param("success", 11, "ok", None, None, 200, 55.5, 62.5,
95-
id="verifies linear backoff approaching 10s cap over 10 retries"),
96-
pytest.param("success", 15, "ok", None, None, 200, 95.7, 105.5,
97-
id="verifies backoff is capped at 10s after 10th retry"),
98-
pytest.param("timeout", None, None, TimeoutError, "Timed out after", 1, 1, None,
99-
id="raises TimeoutError after 1 second of continuous retries"),
100-
pytest.param("timeout", None, None, TimeoutError, "Timed out after", 5, 5, None,
101-
id="raises TimeoutError after 5 seconds of continuous retries"),
102-
pytest.param("timeout", None, None, TimeoutError, "Timed out after", 15, 15, None,
103-
id="raises TimeoutError after 15 seconds of continuous retries"),
104-
pytest.param("halt", 1, None, ValueError, "halt error", 60, None, None,
105-
id="raises ValueError immediately when halt error on first attempt"),
106-
pytest.param("halt", 2, None, ValueError, "halt error", 60, None, None,
107-
id="raises ValueError after 1 retry when halt error on second attempt"),
108-
pytest.param("halt", 3, None, ValueError, "halt error", 60, None, None,
109-
id="raises ValueError after 2 retries when halt error on third attempt"),
110-
pytest.param("unexpected", 1, None, RuntimeError, "unexpected", 60, None, None,
111-
id="raises RuntimeError immediately on unexpected exception"),
112-
pytest.param("unexpected", 3, None, RuntimeError, "unexpected", 60, None, None,
113-
id="raises RuntimeError after 2 retries on unexpected exception"),
82+
pytest.param(
83+
"success",
84+
1,
85+
"immediate",
86+
None,
87+
None,
88+
60,
89+
0.0,
90+
0.0,
91+
id="returns string immediately on first attempt with no sleep",
92+
),
93+
pytest.param("success", 2, 42, None, None, 60, 1.05, 1.75, id="returns integer after 1 retry with ~1s backoff"),
94+
pytest.param(
95+
"success",
96+
3,
97+
{"key": "val"},
98+
None,
99+
None,
100+
60,
101+
3.10,
102+
3.90,
103+
id="returns dict after 2 retries with linear backoff (1s+2s)",
104+
),
105+
pytest.param(
106+
"success",
107+
5,
108+
[1, 2],
109+
None,
110+
None,
111+
60,
112+
10.25,
113+
11.75,
114+
id="returns list after 4 retries with linear backoff (1s+2s+3s+4s)",
115+
),
116+
pytest.param(
117+
"success",
118+
1,
119+
None,
120+
None,
121+
None,
122+
60,
123+
0.0,
124+
0.0,
125+
id="returns None as valid result immediately (None is acceptable)",
126+
),
127+
pytest.param(
128+
"success", 5, "ok", None, None, 200, 10.2, 13.0, id="verifies linear backoff increase over 4 retries"
129+
),
130+
pytest.param(
131+
"success",
132+
11,
133+
"ok",
134+
None,
135+
None,
136+
200,
137+
55.5,
138+
62.5,
139+
id="verifies linear backoff approaching 10s cap over 10 retries",
140+
),
141+
pytest.param(
142+
"success", 15, "ok", None, None, 200, 95.7, 105.5, id="verifies backoff is capped at 10s after 10th retry"
143+
),
144+
pytest.param(
145+
"timeout",
146+
None,
147+
None,
148+
TimeoutError,
149+
"Timed out after",
150+
1,
151+
1,
152+
None,
153+
id="raises TimeoutError after 1 second of continuous retries",
154+
),
155+
pytest.param(
156+
"timeout",
157+
None,
158+
None,
159+
TimeoutError,
160+
"Timed out after",
161+
5,
162+
5,
163+
None,
164+
id="raises TimeoutError after 5 seconds of continuous retries",
165+
),
166+
pytest.param(
167+
"timeout",
168+
None,
169+
None,
170+
TimeoutError,
171+
"Timed out after",
172+
15,
173+
15,
174+
None,
175+
id="raises TimeoutError after 15 seconds of continuous retries",
176+
),
177+
pytest.param(
178+
"halt",
179+
1,
180+
None,
181+
ValueError,
182+
"halt error",
183+
60,
184+
None,
185+
None,
186+
id="raises ValueError immediately when halt error on first attempt",
187+
),
188+
pytest.param(
189+
"halt",
190+
2,
191+
None,
192+
ValueError,
193+
"halt error",
194+
60,
195+
None,
196+
None,
197+
id="raises ValueError after 1 retry when halt error on second attempt",
198+
),
199+
pytest.param(
200+
"halt",
201+
3,
202+
None,
203+
ValueError,
204+
"halt error",
205+
60,
206+
None,
207+
None,
208+
id="raises ValueError after 2 retries when halt error on third attempt",
209+
),
210+
pytest.param(
211+
"unexpected",
212+
1,
213+
None,
214+
RuntimeError,
215+
"unexpected",
216+
60,
217+
None,
218+
None,
219+
id="raises RuntimeError immediately on unexpected exception",
220+
),
221+
pytest.param(
222+
"unexpected",
223+
3,
224+
None,
225+
RuntimeError,
226+
"unexpected",
227+
60,
228+
None,
229+
None,
230+
id="raises RuntimeError after 2 retries on unexpected exception",
231+
),
114232
],
115233
)
116234
def test_poll_behavior(
@@ -137,20 +255,20 @@ def test_poll_behavior(
137255
def fn() -> tuple[Any, Optional[RetryError]]:
138256
nonlocal call_count
139257
call_count += 1
140-
258+
141259
if scenario == "success":
142260
if call_count < attempts:
143261
return None, RetryError.continues(f"attempt {call_count}")
144262
return result_value, None
145-
263+
146264
elif scenario == "timeout":
147265
return None, RetryError.continues("retrying")
148-
266+
149267
elif scenario == "halt":
150-
if call_count < attempts:
268+
if call_count < attempts:
151269
return None, RetryError.continues("retrying")
152270
return None, RetryError.halt(ValueError(exception_msg))
153-
271+
154272
elif scenario == "unexpected":
155273
if call_count < attempts:
156274
return None, RetryError.continues("retrying")
@@ -167,10 +285,10 @@ def fn() -> tuple[Any, Optional[RetryError]]:
167285
else:
168286
with pytest.raises(exception_type) as exc_info:
169287
poll(fn, timeout=timedelta(seconds=timeout), clock=clock)
170-
288+
171289
assert exception_msg in str(exc_info.value)
172290
assert call_count >= 1
173-
291+
174292
if scenario == "timeout":
175293
assert clock.time() >= min_time - 1
176294
elif scenario in ("halt", "unexpected"):

0 commit comments

Comments
 (0)