Skip to content

Commit c165a5a

Browse files
alexluongclaude
andauthored
fix(e2e): apply migrations before starting app in tests (#829)
The unified migration CLI (#816) added a startup gate that refuses to start when migrations are pending. E2e tests create fresh databases but never applied migrations, causing all tests to fail. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 003650f commit c165a5a

3 files changed

Lines changed: 69 additions & 0 deletions

File tree

cmd/e2e/configs/migrate.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package configs
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/hookdeck/outpost/internal/config"
8+
"github.com/hookdeck/outpost/internal/logging"
9+
"github.com/hookdeck/outpost/internal/migrator"
10+
"github.com/hookdeck/outpost/internal/migrator/coordinator"
11+
"github.com/hookdeck/outpost/internal/migrator/migrations"
12+
"github.com/hookdeck/outpost/internal/redis"
13+
)
14+
15+
// ApplyMigrations runs all pending SQL and Redis migrations for the given
16+
// config. E2E tests must call this before starting the app, since the app
17+
// refuses to start when migrations are pending.
18+
func ApplyMigrations(t *testing.T, cfg *config.Config) {
19+
t.Helper()
20+
ctx := context.Background()
21+
22+
logger, err := logging.NewLogger(logging.WithLogLevel("warn"))
23+
if err != nil {
24+
t.Fatalf("create logger for migrations: %v", err)
25+
}
26+
27+
// SQL migrator
28+
opts := cfg.ToMigratorOpts()
29+
var sqlMigrator *migrator.Migrator
30+
if opts.PG.URL != "" || opts.CH.Addr != "" {
31+
m, err := migrator.New(opts)
32+
if err != nil {
33+
t.Fatalf("create sql migrator: %v", err)
34+
}
35+
defer func() {
36+
if sourceErr, dbErr := m.Close(ctx); sourceErr != nil || dbErr != nil {
37+
t.Logf("close sql migrator: source=%v db=%v", sourceErr, dbErr)
38+
}
39+
}()
40+
sqlMigrator = m
41+
}
42+
43+
// Redis client
44+
redisClient, err := redis.New(ctx, cfg.Redis.ToConfig())
45+
if err != nil {
46+
t.Fatalf("create redis client for migrations: %v", err)
47+
}
48+
49+
redisMigrations := migrations.AllRedisMigrationsWithLogging(
50+
redisClient, logger, false, cfg.DeploymentID,
51+
)
52+
53+
coord := coordinator.New(coordinator.Config{
54+
SQLMigrator: sqlMigrator,
55+
RedisClient: redisClient,
56+
RedisMigrations: redisMigrations,
57+
DeploymentID: cfg.DeploymentID,
58+
Logger: logger,
59+
})
60+
61+
if err := coord.Apply(ctx, coordinator.ApplyOptions{}); err != nil {
62+
t.Fatalf("apply migrations: %v", err)
63+
}
64+
}

cmd/e2e/regressions_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ func TestE2E_Regression_AutoDisableWithoutCallbackURL(t *testing.T) {
9494
cfg.Alert.ConsecutiveFailureCount = 20
9595

9696
require.NoError(t, cfg.Validate(config.Flags{}))
97+
configs.ApplyMigrations(t, &cfg)
9798

9899
ctx, cancel := context.WithCancel(context.Background())
99100
defer cancel()
@@ -228,6 +229,7 @@ func TestE2E_ManualRetryScheduleInteraction(t *testing.T) {
228229
cfg.LogBatchThresholdSeconds = 0 // Immediate flush so logstore queries work
229230

230231
require.NoError(t, cfg.Validate(config.Flags{}))
232+
configs.ApplyMigrations(t, &cfg)
231233

232234
ctx, cancel := context.WithCancel(context.Background())
233235
defer cancel()
@@ -412,6 +414,7 @@ func TestE2E_Regression_RetryRaceCondition(t *testing.T) {
412414
cfg.RetryVisibilityTimeoutSeconds = 2
413415

414416
require.NoError(t, cfg.Validate(config.Flags{}))
417+
configs.ApplyMigrations(t, &cfg)
415418

416419
ctx, cancel := context.WithCancel(context.Background())
417420
defer cancel()

cmd/e2e/suites_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ func (suite *basicSuite) SetupSuite() {
111111

112112
require.NoError(t, cfg.Validate(config.Flags{}))
113113

114+
configs.ApplyMigrations(t, &cfg)
115+
114116
suite.e2eSuite = e2eSuite{
115117
config: cfg,
116118
mockServerBaseURL: mockServerBaseURL,

0 commit comments

Comments
 (0)