diff --git a/tests/ZB.MOM.WW.ScadaBridge.InboundAPI.Tests/InboundDatabaseHelperTests.cs b/tests/ZB.MOM.WW.ScadaBridge.InboundAPI.Tests/InboundDatabaseHelperTests.cs
index b50c2fb3..e9ec4a89 100644
--- a/tests/ZB.MOM.WW.ScadaBridge.InboundAPI.Tests/InboundDatabaseHelperTests.cs
+++ b/tests/ZB.MOM.WW.ScadaBridge.InboundAPI.Tests/InboundDatabaseHelperTests.cs
@@ -33,11 +33,25 @@ public class InboundDatabaseHelperTests
=> throw new NotImplementedException();
}
- private static SqliteGateway SeededGateway(bool honorTokenOnOpen = true)
+ ///
+ /// 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 (no such table: Machine). This is the same latent
+ /// flake the executor tests hit.
+ ///
+ 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);
diff --git a/tests/ZB.MOM.WW.ScadaBridge.InboundAPI.Tests/InboundScriptExecutorTests.cs b/tests/ZB.MOM.WW.ScadaBridge.InboundAPI.Tests/InboundScriptExecutorTests.cs
index 4d47c438..0d8a701c 100644
--- a/tests/ZB.MOM.WW.ScadaBridge.InboundAPI.Tests/InboundScriptExecutorTests.cs
+++ b/tests/ZB.MOM.WW.ScadaBridge.InboundAPI.Tests/InboundScriptExecutorTests.cs
@@ -940,6 +940,13 @@ public class InboundScriptExecutorTests
var services = new ServiceCollection();
services.AddSingleton(SeededSqliteGateway());
using var provider = services.BuildServiceProvider();
+ // Regression guard for the old flake: force the collection the full suite used to hit during
+ // the script compile, then the pool reclaim that followed it. An unrooted keep-alive dies here
+ // deterministically ("Internal script error"); ClearAllPools only closes IDLE connections.
+ GC.Collect();
+ GC.WaitForPendingFinalizers();
+ GC.Collect();
+ SqliteConnection.ClearAllPools();
var executor = new InboundScriptExecutor(
NullLogger.Instance, provider);
@@ -1052,11 +1059,26 @@ public class InboundScriptExecutorTests
=> throw new NotImplementedException();
}
- private static SqliteGateway SeededSqliteGateway()
+ ///
+ /// 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
+ /// (likely during the script compile under a full-suite run) Microsoft.Data.Sqlite's pool
+ /// reclaimed the leaked connection, closed the last connection and destroyed the database. The
+ /// query then failed with no such table: Machine, which the script reported as "Internal
+ /// script error" (4 runs in 30, captured 2026-11-10).
+ ///
+ private static readonly SqliteConnection KeepAlive = OpenKeepAlive();
+
+ private static SqliteConnection OpenKeepAlive()
{
var keep = new SqliteConnection("DataSource=file:movein-exec?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 SeededSqliteGateway()
+ {
+ 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-exec?mode=memory&cache=shared");