Skip to content

fix(credentials): serialize profile writes with cross-process file locking#32

Open
SahilRakhaiya05 wants to merge 3 commits into
TestSprite:mainfrom
SahilRakhaiya05:fix/credentials-write-lock
Open

fix(credentials): serialize profile writes with cross-process file locking#32
SahilRakhaiya05 wants to merge 3 commits into
TestSprite:mainfrom
SahilRakhaiya05:fix/credentials-write-lock

Conversation

@SahilRakhaiya05

Copy link
Copy Markdown
Contributor

Summary

writeProfile and deleteProfile perform read-modify-write on ~/.testsprite/credentials. The final rename is atomic, but the read and write are not one operation. Two concurrent CLI processes (e.g. two terminals running testsprite setup for different profiles, or setup + auth remove) can each read the same snapshot; the last rename wins and silently drops the other profile update - real credentials data loss.

The fix

  • Wrap writeProfile / deleteProfile in withCredentialsLock()
  • Exclusive lock file at {credentialsPath}.lock via openSync(..., 'wx')
  • Stale-lock reclamation when holder pid is dead or lock age > 30s
  • Bounded retry (25ms back-off, 10s max wait)

Tests

  • Subprocess regression: parallel writers for dev + staging profiles - both survive
  • Lock file is removed after writeProfile / deleteProfile complete

Notes

…cking

writeProfile and deleteProfile read-modify-write the credentials file; without a lock, concurrent CLI processes can each read the same snapshot and the last atomic rename wins, silently dropping the other update.

Acquire an exclusive lock file ({path}.lock) before read-modify-write, with stale-lock reclamation and a bounded retry loop. Add subprocess regression tests proving concurrent writes to different profiles both survive.
Resolve conflict in credentials.test.ts by keeping both the
cross-process write-lock regression tests and the profile-name
validation tests added in TestSprite#21.
acquireCredentialsLock now creates the credentials directory before
openSync on the lock path, so first-time setup on a fresh HOME no longer
throws ENOENT (fixes subprocess setup/auth tests). Add trailing newline
to credentials-write-child.mjs for format:check.
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