Skip to content

Commit 8db51bb

Browse files
committed
Fixing flaky test + exclude cache enabled test for servers <7.4
1 parent 3768c42 commit 8db51bb

2 files changed

Lines changed: 57 additions & 61 deletions

File tree

tests/maint_notifications/test_cluster_maint_notifications_handling.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ def test_oss_maint_handler_propagation(self):
411411
conn, cluster, cluster.maint_notifications_config
412412
)
413413

414+
@skip_if_server_version_lt("7.4.0")
414415
def test_oss_maint_handler_propagation_cache_enabled(self):
415416
"""Test that OSSMaintNotificationsHandler is propagated to all connections."""
416417
cluster = self._create_cluster_client(enable_cache=True)

tests/test_auth/test_token_manager.py

Lines changed: 56 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import asyncio
22
from datetime import datetime, timezone
33
from time import sleep
4-
from unittest.mock import AsyncMock, Mock
4+
from unittest.mock import Mock
55

66
import pytest
77
from redis.auth.err import RequestTokenErr, TokenRenewalErr
@@ -29,48 +29,38 @@ class TestTokenManager:
2929
)
3030
def test_success_token_renewal(self, exp_refresh_ratio):
3131
tokens = []
32+
errors = []
33+
34+
# Use a function to generate fresh tokens at request time
35+
# to avoid timing issues on slow CI runners
36+
def generate_token():
37+
now = datetime.now(timezone.utc).timestamp() * 1000
38+
return SimpleToken("value", now + 10000, now, {"oid": "test"})
39+
3240
mock_provider = Mock(spec=IdentityProviderInterface)
33-
mock_provider.request_token.side_effect = [
34-
SimpleToken(
35-
"value",
36-
(datetime.now(timezone.utc).timestamp() * 1000) + 100,
37-
(datetime.now(timezone.utc).timestamp() * 1000),
38-
{"oid": "test"},
39-
),
40-
SimpleToken(
41-
"value",
42-
(datetime.now(timezone.utc).timestamp() * 1000) + 150,
43-
(datetime.now(timezone.utc).timestamp() * 1000) + 50,
44-
{"oid": "test"},
45-
),
46-
SimpleToken(
47-
"value",
48-
(datetime.now(timezone.utc).timestamp() * 1000) + 170,
49-
(datetime.now(timezone.utc).timestamp() * 1000) + 70,
50-
{"oid": "test"},
51-
),
52-
SimpleToken(
53-
"value",
54-
(datetime.now(timezone.utc).timestamp() * 1000) + 190,
55-
(datetime.now(timezone.utc).timestamp() * 1000) + 90,
56-
{"oid": "test"},
57-
),
58-
]
41+
mock_provider.request_token.side_effect = (
42+
lambda *args, **kwargs: generate_token()
43+
)
5944

6045
def on_next(token):
6146
nonlocal tokens
6247
tokens.append(token)
6348

49+
def on_error(err):
50+
nonlocal errors
51+
errors.append(err)
52+
6453
mock_listener = Mock(spec=CredentialsListener)
6554
mock_listener.on_next = on_next
66-
mock_listener.on_error = AsyncMock() # Add this line
55+
mock_listener.on_error = on_error
6756

6857
retry_policy = RetryPolicy(1, 10)
6958
config = TokenManagerConfig(exp_refresh_ratio, 0, 1000, retry_policy)
7059
mgr = TokenManager(mock_provider, config)
7160
mgr.start(mock_listener)
7261
sleep(0.1)
7362

63+
assert len(errors) == 0, f"Unexpected errors: {errors}"
7464
assert len(tokens) > 0
7565

