test(inboundapi): root the shared in-memory SQLite keep-alive so the database cannot vanish mid-test
Script_UsingDatabase_QueriesViaGateway failed in about 2 of 27 full InboundAPI runs. Looping the suite 30 times captured the failure 4 times, always as "Internal script error". The exception underneath was SqliteException 'no such table: Machine'. Cause: the seeding helper opened its keep-alive SqliteConnection in a local. Once the helper returned, nothing referenced that connection. After a GC (likely during the Roslyn compile, under full-suite load), Microsoft.Data.Sqlite's pool reclaimed the leaked connection and closed the last connection to the shared in-memory database, which destroyed it. Fix: hold the keep-alive in a static field. InboundDatabaseHelperTests had the same latent bug and gets the same fix. The test now forces GC plus SqliteConnection.ClearAllPools() before the query. That makes the old pattern fail deterministically and the fix pass deterministically. Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -33,11 +33,25 @@ public class InboundDatabaseHelperTests
|
||||
=> throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static SqliteGateway SeededGateway(bool honorTokenOnOpen = true)
|
||||
/// <summary>
|
||||
/// Keep-alive for the shared in-memory database, rooted in a static field. It used to be a
|
||||
/// local in the seeding helper: once the helper returned nothing referenced it, so after a GC the
|
||||
/// Sqlite pool could reclaim the leaked connection, close the last connection and destroy the
|
||||
/// database before the test's query ran (<c>no such table: Machine</c>). This is the same latent
|
||||
/// flake the executor tests hit.
|
||||
/// </summary>
|
||||
private static readonly SqliteConnection KeepAlive = OpenKeepAlive();
|
||||
|
||||
private static SqliteConnection OpenKeepAlive()
|
||||
{
|
||||
var keep = new SqliteConnection("DataSource=file:movein?mode=memory&cache=shared");
|
||||
keep.Open(); // keep-alive: shared in-memory db lives until process exit
|
||||
using var cmd = keep.CreateCommand();
|
||||
keep.Open(); // lives until process exit
|
||||
return keep;
|
||||
}
|
||||
|
||||
private static SqliteGateway SeededGateway(bool honorTokenOnOpen = true)
|
||||
{
|
||||
using var cmd = KeepAlive.CreateCommand();
|
||||
cmd.CommandText = "CREATE TABLE IF NOT EXISTS Machine(Code TEXT, SAPID TEXT); DELETE FROM Machine; INSERT INTO Machine VALUES('Z28061A','131453');";
|
||||
cmd.ExecuteNonQuery();
|
||||
return new SqliteGateway("DataSource=file:movein?mode=memory&cache=shared", honorTokenOnOpen);
|
||||
|
||||
Reference in New Issue
Block a user