Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- **`RestoreCredentialAsync_Preserves…` flaked on the OS-native backends** (#61). The test
retried until one credential was visible and then asserted `IsSelected`, which comes from a
*separate* store item written moments earlier — so the credential could become visible
before the selection did and the assertion ran against a half-visible store. Observed once
on the macOS runner. The retry predicate now covers the property being asserted.

- **`SelectionsLock`'s sentinel cleanup and exhaustion path were untested** (#57). The suite
covered acquire, contend and re-acquire, but never asserted that `FileOptions.DeleteOnClose`
actually removes the sentinel — one test's comment claimed it without checking — so dropping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,14 @@ public async Task RestoreCredentialAsync_PreservesAccountIdAndSelection()
Assert.True(await RetryHelper.UntilTrueAsync(() => manager.DeleteCredentialAsync(id)));
await manager.RestoreCredentialAsync(exported);

var restored = Assert.Single(await RetryHelper.UntilAsync(() => manager.ExportCredentialsAsync(), r => r.Count == 1));
// Retry on the property actually being asserted, not just the count. The
// selection is a separate store item written moments earlier by
// RestoreCredentialAsync, so the credential can become visible before the
// selection does — and the count-only predicate let the assertions run against
// a half-visible store, which is what flaked on the macOS runner (#61).
var restored = Assert.Single(await RetryHelper.UntilAsync(
() => manager.ExportCredentialsAsync(),
r => r.Count == 1 && r[0].IsSelected));
Assert.Equal(id, restored.AccountId);
Assert.True(restored.IsSelected);
Assert.Equal("{\"apiKey\":\"secret\"}", await manager.GetSelectedCredentialAsync("Adobe"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,14 @@ public async Task RestoreCredentialAsync_PreservesAccountIdCreatedAtAndSelection
Assert.True(await RetryHelper.UntilTrueAsync(() => manager.DeleteCredentialAsync(id)));
await manager.RestoreCredentialAsync(exported);

var restored = Assert.Single(await RetryHelper.UntilAsync(() => manager.ExportCredentialsAsync(), r => r.Count == 1));
// Retry on the property actually being asserted, not just the count. The
// selection is a separate store item written moments earlier by
// RestoreCredentialAsync, so the credential can become visible before the
// selection does — and the count-only predicate let the assertions run against
// a half-visible store, which is what flaked on the macOS runner (#61).
var restored = Assert.Single(await RetryHelper.UntilAsync(
() => manager.ExportCredentialsAsync(),
r => r.Count == 1 && r[0].IsSelected));
Assert.Equal(id, restored.AccountId);
Assert.Equal(exported.CreatedAt, restored.CreatedAt); // libsecret preserves it via attribute
Assert.True(restored.IsSelected);
Expand Down