1
1
import asyncio
2
2
import json
3
3
import logging
4
+ import threading
4
5
import time
5
6
from collections .abc import AsyncIterator , Generator , Iterator
6
7
from datetime import datetime , timedelta
65
66
66
67
@pytest .fixture
67
68
def mock_api () -> None :
69
+ test_server_lock = threading .Lock ()
70
+
68
71
def get_responses () -> Generator [httpx .Response , None , None ]:
69
72
"""Simulate actor run that changes status 3 times."""
70
73
for _ in range (5 ):
@@ -116,8 +119,11 @@ def get_responses() -> Generator[httpx.Response, None, None]:
116
119
responses = get_responses ()
117
120
118
121
def actor_runs_side_effect (_ : httpx .Request ) -> httpx .Response :
119
- time .sleep (0.1 )
120
- return next (responses )
122
+ test_server_lock .acquire ()
123
+ # To avoid multiple threads accessing at the same time and causing `ValueError: generator already executing`
124
+ response = next (responses )
125
+ test_server_lock .release_lock ()
126
+ return response
121
127
122
128
respx .get (url = f'{ _MOCKED_API_URL } /v2/actor-runs/{ _MOCKED_RUN_ID } ' ).mock (side_effect = actor_runs_side_effect )
123
129
@@ -212,10 +218,10 @@ async def test_redirected_logs_async(
212
218
# Do stuff while the log from the other Actor is being redirected to the logs.
213
219
await asyncio .sleep (2 )
214
220
215
- assert len ( caplog . records ) == expected_log_count
216
- for expected_message_and_level , record in zip ( _EXPECTED_MESSAGES_AND_LEVELS [ - expected_log_count :], caplog .records ):
217
- assert expected_message_and_level [ 0 ] == record . message
218
- assert expected_message_and_level [ 1 ] == record . levelno
221
+ # Ensure logs are propagated
222
+ assert {( record . message , record . levelno ) for record in caplog .records } == set (
223
+ _EXPECTED_MESSAGES_AND_LEVELS [ - expected_log_count :]
224
+ )
219
225
220
226
221
227
@pytest .mark .parametrize (
@@ -250,10 +256,10 @@ def test_redirected_logs_sync(
250
256
# Do stuff while the log from the other Actor is being redirected to the logs.
251
257
time .sleep (2 )
252
258
253
- assert len ( caplog . records ) == expected_log_count
254
- for expected_message_and_level , record in zip ( _EXPECTED_MESSAGES_AND_LEVELS [ - expected_log_count :], caplog .records ):
255
- assert expected_message_and_level [ 0 ] == record . message
256
- assert expected_message_and_level [ 1 ] == record . levelno
259
+ # Ensure logs are propagated
260
+ assert {( record . message , record . levelno ) for record in caplog .records } == set (
261
+ _EXPECTED_MESSAGES_AND_LEVELS [ - expected_log_count :]
262
+ )
257
263
258
264
259
265
@respx .mock
@@ -278,10 +284,9 @@ async def test_actor_call_redirect_logs_to_default_logger_async(
278
284
assert isinstance (logger .handlers [0 ], logging .StreamHandler )
279
285
280
286
# Ensure logs are propagated
281
- assert len (caplog .records ) == len (_EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES )
282
- for expected_message_and_level , record in zip (_EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES , caplog .records ):
283
- assert expected_message_and_level [0 ] == record .message
284
- assert expected_message_and_level [1 ] == record .levelno
287
+ assert {(record .message , record .levelno ) for record in caplog .records } == set (
288
+ _EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES
289
+ )
285
290
286
291
287
292
@respx .mock
@@ -306,10 +311,9 @@ def test_actor_call_redirect_logs_to_default_logger_sync(
306
311
assert isinstance (logger .handlers [0 ], logging .StreamHandler )
307
312
308
313
# Ensure logs are propagated
309
- assert len (caplog .records ) == len (_EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES )
310
- for expected_message_and_level , record in zip (_EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES , caplog .records ):
311
- assert expected_message_and_level [0 ] == record .message
312
- assert expected_message_and_level [1 ] == record .levelno
314
+ assert {(record .message , record .levelno ) for record in caplog .records } == set (
315
+ _EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES
316
+ )
313
317
314
318
315
319
@respx .mock
@@ -357,10 +361,10 @@ async def test_actor_call_redirect_logs_to_custom_logger_async(
357
361
with caplog .at_level (logging .DEBUG , logger = logger_name ):
358
362
await actor_client .call (logger = logger )
359
363
360
- assert len ( caplog . records ) == len ( _EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES )
361
- for expected_message_and_level , record in zip ( _EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES , caplog .records ):
362
- assert expected_message_and_level [ 0 ] == record . message
363
- assert expected_message_and_level [ 1 ] == record . levelno
364
+ # Ensure logs are propagated
365
+ assert {( record . message , record . levelno ) for record in caplog .records } == set (
366
+ _EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES
367
+ )
364
368
365
369
366
370
@respx .mock
@@ -378,10 +382,10 @@ def test_actor_call_redirect_logs_to_custom_logger_sync(
378
382
with caplog .at_level (logging .DEBUG , logger = logger_name ):
379
383
actor_client .call (logger = logger )
380
384
381
- assert len ( caplog . records ) == len ( _EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES )
382
- for expected_message_and_level , record in zip ( _EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES , caplog .records ):
383
- assert expected_message_and_level [ 0 ] == record . message
384
- assert expected_message_and_level [ 1 ] == record . levelno
385
+ # Ensure logs are propagated
386
+ assert {( record . message , record . levelno ) for record in caplog .records } == set (
387
+ _EXPECTED_MESSAGES_AND_LEVELS_WITH_STATUS_MESSAGES
388
+ )
385
389
386
390
387
391
@respx .mock
0 commit comments