From 4a2e3fc1695981cf39b434c59941dc39703cba23 Mon Sep 17 00:00:00 2001 From: Chris Coutinho Date: Thu, 23 Apr 2026 07:05:17 +0200 Subject: [PATCH] test: stagger parallel OAuth fetches for login-flow users Mirrors the per-user delay pattern used in tests/conftest.py:all_oauth_tokens (commit 963a504). Without it, all four Playwright browser contexts hit Nextcloud's OIDC authorize endpoint simultaneously and the last users in iteration order (charlie/diana) frequently time out on the consent screen in CI, producing `TimeoutError: Timeout waiting for OAuth callback`. Uses a 0.5s stagger locally and 10s in GITHUB_ACTIONS, matching the existing fixture so behaviour stays consistent across the two parallel fixtures. Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/server/login_flow/conftest.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/server/login_flow/conftest.py b/tests/server/login_flow/conftest.py index 703ed79b..ac4a81d2 100644 --- a/tests/server/login_flow/conftest.py +++ b/tests/server/login_flow/conftest.py @@ -667,7 +667,14 @@ async def all_login_flow_user_tokens( results: dict[str, str | Exception] = {} - async def _fetch(username: str, config: dict) -> None: + # Stagger per-user starts so parallel Playwright OAuth flows don't all hit + # Nextcloud's OIDC consent rendering at once — CI under load needs a wider + # gap (see tests/conftest.py:all_oauth_tokens). + scale = 0.5 if "GITHUB_ACTIONS" not in os.environ else 10 + + async def _fetch(username: str, config: dict, delay: float) -> None: + if delay > 0: + await anyio.sleep(delay) try: token = await _get_login_flow_token_for_user( browser, @@ -682,8 +689,8 @@ async def all_login_flow_user_tokens( user_list = list(test_users_setup.items()) async with anyio.create_task_group() as tg: - for username, config in user_list: - tg.start_soon(_fetch, username, config) + for idx, (username, config) in enumerate(user_list): + tg.start_soon(_fetch, username, config, idx * scale) for username, result in results.items(): if isinstance(result, Exception):