Skip to content

Commit 64084ac

Browse files
committed
test: upgrade pytest-asyncio and add loop scoping
Upgrade pytest-asyncio from 0.20.1 to 0.24.0+ and configure event loop scope to prevent fixture crashes. requirements.txt changes: - pytest>=8.3,<9.0 (was >=7.1.2) - pytest-asyncio>=0.24.0,<0.25.0 (was ==0.20.1) conftest.py changes: - Remove manual event_loop fixture override (deprecated in 0.24+) - Rewrite async_client fixture to bypass async_pool. With session-scoped loops, the standalone ConnectionPool in async_pool retains connections with stale loop references when df_server restarts between test classes. Now async_client creates Redis directly with connection params, letting Redis manage its own internal pool and adding proper aclose() cleanup. This fixes 7 failing tests (test_publish_stuck, test_nested_client_pause, test_cron_snapshot, test_set_cron_snapshot, test_basic_memory_usage, test_mixed_append, test_tiered_replication_with_hashes). pytest.ini changes: - Add asyncio_default_fixture_loop_scope=session pytest-asyncio 0.24+ forbids manual event_loop overrides and requires explicit loop scope configuration. We use session scope because: 1. df_factory and other fixtures are class-scoped 2. Many async tests are module-level functions (not in classes) 3. session scope supports both patterns without UsageError Upper bounds prevent pip from installing pytest 9.x and pytest-asyncio 1.x, which conflict with dragonfly-fakeredis-tests. snapshot_test.py changes: - test_s3_snapshot, test_s3_save_local_dir: replace async_client fixture with df_server.client(). With session-scoped loops, the shared async_client pool holds stale connections from a previous df_server instance, causing "Future attached to a different loop". Creating a fresh client per test avoids this (same pattern used by test_s3_reload_snapshot_after_restart). Signed-off-by: Gil Levkovich <69595609+glevkovich@users.noreply.github.com>
1 parent e426a6f commit 64084ac

4 files changed

Lines changed: 16 additions & 13 deletions

File tree

tests/dragonfly/conftest.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,6 @@ def parse_args(args: List[str]) -> Dict[str, Union[str, None]]:
250250
return args_dict
251251

252252

253-
@pytest_asyncio.fixture(scope="class")
254-
def event_loop():
255-
loop = asyncio.new_event_loop()
256-
yield loop
257-
loop.close()
258-
259-
260253
@pytest_asyncio.fixture(scope="class", params=[{}])
261254
async def df_factory(
262255
request,
@@ -363,15 +356,22 @@ async def async_pool(df_server: DflyInstance):
363356

364357

365358
@pytest_asyncio.fixture(scope="function")
366-
async def async_client(async_pool):
359+
async def async_client(df_server: DflyInstance):
367360
"""
368361
Return an async client to the default instance with all entries flushed.
369362
"""
370-
client = aioredis.Redis(connection_pool=async_pool)
363+
client = aioredis.Redis(
364+
host="localhost",
365+
port=df_server.port,
366+
db=DATABASE_INDEX,
367+
decode_responses=True,
368+
max_connections=32,
369+
)
371370
await client.client_setname("default-async-fixture")
372371
await client.flushall()
373372
await client.select(DATABASE_INDEX)
374373
yield client
374+
await client.aclose()
375375

376376

377377
def pytest_addoption(parser):

tests/dragonfly/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ packaging>=23.1
66
pluggy>=1.0.0
77
py>=1.11.0
88
pyparsing>=3.0.9
9-
pytest>=7.1.2
9+
pytest>=8.3,<9.0
1010
redis>=5.2.1
1111
tomli>=2.0.1
1212
wrapt>=1.14.1
13-
pytest-asyncio==0.20.1
13+
pytest-asyncio>=0.24.0,<0.25.0
1414
pytest-repeat>=0.9.3
1515
pymemcache>=4.0.0
1616
meta_memcache>=2

tests/dragonfly/snapshot_test.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,8 @@ async def test_exit_on_s3_snapshot_load_err(df_factory):
390390
reason="AWS S3 snapshots bucket or credentials are not configured",
391391
)
392392
@dfly_args({**BASIC_ARGS})
393-
async def test_s3_snapshot(async_client, tmp_dir):
393+
async def test_s3_snapshot(df_server, tmp_dir):
394+
async_client = df_server.client()
394395
seeder = DebugPopulateSeeder(key_target=10_000)
395396
await seeder.run(async_client)
396397

@@ -460,7 +461,8 @@ async def test_s3_reload_snapshot_after_restart(df_factory, tmp_dir):
460461
reason="AWS S3 snapshots bucket or credentials are not configured",
461462
)
462463
@dfly_args({**BASIC_ARGS})
463-
async def test_s3_save_local_dir(async_client, tmp_dir):
464+
async def test_s3_save_local_dir(df_server, tmp_dir):
465+
async_client = df_server.client()
464466
seeder = DebugPopulateSeeder(key_target=10_000)
465467
await seeder.run(async_client)
466468

tests/pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ log_date_format = %Y-%m-%d %H:%M:%S
55
log_file_level=INFO
66
log_cli = true
77
asyncio_mode=auto
8+
asyncio_default_fixture_loop_scope=session
89
addopts = -ra --emoji --showlocals -m "not large"
910
markers =
1011
# Tests that should only run on release builds and take significant amount of time to run.

0 commit comments

Comments
 (0)