Skip to content

tests: serialise keyring writes across xdist workers - #214

Open
robmsmt wants to merge 1 commit into
mainfrom
fix/keyring-race-xdist
Open

tests: serialise keyring writes across xdist workers#214
robmsmt wants to merge 1 commit into
mainfrom
fix/keyring-race-xdist

Conversation

@robmsmt

@robmsmt robmsmt commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Problem

Main's post-merge run 33120371812 (rerun) died in 23 s with 12 passed, 90 errors, every one:

FileExistsError: [Errno 17] File exists: '/home/runner/.local/share/python_keyring'
  keyrings/alt/file_base.py:161 in _ensure_file_path -> os.makedirs(storage_root)
  <- keyring.set_password  <- InitConfig.set_value  <- conftest sml_config_dir (session, autouse)

sml_config_dir runs on each of the -n 2 xdist workers and writes secrets into the keyring; on CI that's keyrings.alt's plaintext file backend, whose _ensure_file_path calls os.makedirs without exist_ok. On a fresh runner both workers race for the directory; the loser raises, the session fixture error is cached, and every test on that worker errors. The backend's read-modify-write of keyring_pass.cfg isn't atomic either.

Fix

_keyring_write_lock() in tests/integration/conftest.py: if the active keyring exposes a file_path, create its directory with exist_ok=True and hold an fcntl.flock for the duration of the config writes. Backends without a file path (macOS Keychain locally) are untouched.

Verified locally with PYTHON_KEYRING_BACKEND=keyrings.alt.file.PlaintextKeyring and four concurrent processes on a fresh XDG_DATA_HOME: all writes land, file stays 0600.

🤖 Generated with Claude Code

The session fixture writes the test InitConfig on every xdist worker,
and on CI its secrets land in keyrings.alt's plaintext file under
~/.local/share/python_keyring. That backend creates the directory with
a bare os.makedirs, so two workers racing for it on a fresh runner
leave one with FileExistsError — and since the fixture is session
scoped, every test on that worker then errors (12 passed, 90 errors on
main's post-merge run 33120371812). Its read-modify-write of the file
isn't atomic either.

Create the directory up front and hold an fcntl lock around the writes.
Keyrings without a file_path (macOS Keychain, ...) are left alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

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