fix(tests): clear the SQLite pool before deleting the secrets path-guard temp dir — Windows sharing violation

This commit is contained in:
Joseph Doherty
2026-08-15 20:04:59 -04:00
parent a756e47682
commit 25f07f89dd
2 changed files with 24 additions and 7 deletions
+6 -6
View File
@@ -557,12 +557,12 @@ real-clock deadlines into failures.
### Two more findings from the 2026-08-15 windev gate
- `SecretsStorePathGuardTests.CreateBuilder_AcceptsSecretsStoreOutsideContentRoot_AndCreatesIt`
fails **deterministically on Windows, on `main` as well as on any branch**, so it is not a
signal about the change under test. Creating the builder opens `secrets.db`, and
`Microsoft.Data.Sqlite`'s connection pool keeps the file handle alive past the test body,
so the recursive directory delete in the cleanup hits a still-open file — a sharing
violation Windows enforces and Unix does not. Pre-existing and tracked separately; do not
chase it as a regression. Subtract it from the expected pass count on Windows.
used to fail deterministically on Windows: creating the builder opens `secrets.db`,
`Microsoft.Data.Sqlite`'s connection pool kept the file handle alive past the test body, and
the cleanup's recursive directory delete hit a sharing violation Windows enforces and Unix
does not. The cleanup now clears the SQLite connection pool before deleting the temp
directory (the same pattern as `TempDatabaseDirectory` and `PreHostSecretExpansionTests`),
so the test passes on Windows and macOS alike — count it as a pass on both.
- The `StaWaitHelper` timing tests (`WaitForSignalOrMessages_*`) flake on a loaded box with a
signature that reads like a broken wait but is not: the helper wakes on *input being
present*, so a message posted to the test thread ends the wait early. That is the helper
@@ -100,7 +100,24 @@ public sealed class SecretsStorePathGuardTests
finally
{
Environment.SetEnvironmentVariable(SqlitePathVariable, original);
Directory.Delete(directory, recursive: true);
// The store runs in WAL mode with connection pooling, so a pooled handle can outlive the
// migration and keep secrets.db (plus its -wal/-shm sidecars) open. Windows refuses to
// delete a directory holding open files where Unix does not, so clear the pool first;
// the catch is belt-and-braces for a sidecar whose handle outlasts even that.
Microsoft.Data.Sqlite.SqliteConnection.ClearAllPools();
try
{
Directory.Delete(directory, recursive: true);
}
catch (IOException)
{
// Best-effort cleanup of the temp store; a locked file must not fail the test.
}
catch (UnauthorizedAccessException)
{
// Best-effort cleanup of the temp store; a locked file must not fail the test.
}
}
}