1
0
mirror of https://github.com/pocketbase/pocketbase.git synced 2025-03-19 22:19:23 +02:00
pocketbase/core/migrations_runner_test.go

213 lines
5.3 KiB
Go
Raw Normal View History

2024-09-29 19:23:19 +03:00
package core_test
import (
"encoding/json"
"fmt"
"testing"
"time"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tests"
)
func TestMigrationsRunnerUpAndDown(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
callsOrder := []string{}
l := core.MigrationsList{}
l.Register(func(app core.App) error {
callsOrder = append(callsOrder, "up2")
return nil
}, func(app core.App) error {
callsOrder = append(callsOrder, "down2")
return nil
}, "2_test")
l.Register(func(app core.App) error {
callsOrder = append(callsOrder, "up3")
return nil
}, func(app core.App) error {
callsOrder = append(callsOrder, "down3")
return nil
}, "3_test")
l.Register(func(app core.App) error {
callsOrder = append(callsOrder, "up1")
return nil
}, func(app core.App) error {
callsOrder = append(callsOrder, "down1")
return nil
}, "1_test")
l.Register(func(app core.App) error {
callsOrder = append(callsOrder, "up4")
return nil
}, func(app core.App) error {
callsOrder = append(callsOrder, "down4")
return nil
}, "4_test")
l.Add(&core.Migration{
Up: func(app core.App) error {
callsOrder = append(callsOrder, "up5")
return nil
},
Down: func(app core.App) error {
callsOrder = append(callsOrder, "down5")
return nil
},
File: "5_test",
ReapplyCondition: func(txApp core.App, runner *core.MigrationsRunner, fileName string) (bool, error) {
return true, nil
},
})
2024-09-29 19:23:19 +03:00
runner := core.NewMigrationsRunner(app, l)
// ---------------------------------------------------------------
// simulate partially out-of-order applied migration
// ---------------------------------------------------------------
2024-09-29 19:23:19 +03:00
_, err := app.DB().Insert(core.DefaultMigrationsTable, dbx.Params{
"file": "4_test",
"applied": time.Now().UnixMicro() - 2,
}).Execute()
if err != nil {
t.Fatalf("Failed to insert 5_test migration: %v", err)
}
_, err = app.DB().Insert(core.DefaultMigrationsTable, dbx.Params{
"file": "5_test",
"applied": time.Now().UnixMicro() - 1,
}).Execute()
if err != nil {
t.Fatalf("Failed to insert 5_test migration: %v", err)
}
_, err = app.DB().Insert(core.DefaultMigrationsTable, dbx.Params{
2024-09-29 19:23:19 +03:00
"file": "2_test",
"applied": time.Now().UnixMicro(),
}).Execute()
if err != nil {
t.Fatalf("Failed to insert 2_test migration: %v", err)
}
// ---------------------------------------------------------------
// Up()
// ---------------------------------------------------------------
if _, err := runner.Up(); err != nil {
t.Fatal(err)
}
expectedUpCallsOrder := `["up1","up3","up5"]` // skip up2 and up4 since they were applied already (up5 has extra reapply condition)
2024-09-29 19:23:19 +03:00
upCallsOrder, err := json.Marshal(callsOrder)
if err != nil {
t.Fatal(err)
}
if v := string(upCallsOrder); v != expectedUpCallsOrder {
t.Fatalf("Expected Up() calls order %s, got %s", expectedUpCallsOrder, upCallsOrder)
}
// ---------------------------------------------------------------
// reset callsOrder
callsOrder = []string{}
// simulate unrun migration
l.Register(nil, func(app core.App) error {
callsOrder = append(callsOrder, "down6")
2024-09-29 19:23:19 +03:00
return nil
}, "6_test")
2024-09-29 19:23:19 +03:00
// simulate applied migrations from different migrations list
_, err = app.DB().Insert(core.DefaultMigrationsTable, dbx.Params{
"file": "from_different_list",
"applied": time.Now().UnixMicro(),
}).Execute()
if err != nil {
t.Fatalf("Failed to insert from_different_list migration: %v", err)
}
// ---------------------------------------------------------------
// ---------------------------------------------------------------
// Down()
// ---------------------------------------------------------------
if _, err := runner.Down(2); err != nil {
t.Fatal(err)
}
expectedDownCallsOrder := `["down5","down3"]` // revert in the applied order
2024-09-29 19:23:19 +03:00
downCallsOrder, err := json.Marshal(callsOrder)
if err != nil {
t.Fatal(err)
}
if v := string(downCallsOrder); v != expectedDownCallsOrder {
t.Fatalf("Expected Down() calls order %s, got %s", expectedDownCallsOrder, downCallsOrder)
}
}
func TestMigrationsRunnerRemoveMissingAppliedMigrations(t *testing.T) {
t.Parallel()
app, _ := tests.NewTestApp()
defer app.Cleanup()
// mock migrations history
for i := 1; i <= 3; i++ {
_, err := app.DB().Insert(core.DefaultMigrationsTable, dbx.Params{
"file": fmt.Sprintf("%d_test", i),
"applied": time.Now().UnixMicro(),
}).Execute()
if err != nil {
t.Fatal(err)
}
}
if !isMigrationApplied(app, "2_test") {
t.Fatalf("Expected 2_test migration to be applied")
}
// create a runner without 2_test to mock deleted migration
l := core.MigrationsList{}
l.Register(func(app core.App) error {
return nil
}, func(app core.App) error {
return nil
}, "1_test")
l.Register(func(app core.App) error {
return nil
}, func(app core.App) error {
return nil
}, "3_test")
r := core.NewMigrationsRunner(app, l)
if err := r.RemoveMissingAppliedMigrations(); err != nil {
t.Fatalf("Failed to remove missing applied migrations: %v", err)
}
if isMigrationApplied(app, "2_test") {
t.Fatalf("Expected 2_test migration to NOT be applied")
}
}
func isMigrationApplied(app core.App, file string) bool {
var exists bool
2025-01-17 15:58:57 +02:00
err := app.DB().Select("(1)").
2024-09-29 19:23:19 +03:00
From(core.DefaultMigrationsTable).
Where(dbx.HashExp{"file": file}).
Limit(1).
Row(&exists)
return err == nil && exists
}