sqldb: harden migration config consistency tests
What changed, and why it matters
This commit is a hardening patch for database migration tests in LND. It adds and strengthens automated checks that ensure every embedded SQL migration file is registered in the migration configuration, that schema versions never go backwards, and that migration names match their SQL filenames. It also fixes one mismatched migration name. There is no runtime code change that would directly create or fix an exploitable vulnerability; the change is defensive test coverage.
No immediate action required. Treat as routine defensive hardening. Ensure CI runs the dev-build migration tests so the new consistency checks are exercised.
Security signals we found
Defensive test hardening for database migration metadata consistency
Fixes a migration config name mismatch that could cause migration lookup failures
Adds regression check preventing schema version regressions in migration config
Adds bidirectional check ensuring embedded SQL files are registered in migration config
Evidence from the diff
The patch modifies sqldb/migrations.go to rename the graph v2 migration config entry from ‘000009_graph_v2_columns’ to ‘000009_graph_v2’ so it matches the embedded SQL file stem. It adds a new dev-build test TestMigrationFilesAllRegistered that walks the embedded sqlc/migrations directory and asserts each .up.sql file’s numeric prefix has a matching SchemaVersion entry in migrationConfig. It strengthens TestMigrationConfigConsistency by deriving the previous schema state from slice index order rather than Version, rejecting schema version regressions, and asserting that migration names exactly match the embedded SQL file stem. These are test-only and metadata consistency improvements.
Changed components
sqldb/migrations.gosqldb/migrations_dev_test.gosqldb/migrations_test.goInspect captured patch +67 / −5
diff --git a/sqldb/migrations.go b/sqldb/migrations.go
index 9f9256d..395bd66 100644
--- a/sqldb/migrations.go
+++ b/sqldb/migrations.go
@@ -93,7 +93,7 @@ var (
// user if necessary.
},
{
- Name: "000009_graph_v2_columns",
+ Name: "000009_graph_v2",
Version: 11,
SchemaVersion: 9,
},
diff --git a/sqldb/migrations_dev_test.go b/sqldb/migrations_dev_test.go
new file mode 100644
index 0000000..43d1b5d
--- /dev/null
+++ b/sqldb/migrations_dev_test.go
@@ -0,0 +1,52 @@
+//go:build test_db_postgres || test_db_sqlite || test_native_sql
+
+package sqldb
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+// TestMigrationFilesAllRegistered verifies that every .up.sql file in the
+// embedded migrations filesystem has a corresponding entry in migrationConfig.
+// This test requires dev build tags so that any future dev-only migrations
+// added to migrationAdditions are visible — without them, such entries would
+// be absent and their SQL files would trigger false failures.
+func TestMigrationFilesAllRegistered(t *testing.T) {
+ t.Parallel()
+
+ migrations := GetMigrations()
+ require.NotEmpty(t, migrations)
+
+ // Collect all schema versions referenced by any entry in migrationConfig
+ // (including migrationAdditions, which is only populated under dev build
+ // tags).
+ registeredSchemaVersions := make(map[int]string)
+ for _, m := range migrations {
+ registeredSchemaVersions[m.SchemaVersion] = m.Name
+ }
+
+ // Read all .up.sql files from the embedded filesystem.
+ embeddedFiles, err := sqlSchemas.ReadDir("sqlc/migrations")
+ require.NoError(t, err)
+
+ for _, f := range embeddedFiles {
+ if f.IsDir() {
+ continue
+ }
+
+ var schemaVersion int
+ _, err := fmt.Sscanf(f.Name(), "%06d_", &schemaVersion)
+ require.NoError(t, err, "migration file %q has no valid "+
+ "numeric prefix", f.Name())
+
+ _, referenced := registeredSchemaVersions[schemaVersion]
+ require.True(t, referenced,
+ "SQL migration file %q (schema version %d) has no "+
+ "corresponding entry in migrationConfig — add "+
+ "an entry with SchemaVersion=%d",
+ f.Name(), schemaVersion, schemaVersion)
+ }
+}
diff --git a/sqldb/migrations_test.go b/sqldb/migrations_test.go
index 399afb1..4e2b68e 100644
--- a/sqldb/migrations_test.go
+++ b/sqldb/migrations_test.go
@@ -4,6 +4,7 @@ import (
"database/sql"
"fmt"
"path/filepath"
+ "strings"
"testing"
"github.com/golang-migrate/migrate/v4"
@@ -667,7 +668,7 @@ func TestMigrationConfigConsistency(t *testing.T) {
seenVersions := make(map[int]string)
seenSchemaVersions := make(map[int]string)
- for _, m := range migrations {
+ for i, m := range migrations {
// 1. Verify no duplicate global versions.
if existing, ok := seenVersions[m.Version]; ok {
t.Fatalf("duplicate global version %d: %q and %q",
@@ -680,20 +681,29 @@ func TestMigrationConfigConsistency(t *testing.T) {
// and no two config entries claim the same schema version
// with different file prefixes.
prevSchema := 0
- if m.Version > 1 {
- prevSchema = migrations[m.Version-2].SchemaVersion
+ if i > 0 {
+ prevSchema = migrations[i-1].SchemaVersion
}
+ require.GreaterOrEqual(t, m.SchemaVersion, prevSchema,
+ "migration %q regresses schema version from %d to %d",
+ m.Name, prevSchema, m.SchemaVersion)
+
// A migration advances the schema if its SchemaVersion is
// higher than the previous migration's SchemaVersion.
if m.SchemaVersion > prevSchema {
- _, hasFile := fileSchemaVersions[m.SchemaVersion]
+ fileName, hasFile := fileSchemaVersions[m.SchemaVersion]
require.True(t, hasFile,
"migration %q (version %d) declares "+
"SchemaVersion=%d but no %06d_*.up.sql"+
" file exists in the embedded FS",
m.Name, m.Version, m.SchemaVersion,
m.SchemaVersion)
+ require.Equal(t, strings.TrimSuffix(fileName, ".up.sql"),
+ m.Name, "migration %q (version %d) has "+
+ "SchemaVersion=%d but its name does not "+
+ "match embedded file %q",
+ m.Name, m.Version, m.SchemaVersion, fileName)
if existing, ok := seenSchemaVersions[m.SchemaVersion]; ok {
t.Fatalf("duplicate schema version %d: "+
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.