Merge pull request #10726 from ziggie1984/fix-migration-table

sqldb: fix migration config consistency coverage
This commit is contained in:
Olaoluwa Osuntokun 2026-04-09 17:20:03 -07:00 committed by GitHub
commit 80572fe39e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 72 additions and 5 deletions

View file

@ -93,7 +93,7 @@ var (
// user if necessary.
},
{
Name: "000009_graph_v2_columns",
Name: "000009_graph_v2",
Version: 11,
SchemaVersion: 9,
},
@ -126,6 +126,11 @@ var (
Version: 16,
SchemaVersion: 13,
},
{
Name: "000014_payments_no_fail_reason_index",
Version: 17,
SchemaVersion: 14,
},
}, migrationAdditions...)
// ErrMigrationMismatch is returned when a migrated record does not

View file

@ -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)
}
}

View file

@ -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: "+