Skip to content

Commit b59fd97

Browse files
committed
test(embedding): тесты retry для embedding провайдеров и backward compat
- test_embedding_retry_integration: OpenAI и VikingDB retry на transient/permanent ошибки - test_retry_config: VLMConfig и EmbeddingConfig max_retries поля и defaults - test_backward_compat: exponential_backoff_retry importable, signature unchanged, time-based
1 parent ced4ce8 commit b59fd97

File tree

3 files changed

+493
-0
lines changed

3 files changed

+493
-0
lines changed

tests/unit/test_backward_compat.py

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
"""Backward compatibility tests for the retry migration.
5+
6+
Verifies that:
7+
- exponential_backoff_retry is still importable from the old location (base.py)
8+
- exponential_backoff_retry signature is unchanged
9+
- exponential_backoff_retry behaviour still works (time-based)
10+
- transient_retry is count-based (different semantics)
11+
"""
12+
13+
from __future__ import annotations
14+
15+
import inspect
16+
import time
17+
from unittest.mock import patch
18+
19+
import pytest
20+
21+
22+
class _HttpError(Exception):
23+
"""Fake HTTP error carrying a numeric status code."""
24+
25+
def __init__(self, status_code: int, message: str = ""):
26+
super().__init__(message or f"HTTP {status_code}")
27+
self.status_code = status_code
28+
29+
30+
class TestExponentialBackoffRetryImportable:
31+
32+
def test_importable_from_old_location(self):
33+
"""exponential_backoff_retry should still be importable from base.py."""
34+
from openviking.models.embedder.base import exponential_backoff_retry
35+
36+
assert callable(exponential_backoff_retry)
37+
38+
39+
class TestExponentialBackoffRetrySignature:
40+
41+
def test_signature_unchanged(self):
42+
"""exponential_backoff_retry should retain its original signature."""
43+
from openviking.models.embedder.base import exponential_backoff_retry
44+
45+
sig = inspect.signature(exponential_backoff_retry)
46+
param_names = list(sig.parameters.keys())
47+
48+
expected_params = [
49+
"func",
50+
"max_wait",
51+
"base_delay",
52+
"max_delay",
53+
"jitter",
54+
"is_retryable",
55+
"logger",
56+
]
57+
58+
assert param_names == expected_params, (
59+
f"exponential_backoff_retry signature changed.\n"
60+
f"Expected: {expected_params}\n"
61+
f"Got: {param_names}"
62+
)
63+
64+
def test_defaults_unchanged(self):
65+
"""Default parameter values should be preserved."""
66+
from openviking.models.embedder.base import exponential_backoff_retry
67+
68+
sig = inspect.signature(exponential_backoff_retry)
69+
params = sig.parameters
70+
71+
assert params["max_wait"].default == 10.0
72+
assert params["base_delay"].default == 0.5
73+
assert params["max_delay"].default == 2.0
74+
assert params["jitter"].default is True
75+
assert params["is_retryable"].default is None
76+
assert params["logger"].default is None
77+
78+
79+
class TestExponentialBackoffRetryBehavior:
80+
81+
def test_success_first_try(self):
82+
"""Function succeeds on first attempt."""
83+
from openviking.models.embedder.base import exponential_backoff_retry
84+
85+
call_count = 0
86+
87+
def fn():
88+
nonlocal call_count
89+
call_count += 1
90+
return "ok"
91+
92+
result = exponential_backoff_retry(fn)
93+
assert result == "ok"
94+
assert call_count == 1
95+
96+
def test_retries_on_failure(self):
97+
"""Function retries on failure until success."""
98+
from openviking.models.embedder.base import exponential_backoff_retry
99+
100+
errors = [Exception("fail"), Exception("fail")]
101+
call_count = 0
102+
103+
def fn():
104+
nonlocal call_count
105+
call_count += 1
106+
if errors:
107+
raise errors.pop(0)
108+
return "ok"
109+
110+
with patch("time.sleep"):
111+
result = exponential_backoff_retry(fn, max_wait=10.0)
112+
113+
assert result == "ok"
114+
assert call_count == 3
115+
116+
def test_is_time_based(self):
117+
"""exponential_backoff_retry should be time-based (uses max_wait, not count)."""
118+
from openviking.models.embedder.base import exponential_backoff_retry
119+
120+
sig = inspect.signature(exponential_backoff_retry)
121+
param_names = list(sig.parameters.keys())
122+
123+
# Time-based: has max_wait, no max_retries
124+
assert "max_wait" in param_names
125+
assert "max_retries" not in param_names
126+
127+
def test_respects_is_retryable(self):
128+
"""exponential_backoff_retry should respect is_retryable callback."""
129+
from openviking.models.embedder.base import exponential_backoff_retry
130+
131+
call_count = 0
132+
133+
def fn():
134+
nonlocal call_count
135+
call_count += 1
136+
raise ValueError("permanent")
137+
138+
# is_retryable returns False => no retry
139+
with patch("time.sleep"):
140+
with pytest.raises(ValueError):
141+
exponential_backoff_retry(fn, is_retryable=lambda e: False)
142+
143+
assert call_count == 1
144+
145+
146+
class TestTransientRetryIsCountBased:
147+
148+
def test_is_count_based(self):
149+
"""transient_retry should be count-based (uses max_retries, not max_wait)."""
150+
from openviking.models.retry import transient_retry
151+
152+
sig = inspect.signature(transient_retry)
153+
param_names = list(sig.parameters.keys())
154+
155+
# Count-based: has max_retries, no max_wait
156+
assert "max_retries" in param_names
157+
assert "max_wait" not in param_names
158+
159+
def test_different_from_backoff_retry(self):
160+
"""transient_retry and exponential_backoff_retry should have different signatures."""
161+
from openviking.models.embedder.base import exponential_backoff_retry
162+
from openviking.models.retry import transient_retry
163+
164+
backoff_params = set(inspect.signature(exponential_backoff_retry).parameters.keys())
165+
retry_params = set(inspect.signature(transient_retry).parameters.keys())
166+
167+
# They share 'func', 'base_delay', 'max_delay', 'jitter', 'is_retryable'
168+
# but differ on time vs count control params
169+
assert "max_wait" in backoff_params
170+
assert "max_wait" not in retry_params
171+
assert "max_retries" in retry_params
172+
assert "max_retries" not in backoff_params

0 commit comments

Comments
 (0)