@@ -24,31 +24,126 @@ func TestEnsureSchemaTable(t *testing.T) {
24
24
store := testStore (db )
25
25
ctx := context .Background ()
26
26
27
- if err := store .Exec (ctx , sqlf .Sprintf ("SELECT * FROM test_migrations_table" )); err == nil {
28
- t .Fatalf ("expected query to fail due to missing schema table" )
27
+ tableNames := []string {
28
+ "migration_logs" ,
29
+ defaultTestTableName ,
29
30
}
30
31
31
- if err := store .Exec (ctx , sqlf .Sprintf ("SELECT * FROM migration_logs" )); err == nil {
32
- t .Fatalf ("expected query to fail due to missing logs table" )
32
+ // Test initially missing tables
33
+ for _ , tableName := range tableNames {
34
+ if err := store .Exec (ctx , sqlf .Sprintf ("SELECT * FROM %s" , quote (tableName ))); err == nil {
35
+ t .Fatalf ("expected query to fail due to missing table %q" , tableName )
36
+ }
33
37
}
34
38
35
39
if err := store .EnsureSchemaTable (ctx ); err != nil {
36
40
t .Fatalf ("unexpected error ensuring schema table exists: %s" , err )
37
41
}
38
42
39
- if err := store .Exec (ctx , sqlf .Sprintf ("SELECT * FROM test_migrations_table" )); err != nil {
40
- t .Fatalf ("unexpected error querying version table: %s" , err )
41
- }
42
-
43
- if err := store .Exec (ctx , sqlf .Sprintf ("SELECT * FROM migration_logs" )); err != nil {
44
- t .Fatalf ("unexpected error querying logs table: %s" , err )
43
+ // Test tables were created
44
+ for _ , tableName := range tableNames {
45
+ if err := store .Exec (ctx , sqlf .Sprintf ("SELECT * FROM %s" , quote (tableName ))); err != nil {
46
+ t .Fatalf ("unexpected error querying %q: %s" , tableName , err )
47
+ }
45
48
}
46
49
50
+ // Test idempotency
47
51
if err := store .EnsureSchemaTable (ctx ); err != nil {
48
52
t .Fatalf ("expected method to be idempotent, got error: %s" , err )
49
53
}
50
54
}
51
55
56
+ func TestEnsureTableBackfills (t * testing.T ) {
57
+ t .Run ("fresh database" , func (t * testing.T ) {
58
+ db := dbtest .NewDB (t )
59
+ store := testStore (db )
60
+ ctx := context .Background ()
61
+
62
+ if err := store .EnsureSchemaTable (ctx ); err != nil {
63
+ t .Fatalf ("unexpected error ensuring schema table exists: %s" , err )
64
+ }
65
+
66
+ assertLogs (t , ctx , store , nil )
67
+ })
68
+
69
+ k := 5
70
+ n := k * 5
71
+ tableName := "test_migrations_table_backfill"
72
+
73
+ expectedLogs := make ([]migrationLog , 0 , n )
74
+ for i := 0 ; i <= n ; i ++ {
75
+ s := true
76
+ expectedLogs = append (expectedLogs , migrationLog {Schema : tableName , Version : 1000000000 + i , Up : true , Success : & s })
77
+ }
78
+
79
+ runTest := func (k int ) func (t * testing.T ) {
80
+ return func (t * testing.T ) {
81
+ db := dbtest .NewDB (t )
82
+ store := NewWithDB (db , tableName , NewOperations (& observation .TestContext ))
83
+ ctx := context .Background ()
84
+
85
+ if err := store .Exec (ctx , sqlf .Sprintf (`CREATE TABLE %s(version bigint NOT NULL PRIMARY KEY, dirty boolean NOT NULL)` , quote (tableName ))); err != nil {
86
+ t .Fatalf ("unexpected error: %s" , err )
87
+ }
88
+ if err := store .Exec (ctx , sqlf .Sprintf (`INSERT INTO %s VALUES (%s, false)` , quote (tableName ), 1000000000 + n )); err != nil {
89
+ t .Fatalf ("unexpected error: %s" , err )
90
+ }
91
+
92
+ if err := store .Exec (ctx , sqlf .Sprintf (`
93
+ CREATE TABLE migration_logs(
94
+ id SERIAL PRIMARY KEY,
95
+ migration_logs_schema_version integer NOT NULL,
96
+ schema text NOT NULL,
97
+ version integer NOT NULL,
98
+ up bool NOT NULL,
99
+ started_at timestamptz NOT NULL,
100
+ finished_at timestamptz,
101
+ success boolean,
102
+ error_message text
103
+ )
104
+ ` )); err != nil {
105
+ t .Fatalf ("unexpected error: %s" , err )
106
+ }
107
+
108
+ for i := 0 ; i < k ; i ++ {
109
+ if err := store .Exec (ctx , sqlf .Sprintf (`
110
+ INSERT INTO migration_logs(
111
+ migration_logs_schema_version,
112
+ schema,
113
+ version,
114
+ up,
115
+ started_at,
116
+ finished_at,
117
+ success
118
+ ) VALUES (
119
+ 1,
120
+ %s,
121
+ %s,
122
+ true,
123
+ NOW(),
124
+ NOW(),
125
+ true
126
+ )` ,
127
+ tableName ,
128
+ 1000000000 + n - i ,
129
+ )); err != nil {
130
+ t .Fatalf ("unexpected error: %s" , err )
131
+ }
132
+ }
133
+
134
+ if err := store .EnsureSchemaTable (ctx ); err != nil {
135
+ t .Fatalf ("unexpected error ensuring schema table exists: %s" , err )
136
+ }
137
+
138
+ assertLogs (t , ctx , store , expectedLogs )
139
+ }
140
+ }
141
+
142
+ t .Run ("full insert" , runTest (0 )) // no migration logs
143
+ t .Run ("partial insert" , runTest (k )) // k migration logs
144
+ t .Run ("nothing to insert" , runTest (n )) // n migration logs
145
+ }
146
+
52
147
func TestVersion (t * testing.T ) {
53
148
db := dbtest .NewDB (t )
54
149
store := testStore (db )
@@ -77,10 +172,10 @@ func TestVersion(t *testing.T) {
77
172
78
173
for _ , testCase := range testCases {
79
174
t .Run (testCase .name , func (t * testing.T ) {
80
- if err := store .Exec (ctx , sqlf .Sprintf (`DELETE FROM test_migrations_table` )); err != nil {
175
+ if err := store .Exec (ctx , sqlf .Sprintf (`DELETE FROM %s` , quote ( defaultTestTableName ) )); err != nil {
81
176
t .Fatalf ("unexpected error clearing data: %s" , err )
82
177
}
83
- if err := store .Exec (ctx , sqlf .Sprintf (`INSERT INTO test_migrations_table VALUES (%s, %s)` , testCase .version , testCase .dirty )); err != nil {
178
+ if err := store .Exec (ctx , sqlf .Sprintf (`INSERT INTO %s VALUES (%s, %s)` , quote ( defaultTestTableName ) , testCase .version , testCase .dirty )); err != nil {
84
179
t .Fatalf ("unexpected error inserting data: %s" , err )
85
180
}
86
181
@@ -154,7 +249,7 @@ func TestVersions(t *testing.T) {
154
249
error_message
155
250
) VALUES (%s, %s, %s, %s, NOW(), %s, NOW(), %s)` ,
156
251
currentMigrationLogSchemaVersion ,
157
- "test_migrations_table" ,
252
+ defaultTestTableName ,
158
253
migrationLog .version ,
159
254
migrationLog .up ,
160
255
migrationLog .success ,
@@ -227,7 +322,7 @@ func TestWrappedUp(t *testing.T) {
227
322
if err := store .EnsureSchemaTable (ctx ); err != nil {
228
323
t .Fatalf ("unexpected error ensuring schema table exists: %s" , err )
229
324
}
230
- if err := store .Exec (ctx , sqlf .Sprintf (`INSERT INTO test_migrations_table VALUES (15, false)` )); err != nil {
325
+ if err := store .Exec (ctx , sqlf .Sprintf (`INSERT INTO %s VALUES (15, false)` , quote ( defaultTestTableName ) )); err != nil {
231
326
t .Fatalf ("unexpected error setting initial version: %s" , err )
232
327
}
233
328
@@ -268,7 +363,7 @@ func TestWrappedUp(t *testing.T) {
268
363
269
364
assertLogs (t , ctx , store , []migrationLog {
270
365
{
271
- Schema : "test_migrations_table" ,
366
+ Schema : defaultTestTableName ,
272
367
Version : 16 ,
273
368
Up : true ,
274
369
Success : boolPtr (true ),
@@ -331,7 +426,7 @@ func TestWrappedUp(t *testing.T) {
331
426
332
427
assertLogs (t , ctx , store , []migrationLog {
333
428
{
334
- Schema : "test_migrations_table" ,
429
+ Schema : defaultTestTableName ,
335
430
Version : 17 ,
336
431
Up : true ,
337
432
Success : boolPtr (false ),
@@ -374,7 +469,7 @@ func TestWrappedDown(t *testing.T) {
374
469
if err := store .EnsureSchemaTable (ctx ); err != nil {
375
470
t .Fatalf ("unexpected error ensuring schema table exists: %s" , err )
376
471
}
377
- if err := store .Exec (ctx , sqlf .Sprintf (`INSERT INTO test_migrations_table VALUES (14, false)` )); err != nil {
472
+ if err := store .Exec (ctx , sqlf .Sprintf (`INSERT INTO %s VALUES (14, false)` , quote ( defaultTestTableName ) )); err != nil {
378
473
t .Fatalf ("unexpected error setting initial version: %s" , err )
379
474
}
380
475
if err := store .Exec (ctx , sqlf .Sprintf (`
@@ -429,7 +524,7 @@ func TestWrappedDown(t *testing.T) {
429
524
430
525
assertLogs (t , ctx , store , []migrationLog {
431
526
{
432
- Schema : "test_migrations_table" ,
527
+ Schema : defaultTestTableName ,
433
528
Version : 14 ,
434
529
Up : false ,
435
530
Success : boolPtr (true ),
@@ -487,7 +582,7 @@ func TestWrappedDown(t *testing.T) {
487
582
488
583
assertLogs (t , ctx , store , []migrationLog {
489
584
{
490
- Schema : "test_migrations_table" ,
585
+ Schema : defaultTestTableName ,
491
586
Version : 13 ,
492
587
Up : false ,
493
588
Success : boolPtr (false ),
@@ -675,8 +770,14 @@ retryLoop:
675
770
}
676
771
}
677
772
773
+ const defaultTestTableName = "test_migrations_table"
774
+
678
775
func testStore (db dbutil.DB ) * Store {
679
- return NewWithDB (db , "test_migrations_table" , NewOperations (& observation .TestContext ))
776
+ return testStoreWithName (db , defaultTestTableName )
777
+ }
778
+
779
+ func testStoreWithName (db dbutil.DB , name string ) * Store {
780
+ return NewWithDB (db , name , NewOperations (& observation .TestContext ))
680
781
}
681
782
682
783
func strPtr (v string ) * string {
@@ -698,7 +799,7 @@ func truncateLogs(t *testing.T, ctx context.Context, store *Store) {
698
799
func assertLogs (t * testing.T , ctx context.Context , store * Store , expectedLogs []migrationLog ) {
699
800
t .Helper ()
700
801
701
- logs , err := scanMigrationLogs (store .Query (ctx , sqlf .Sprintf (`SELECT schema, version, up, success FROM migration_logs ORDER BY started_at ` )))
802
+ logs , err := scanMigrationLogs (store .Query (ctx , sqlf .Sprintf (`SELECT schema, version, up, success FROM migration_logs ORDER BY version ` )))
702
803
if err != nil {
703
804
t .Fatalf ("unexpected error scanning logs: %s" , err )
704
805
}
0 commit comments