Since #69 the internal/cli tests took much longer. A verbose run inside the docker build showed where: TestChangingCommandsWaitForLock, added with the lock, slept a fixed 100 ms for each of its 16 commands, and six path and move tests each created two vaults with passphrase unlockers, which are slow to create by design.
What changed:
requireWaitsForLock no longer sleeps. It reads the goroutine stack traces until one is stopped in vault.LockStateDir waiting for the in-memory filesystem's lock, checks the state directory is unchanged, then releases the lock. A command that takes no lock still finishes first and fails; one that changes something before locking always fails the unchanged check, instead of relying on 100 ms being long enough.
newTwoVaultFs creates its vaults once and returns a fresh copy on every call, the same copying the rejection cases already did. The test bodies are unchanged.
Each changed test fails with its guarded defect planted back.
What is left in TestChangingCommandsWaitForLock is creating passphrase unlockers: four of the commands create one, and two cases need one first. The size cases and -race are untouched (#52).
Judgement call: spotting the waiting command depends on the runtime's [sync.Mutex.Lock] wait reason in stack traces; if that text changes, the test fails with "never waited for the lock" rather than passing.
Rule suppressed: gochecknoglobals on the shared fixture's sync.Once and its copy source.
Model: opus-5-5
Since https://git.eeqj.de/sneak/secret/pulls/69 the `internal/cli` tests took much longer. A verbose run inside the docker build showed where: `TestChangingCommandsWaitForLock`, added with the lock, slept a fixed 100 ms for each of its 16 commands, and six path and move tests each created two vaults with passphrase unlockers, which are slow to create by design.
What changed:
- `requireWaitsForLock` no longer sleeps. It reads the goroutine stack traces until one is stopped in `vault.LockStateDir` waiting for the in-memory filesystem's lock, checks the state directory is unchanged, then releases the lock. A command that takes no lock still finishes first and fails; one that changes something before locking always fails the unchanged check, instead of relying on 100 ms being long enough.
- `newTwoVaultFs` creates its vaults once and returns a fresh copy on every call, the same copying the rejection cases already did. The test bodies are unchanged.
Each changed test fails with its guarded defect planted back.
What is left in `TestChangingCommandsWaitForLock` is creating passphrase unlockers: four of the commands create one, and two cases need one first. The size cases and `-race` are untouched (https://git.eeqj.de/sneak/secret/issues/52).
- Judgement call: spotting the waiting command depends on the runtime's `[sync.Mutex.Lock]` wait reason in stack traces; if that text changes, the test fails with "never waited for the lock" rather than passing.
- Rule suppressed: `gochecknoglobals` on the shared fixture's `sync.Once` and its copy source.
Model: opus-5-5
clawbot
self-assigned this 2026-10-04 06:49:14 +02:00
PASS: the lock test and the path and move tests are faster and still prove everything they proved before.
Disclosure: conflicts with current next only in TODO.md (both add a Completed Steps entry); reviewed with both entries kept.
Model: opus-5-5
PASS: the lock test and the path and move tests are faster and still prove everything they proved before.
Disclosure: conflicts with current `next` only in `TODO.md` (both add a Completed Steps entry); reviewed with both entries kept.
Model: opus-5-5
The test that each changing command waits for the state directory lock
slept a fixed 100 ms per command. It now polls the goroutine stacks until
the command is parked in vault.LockStateDir, checks the state directory
is unchanged, and releases the lock; a command that takes no lock still
fails by finishing first.
newTwoVaultFs creates its two vaults, each with a passphrase unlocker,
once, and returns a fresh copy of them on every call, so the six path and
move tests no longer each pay for two passphrase key derivations.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Since #69 the
internal/clitests took much longer. A verbose run inside the docker build showed where:TestChangingCommandsWaitForLock, added with the lock, slept a fixed 100 ms for each of its 16 commands, and six path and move tests each created two vaults with passphrase unlockers, which are slow to create by design.What changed:
requireWaitsForLockno longer sleeps. It reads the goroutine stack traces until one is stopped invault.LockStateDirwaiting for the in-memory filesystem's lock, checks the state directory is unchanged, then releases the lock. A command that takes no lock still finishes first and fails; one that changes something before locking always fails the unchanged check, instead of relying on 100 ms being long enough.newTwoVaultFscreates its vaults once and returns a fresh copy on every call, the same copying the rejection cases already did. The test bodies are unchanged.Each changed test fails with its guarded defect planted back.
What is left in
TestChangingCommandsWaitForLockis creating passphrase unlockers: four of the commands create one, and two cases need one first. The size cases and-raceare untouched (#52).[sync.Mutex.Lock]wait reason in stack traces; if that text changes, the test fails with "never waited for the lock" rather than passing.gochecknoglobalson the shared fixture'ssync.Onceand its copy source.Model: opus-5-5
PASS: the lock test and the path and move tests are faster and still prove everything they proved before.
Disclosure: conflicts with current
nextonly inTODO.md(both add a Completed Steps entry); reviewed with both entries kept.Model: opus-5-5
9fc49f6052to02b42499e6