Skip to content

Commit bd7e950

Browse files
committed
sqldb: harden migration config consistency tests
Strengthen migration consistency coverage by checking the reverse mapping from embedded SQL files to migrationConfig entries, deriving previous schema state from slice order instead of Version, rejecting schema version regressions, and asserting migration names match the embedded SQL file stems. Also fix the graph v2 migration config name to match the embedded migration filename.
1 parent 8a9f774 commit bd7e950

3 files changed

Lines changed: 67 additions & 5 deletions

File tree

sqldb/migrations.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ var (
9393
// user if necessary.
9494
},
9595
{
96-
Name: "000009_graph_v2_columns",
96+
Name: "000009_graph_v2",
9797
Version: 11,
9898
SchemaVersion: 9,
9999
},

sqldb/migrations_dev_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//go:build test_db_postgres || test_db_sqlite || test_native_sql
2+
3+
package sqldb
4+
5+
import (
6+
"fmt"
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
// TestMigrationFilesAllRegistered verifies that every .up.sql file in the
13+
// embedded migrations filesystem has a corresponding entry in migrationConfig.
14+
// This test requires dev build tags so that any future dev-only migrations
15+
// added to migrationAdditions are visible — without them, such entries would
16+
// be absent and their SQL files would trigger false failures.
17+
func TestMigrationFilesAllRegistered(t *testing.T) {
18+
t.Parallel()
19+
20+
migrations := GetMigrations()
21+
require.NotEmpty(t, migrations)
22+
23+
// Collect all schema versions referenced by any entry in migrationConfig
24+
// (including migrationAdditions, which is only populated under dev build
25+
// tags).
26+
registeredSchemaVersions := make(map[int]string)
27+
for _, m := range migrations {
28+
registeredSchemaVersions[m.SchemaVersion] = m.Name
29+
}
30+
31+
// Read all .up.sql files from the embedded filesystem.
32+
embeddedFiles, err := sqlSchemas.ReadDir("sqlc/migrations")
33+
require.NoError(t, err)
34+
35+
for _, f := range embeddedFiles {
36+
if f.IsDir() {
37+
continue
38+
}
39+
40+
var schemaVersion int
41+
_, err := fmt.Sscanf(f.Name(), "%06d_", &schemaVersion)
42+
require.NoError(t, err, "migration file %q has no valid "+
43+
"numeric prefix", f.Name())
44+
45+
_, referenced := registeredSchemaVersions[schemaVersion]
46+
require.True(t, referenced,
47+
"SQL migration file %q (schema version %d) has no "+
48+
"corresponding entry in migrationConfig — add "+
49+
"an entry with SchemaVersion=%d",
50+
f.Name(), schemaVersion, schemaVersion)
51+
}
52+
}

sqldb/migrations_test.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"database/sql"
55
"fmt"
66
"path/filepath"
7+
"strings"
78
"testing"
89

910
"github.com/golang-migrate/migrate/v4"
@@ -667,7 +668,7 @@ func TestMigrationConfigConsistency(t *testing.T) {
667668
seenVersions := make(map[int]string)
668669
seenSchemaVersions := make(map[int]string)
669670

670-
for _, m := range migrations {
671+
for i, m := range migrations {
671672
// 1. Verify no duplicate global versions.
672673
if existing, ok := seenVersions[m.Version]; ok {
673674
t.Fatalf("duplicate global version %d: %q and %q",
@@ -680,20 +681,29 @@ func TestMigrationConfigConsistency(t *testing.T) {
680681
// and no two config entries claim the same schema version
681682
// with different file prefixes.
682683
prevSchema := 0
683-
if m.Version > 1 {
684-
prevSchema = migrations[m.Version-2].SchemaVersion
684+
if i > 0 {
685+
prevSchema = migrations[i-1].SchemaVersion
685686
}
686687

688+
require.GreaterOrEqual(t, m.SchemaVersion, prevSchema,
689+
"migration %q regresses schema version from %d to %d",
690+
m.Name, prevSchema, m.SchemaVersion)
691+
687692
// A migration advances the schema if its SchemaVersion is
688693
// higher than the previous migration's SchemaVersion.
689694
if m.SchemaVersion > prevSchema {
690-
_, hasFile := fileSchemaVersions[m.SchemaVersion]
695+
fileName, hasFile := fileSchemaVersions[m.SchemaVersion]
691696
require.True(t, hasFile,
692697
"migration %q (version %d) declares "+
693698
"SchemaVersion=%d but no %06d_*.up.sql"+
694699
" file exists in the embedded FS",
695700
m.Name, m.Version, m.SchemaVersion,
696701
m.SchemaVersion)
702+
require.Equal(t, strings.TrimSuffix(fileName, ".up.sql"),
703+
m.Name, "migration %q (version %d) has "+
704+
"SchemaVersion=%d but its name does not "+
705+
"match embedded file %q",
706+
m.Name, m.Version, m.SchemaVersion, fileName)
697707

698708
if existing, ok := seenSchemaVersions[m.SchemaVersion]; ok {
699709
t.Fatalf("duplicate schema version %d: "+

0 commit comments

Comments
 (0)