Skip to content

Harden integration tests against the post-boot Moodle login race#74

Merged
erseco merged 2 commits into
mainfrom
harden-integration-login-warmup
Jul 8, 2026
Merged

Harden integration tests against the post-boot Moodle login race#74
erseco merged 2 commits into
mainfrom
harden-integration-login-warmup

Conversation

@erseco

@erseco erseco commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

Eliminates the recurring integration-test flake where fixture setup fails with Moodle login failed: invalid username or password. Adds a session-scoped, autouse login warmup (retry) fixture so a freshly-booted Moodle is warm before any test logs in. Integration-harness only; no library/CLI change.

Problem

Right after a fresh Moodle container starts serving /login/index.php, the first login attempt intermittently fails with "invalid username or password" while Moodle finishes initializing (caches/sessions); a moment later the same credentials work — which is exactly why every occurrence went green on rerun. Under pytest-xdist -n auto this hit whichever test a worker ran first (observed on test_create_and_delete_course, test_add_assign, test_list_courses, …), making the whole suite flaky and forcing repeated CI reruns.

Fix

A scope="session", autouse=True fixture (_warm_up_moodle_login) in tests/conftest.py that, only when --integration is active, performs a retrying warmup login (up to 6 attempts, 5s apart) once per session — i.e. once per xdist worker — before tests run. Once the warmup login succeeds the Moodle server is warm, so every subsequent per-test (new-session) login is reliable. If login never succeeds within the budget it pytest.exits with a clear message (a genuinely-down Moodle still fails fast-ish, not silently).

Test plan

  • pytest tests/unit — green; the warmup fixture is a no-op without --integration, so unit runs are unaffected.
  • make lint (black/isort/flake8) — clean.
  • Real validation is this PR's integration matrix (4.5.5 / 5.0.1 / 5.1.5): the login-race errors should stop recurring. If any leg still flakes on an unrelated race (e.g. a parallel course-state collision), that is a separate, pre-existing issue.

Backwards compatibility

No change to any library or CLI behavior; only the integration test harness. Unit tests, and any environment without --integration, are unaffected.

Notes for reviewers

This is the counterpart to #62 (which serialized course creation across workers) and #73 (ephemeral CI containers + boot diagnostics): together they target the main sources of integration flakiness. The warmup absorbs the login race specifically. Retry budget (6×5s) is generous but only spends time when the race is actually occurring — a first-try success is instant.

erseco added 2 commits July 8, 2026 00:58
The Docker-backed integration suite intermittently failed at fixture
setup with 'Moodle login failed: invalid username or password', on
whichever test a pytest-xdist worker ran first. This is a transient
race: right after a freshly-started Moodle container begins serving its
login page, the very first login attempt sometimes fails while Moodle
finishes initializing caches/sessions; a moment later the same
credentials work (which is why reruns always went green).

Add a session-scoped, autouse warmup fixture that performs a retrying
login (up to 6 attempts, 5s apart) once per session -- i.e. once per
xdist worker -- before any integration test runs. A successful warmup
means the Moodle server is warm, so every subsequent per-test
(new-session) login is reliable. It is a no-op unless --integration is
passed, so unit runs are unaffected.

No library/CLI change; this only touches the integration test harness.
@erseco erseco merged commit 33cbd12 into main Jul 8, 2026
13 checks passed
@erseco erseco deleted the harden-integration-login-warmup branch July 8, 2026 00:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant