mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-07-12 06:02:51 +02:00
sqldb: add unit test for the v0.19.0-rc1 migration bug
This commit is contained in:
@ -578,3 +578,168 @@ func TestSchemaMigrationIdempotency(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestMigrationBug19RC1 tests a bug that was present in the migration code
|
||||
// at the v0.19.0-rc1 release.
|
||||
// The bug was fixed in: https://github.com/lightningnetwork/lnd/pull/9647
|
||||
// NOTE: This test may be removed once the final version of 0.19.0 is released.
|
||||
func TestMigrationSucceedsAfterDirtyStateMigrationFailure19RC1(t *testing.T) {
|
||||
// setMigrationTrackerVersion is a helper function that
|
||||
// updates the migration tracker table to a specific version that
|
||||
// simulates the conditions of the bug.
|
||||
setMigrationTrackerVersion := func(t *testing.T, db *BaseDB) {
|
||||
_, err := db.Exec(`
|
||||
DELETE FROM migration_tracker;
|
||||
INSERT INTO migration_tracker (version, migration_time)
|
||||
VALUES (2, CURRENT_TIMESTAMP);
|
||||
`)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
const (
|
||||
maxSchemaVersionBefore19RC1 = 4
|
||||
failingSchemaVersion = 3
|
||||
)
|
||||
|
||||
ctxb := context.Background()
|
||||
migrations := GetMigrations()
|
||||
migrations = migrations[:maxSchemaVersionBefore19RC1]
|
||||
lastMigration := migrations[len(migrations)-1]
|
||||
|
||||
// Make sure that the last migration is the one we expect.
|
||||
require.Equal(
|
||||
t, maxSchemaVersionBefore19RC1, lastMigration.SchemaVersion,
|
||||
)
|
||||
|
||||
t.Run("SQLite", func(t *testing.T) {
|
||||
// First instantiate the database and run the migrations
|
||||
// including the custom migrations.
|
||||
t.Logf("Creating new SQLite DB for testing migrations")
|
||||
|
||||
dbFileName := filepath.Join(t.TempDir(), "tmp.db")
|
||||
var (
|
||||
db *SqliteStore
|
||||
err error
|
||||
)
|
||||
|
||||
db, err = NewSqliteStore(&SqliteConfig{
|
||||
SkipMigrations: false,
|
||||
}, dbFileName)
|
||||
require.NoError(t, err)
|
||||
|
||||
dbToCleanup := db.DB
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, dbToCleanup.Close())
|
||||
})
|
||||
|
||||
require.NoError(t, db.ApplyAllMigrations(ctxb, migrations))
|
||||
|
||||
version, dirty, err := db.GetSchemaVersion()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Now reset the schema version to 0 and make sure that
|
||||
// we can apply the migrations again.
|
||||
require.Equal(t, lastMigration.SchemaVersion, version)
|
||||
require.False(t, dirty)
|
||||
|
||||
// Set the schema version to the failing version and
|
||||
// make make the version dirty which essentially tells
|
||||
// golang-migrate that the migration failed.
|
||||
require.NoError(
|
||||
t, db.SetSchemaVersion(failingSchemaVersion, true),
|
||||
)
|
||||
|
||||
// Set the migration tracker to the failing version.
|
||||
setMigrationTrackerVersion(t, db.BaseDB)
|
||||
|
||||
// Close the DB so we can reopen it and apply the
|
||||
// migrations again.
|
||||
db.DB.Close()
|
||||
|
||||
db, err = NewSqliteStore(&SqliteConfig{
|
||||
SkipMigrations: false,
|
||||
}, dbFileName)
|
||||
require.NoError(t, err)
|
||||
|
||||
dbToCleanup2 := db.DB
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, dbToCleanup2.Close())
|
||||
})
|
||||
|
||||
require.NoError(t, db.ApplyAllMigrations(ctxb, migrations))
|
||||
|
||||
version, dirty, err = db.GetSchemaVersion()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, lastMigration.SchemaVersion, version)
|
||||
require.False(t, dirty)
|
||||
})
|
||||
|
||||
t.Run("Postgres", func(t *testing.T) {
|
||||
// First create a temporary Postgres database to run
|
||||
// the migrations on.
|
||||
fixture := NewTestPgFixture(
|
||||
t, DefaultPostgresFixtureLifetime,
|
||||
)
|
||||
t.Cleanup(func() {
|
||||
fixture.TearDown(t)
|
||||
})
|
||||
|
||||
dbName := randomDBName(t)
|
||||
|
||||
// Next instantiate the database and run the migrations
|
||||
// including the custom migrations.
|
||||
t.Logf("Creating new Postgres DB '%s' for testing "+
|
||||
"migrations", dbName)
|
||||
|
||||
_, err := fixture.db.ExecContext(
|
||||
context.Background(), "CREATE DATABASE "+dbName,
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := fixture.GetConfig(dbName)
|
||||
var db *PostgresStore
|
||||
|
||||
cfg.SkipMigrations = false
|
||||
db, err = NewPostgresStore(cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, db.ApplyAllMigrations(ctxb, migrations))
|
||||
|
||||
version, dirty, err := db.GetSchemaVersion()
|
||||
require.NoError(t, err)
|
||||
|
||||
// Now reset the schema version to 0 and make sure that
|
||||
// we can apply the migrations again.
|
||||
require.Equal(t, lastMigration.SchemaVersion, version)
|
||||
require.False(t, dirty)
|
||||
|
||||
// Set the schema version to the failing version and
|
||||
// make make the version dirty which essentially tells
|
||||
// golang-migrate that the migration failed.
|
||||
require.NoError(
|
||||
t, db.SetSchemaVersion(failingSchemaVersion, true),
|
||||
)
|
||||
|
||||
// Set the migration tracker to the failing version.
|
||||
setMigrationTrackerVersion(t, db.BaseDB)
|
||||
|
||||
// Close the DB so we can reopen it and apply the
|
||||
// migrations again.
|
||||
db.DB.Close()
|
||||
|
||||
db, err = NewPostgresStore(cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
dbToCleanup2 := db.DB
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, dbToCleanup2.Close())
|
||||
})
|
||||
|
||||
require.NoError(t, db.ApplyAllMigrations(ctxb, migrations))
|
||||
|
||||
version, dirty, err = db.GetSchemaVersion()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, lastMigration.SchemaVersion, version)
|
||||
require.False(t, dirty)
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user