test(#1811): satisfy pr-preflight async-migration gate on test fixtures

The new RunStartupLoad tests + the rewritten Test1809 fixture trip the
async-migration preflight gate because they inline CREATE TABLE /
CREATE INDEX in test helpers. The gate's intent is to catch sync DDL
in PROD migration paths; ephemeral in-memory test fixtures are exempt
in spirit but need the explicit annotation.

Two changes:
  * runstartup_load_test.go: drop the duplicated inline CREATE TABLE
    block in TestLoadBackgroundChunks_PanicsOnOldestLoadedEmpty_Invariant
    and reuse the existing createTestDBWithLastSeen helper with 0 rows
    (schema-only).
  * issue1809_bg_load_race_test.go: annotate the new
    createTestDBSpreadOverDays helper's DDL with PREFLIGHT comments
    so the gate can identify these as test-fixture exemptions.

No behavior change. Refs PR #1811.
This commit is contained in:
meshcore-bot
2026-06-30 14:34:22 -07:00
parent 70fa16f760
commit eec1b48c7e
2 changed files with 13 additions and 32 deletions
@@ -122,6 +122,7 @@ func createTestDBSpreadOverDays(t *testing.T, dbPath string, numTx, spanDays int
t.Fatalf("test DB exec: %v\nSQL: %s", err, s)
}
}
// PREFLIGHT: async=true reason="unit-test fixture; in-memory ephemeral SQLite, no prod DB path"
execOrFail(`CREATE TABLE transmissions (
id INTEGER PRIMARY KEY,
raw_hex TEXT, hash TEXT, first_seen TEXT,
@@ -129,16 +130,22 @@ func createTestDBSpreadOverDays(t *testing.T, dbPath string, numTx, spanDays int
payload_version INTEGER, decoded_json TEXT,
last_seen INTEGER NOT NULL DEFAULT 0
)`)
// PREFLIGHT: async=true reason="unit-test fixture"
execOrFail(`CREATE TABLE observations (
id INTEGER PRIMARY KEY, transmission_id INTEGER, observer_id TEXT, observer_name TEXT,
direction TEXT, snr REAL, rssi REAL, score INTEGER,
path_json TEXT, timestamp TEXT, raw_hex TEXT
)`)
// PREFLIGHT: async=true reason="unit-test fixture"
execOrFail(`CREATE TABLE observers (rowid INTEGER PRIMARY KEY, id TEXT, name TEXT, iata TEXT)`)
// PREFLIGHT: async=true reason="unit-test fixture"
execOrFail(`CREATE TABLE nodes (pubkey TEXT PRIMARY KEY, name TEXT, role TEXT, lat REAL, lon REAL, last_seen TEXT, first_seen TEXT, frequency REAL)`)
// PREFLIGHT: async=true reason="unit-test fixture"
execOrFail(`CREATE TABLE schema_version (version INTEGER)`)
execOrFail(`INSERT INTO schema_version (version) VALUES (1)`)
// PREFLIGHT: async=true reason="unit-test fixture; index on ephemeral test DB"
execOrFail(`CREATE INDEX idx_tx_first_seen ON transmissions(first_seen)`)
// PREFLIGHT: async=true reason="unit-test fixture"
execOrFail(`CREATE INDEX idx_tx_last_seen ON transmissions(last_seen)`)
txStmt, err := conn.Prepare("INSERT INTO transmissions (id, raw_hex, hash, first_seen, route_type, payload_type, payload_version, decoded_json, last_seen) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")
+6 -32
View File
@@ -18,7 +18,6 @@ package main
// before loadBackgroundChunks executes (so oldestLoaded is set)
import (
"database/sql"
"fmt"
"path/filepath"
"testing"
@@ -186,37 +185,12 @@ func TestRunStartupLoad_BgLoaderRunsAfterLoadChunkedSets_OldestLoaded(t *testing
func TestLoadBackgroundChunks_PanicsOnOldestLoadedEmpty_Invariant(t *testing.T) {
dir := t.TempDir()
dbPath := filepath.Join(dir, "test.db")
conn, err := sql.Open("sqlite", dbPath+"?_journal_mode=WAL")
if err != nil {
t.Fatal(err)
}
// Create the bare minimum schema so OpenDB succeeds; we don't care
// about row count — only the guard at the top of the function.
if _, err := conn.Exec(`CREATE TABLE transmissions (
id INTEGER PRIMARY KEY, raw_hex TEXT, hash TEXT, first_seen TEXT,
route_type INTEGER, payload_type INTEGER, payload_version INTEGER,
decoded_json TEXT, last_seen INTEGER NOT NULL DEFAULT 0)`); err != nil {
t.Fatal(err)
}
if _, err := conn.Exec(`CREATE TABLE observations (
id INTEGER PRIMARY KEY, transmission_id INTEGER, observer_id TEXT,
observer_name TEXT, direction TEXT, snr REAL, rssi REAL,
score INTEGER, path_json TEXT, timestamp TEXT, raw_hex TEXT)`); err != nil {
t.Fatal(err)
}
if _, err := conn.Exec(`CREATE TABLE observers (rowid INTEGER PRIMARY KEY, id TEXT, name TEXT, iata TEXT)`); err != nil {
t.Fatal(err)
}
if _, err := conn.Exec(`CREATE TABLE nodes (pubkey TEXT PRIMARY KEY, name TEXT, role TEXT, lat REAL, lon REAL, last_seen TEXT, first_seen TEXT, frequency REAL)`); err != nil {
t.Fatal(err)
}
if _, err := conn.Exec(`CREATE TABLE schema_version (version INTEGER)`); err != nil {
t.Fatal(err)
}
if _, err := conn.Exec(`INSERT INTO schema_version (version) VALUES (1)`); err != nil {
t.Fatal(err)
}
conn.Close()
// Reuse the existing schema-only fixture helper (0 rows) so this
// test does not introduce a new inline CREATE TABLE block (pr-preflight
// async-migration gate). The fixture provides exactly the bare schema
// loadBackgroundChunks needs to reach its panic guard.
createTestDBWithLastSeen(t, dbPath, 0, 0, time.Now().UTC().Unix(),
30*time.Minute, 30*time.Minute)
db, err := OpenDB(dbPath)
if err != nil {