7666
@pytest.mark.parametrize(
@@ -247,30 +237,32 @@ async def on_next(token):
247237

248238
def test_success_token_renewal_with_retry(self):
249239
tokens = []
240+
errors = []
241+
call_count = [0]
242+
243+
# Use a function to generate fresh tokens at request time
244+
# to avoid timing issues on slow CI runners
245+
def request_token_side_effect(*args, **kwargs):
246+
call_count[0] += 1
247+
if call_count[0] <= 2:
248+
raise RequestTokenErr("Simulated failure")
249+
now = datetime.now(timezone.utc).timestamp() * 1000
250+
return SimpleToken("value", now + 10000, now, {"oid": "test"})
251+
250252
mock_provider = Mock(spec=IdentityProviderInterface)
251-
mock_provider.request_token.side_effect = [
252-
RequestTokenErr,
253-
RequestTokenErr,
254-
SimpleToken(
255-
"value",
256-
(datetime.now(timezone.utc).timestamp() * 1000) + 100,
257-
(datetime.now(timezone.utc).timestamp() * 1000),
258-
{"oid": "test"},
259-
),
260-
SimpleToken(
261-
"value",
262-
(datetime.now(timezone.utc).timestamp() * 1000) + 100,
263-
(datetime.now(timezone.utc).timestamp() * 1000),
264-
{"oid": "test"},
265-
),
266-
]
253+
mock_provider.request_token.side_effect = request_token_side_effect
267254

268255
def on_next(token):
269256
nonlocal tokens
270257
tokens.append(token)
271258

259+
def on_error(err):
260+
nonlocal errors
261+
errors.append(err)
262+
272263
mock_listener = Mock(spec=CredentialsListener)
273264
mock_listener.on_next = on_next
265+
mock_listener.on_error = on_error
274266

275267
retry_policy = RetryPolicy(3, 10)
276268
config = TokenManagerConfig(1, 0, 1000, retry_policy)
@@ -280,37 +272,39 @@ def on_next(token):
280272
# due to additional token renewal.
281273
sleep(0.08)
282274

275+
assert len(errors) == 0, f"Unexpected errors: {errors}"
283276
assert mock_provider.request_token.call_count > 0
284277
assert len(tokens) > 0
285278

286279
@pytest.mark.asyncio
287280
async def test_async_success_token_renewal_with_retry(self):
288281
tokens = []
282+
errors = []
283+
call_count = [0]
284+
285+
# Use a function to generate fresh tokens at request time
286+
# to avoid timing issues on slow CI runners
287+
def request_token_side_effect(*args, **kwargs):
288+
call_count[0] += 1
289+
if call_count[0] <= 2:
290+
raise RequestTokenErr("Simulated failure")
291+
now = datetime.now(timezone.utc).timestamp() * 1000
292+
return SimpleToken("value", now + 10000, now, {"oid": "test"})
293+
289294
mock_provider = Mock(spec=IdentityProviderInterface)
290-
mock_provider.request_token.side_effect = [
291-
RequestTokenErr,
292-
RequestTokenErr,
293-
SimpleToken(
294-
"value",
295-
(datetime.now(timezone.utc).timestamp() * 1000) + 100,
296-
(datetime.now(timezone.utc).timestamp() * 1000),
297-
{"oid": "test"},
298-
),
299-
SimpleToken(
300-
"value",
301-
(datetime.now(timezone.utc).timestamp() * 1000) + 100,
302-
(datetime.now(timezone.utc).timestamp() * 1000),
303-
{"oid": "test"},
304-
),
305-
]
295+
mock_provider.request_token.side_effect = request_token_side_effect
306296

307297
async def on_next(token):
308298
nonlocal tokens
309299
tokens.append(token)
310300

301+
async def on_error(err):
302+
nonlocal errors
303+
errors.append(err)
304+
311305
mock_listener = Mock(spec=CredentialsListener)
312306
mock_listener.on_next = on_next
313-
mock_listener.on_error = None
307+
mock_listener.on_error = on_error
314308

315309
retry_policy = RetryPolicy(3, 10)
316310
config = TokenManagerConfig(1, 0, 1000, retry_policy)
@@ -320,6 +314,7 @@ async def on_next(token):
320314
# due to additional token renewal.
321315
await asyncio.sleep(0.08)
322316

317+
assert len(errors) == 0, f"Unexpected errors: {errors}"
323318
assert mock_provider.request_token.call_count > 0
324319
assert len(tokens) > 0
325320

0 commit comments

Comments
 (0)