• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

golang-migrate / migrate / 24640136570

19 Apr 2026 09:58PM UTC coverage: 56.328% (+1.9%) from 54.432%
24640136570

Pull #1394

github

joschi
fix: address second round of Copilot review comments

- README.md: fix db.system → db.system.name in database span table
- otel.go: call otel.Handle(err) on instrument creation errors instead
  of silently discarding them (doc comment already promised this)
- migrate.go: use attribute.Int64 for uint version fields to avoid
  int overflow on 32-bit platforms
- migrate.go: sanitize database.Error in otelSpanSetError to avoid
  leaking migration SQL into trace span status descriptions
- database/oteldriver.go: same SQL-leak fix in endSpan; add errors import
- source/oteldriver.go: use attribute.Int64 for uint version fields
- source/oteldriver_test.go: assert span.Status().Code != codes.Error
  directly rather than comparing full sdktrace.Status struct
- source/pkger/pkger.go: fix import grouping (stdlib before third-party)
- source/google_cloud_storage/storage.go: merge context into stdlib group

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pull Request #1394: feat: OpenTelemetry instrumentation

1020 of 1236 new or added lines in 47 files covered. (82.52%)

8 existing lines in 7 files now uncovered.

4731 of 8399 relevant lines covered (56.33%)

50.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/source/testing/testing.go
1
// Package testing has the source tests.
2
// All source drivers must pass the Test function.
3
// This lives in it's own package so it stays a test dependency.
4
package testing
5

6
import (
7
        "context"
8
        "errors"
9
        "os"
10
        "testing"
11

12
        "github.com/golang-migrate/migrate/v4/source"
13
)
14

15
// Test runs tests against source implementations.
16
// It assumes that the driver tests has access to the following migrations:
17
//
18
// u = up migration, d = down migration, n = version
19
//
20
//        |  1  |  -  |  3  |  4  |  5  |  -  |  7  |
21
//        | u d |  -  | u   | u d |   d |  -  | u d |
22
//
23
// See source/stub/stub_test.go or source/file/file_test.go for an example.
24
func Test(t *testing.T, d source.Driver) {
×
NEW
25
        ctx := context.Background()
×
NEW
26
        TestFirst(t, ctx, d)
×
NEW
27
        TestPrev(t, ctx, d)
×
NEW
28
        TestNext(t, ctx, d)
×
NEW
29
        TestReadUp(t, ctx, d)
×
NEW
30
        TestReadDown(t, ctx, d)
×
UNCOV
31
}
×
32

NEW
33
func TestFirst(t *testing.T, ctx context.Context, d source.Driver) {
×
NEW
34
        version, err := d.First(ctx)
×
35
        if err != nil {
×
36
                t.Fatalf("First: expected err to be nil, got %v", err)
×
37
        }
×
38
        if version != 1 {
×
39
                t.Errorf("First: expected 1, got %v", version)
×
40
        }
×
41
}
42

NEW
43
func TestPrev(t *testing.T, ctx context.Context, d source.Driver) {
×
44
        tt := []struct {
×
45
                version           uint
×
46
                expectErr         error
×
47
                expectPrevVersion uint
×
48
        }{
×
49
                {version: 0, expectErr: os.ErrNotExist},
×
50
                {version: 1, expectErr: os.ErrNotExist},
×
51
                {version: 2, expectErr: os.ErrNotExist},
×
52
                {version: 3, expectErr: nil, expectPrevVersion: 1},
×
53
                {version: 4, expectErr: nil, expectPrevVersion: 3},
×
54
                {version: 5, expectErr: nil, expectPrevVersion: 4},
×
55
                {version: 6, expectErr: os.ErrNotExist},
×
56
                {version: 7, expectErr: nil, expectPrevVersion: 5},
×
57
                {version: 8, expectErr: os.ErrNotExist},
×
58
                {version: 9, expectErr: os.ErrNotExist},
×
59
        }
×
60

×
61
        for i, v := range tt {
×
NEW
62
                pv, err := d.Prev(ctx, v.version)
×
63
                if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) && v.expectErr != err {
×
64
                        t.Errorf("Prev: expected %v, got %v, in %v", v.expectErr, err, i)
×
65
                }
×
66
                if err == nil && v.expectPrevVersion != pv {
×
67
                        t.Errorf("Prev: expected %v, got %v, in %v", v.expectPrevVersion, pv, i)
×
68
                }
×
69
        }
70
}
71

NEW
72
func TestNext(t *testing.T, ctx context.Context, d source.Driver) {
×
73
        tt := []struct {
×
74
                version           uint
×
75
                expectErr         error
×
76
                expectNextVersion uint
×
77
        }{
×
78
                {version: 0, expectErr: os.ErrNotExist},
×
79
                {version: 1, expectErr: nil, expectNextVersion: 3},
×
80
                {version: 2, expectErr: os.ErrNotExist},
×
81
                {version: 3, expectErr: nil, expectNextVersion: 4},
×
82
                {version: 4, expectErr: nil, expectNextVersion: 5},
×
83
                {version: 5, expectErr: nil, expectNextVersion: 7},
×
84
                {version: 6, expectErr: os.ErrNotExist},
×
85
                {version: 7, expectErr: os.ErrNotExist},
×
86
                {version: 8, expectErr: os.ErrNotExist},
×
87
                {version: 9, expectErr: os.ErrNotExist},
×
88
        }
×
89

×
90
        for i, v := range tt {
×
NEW
91
                nv, err := d.Next(ctx, v.version)
×
92
                if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) && v.expectErr != err {
×
93
                        t.Errorf("Next: expected %v, got %v, in %v", v.expectErr, err, i)
×
94
                }
×
95
                if err == nil && v.expectNextVersion != nv {
×
96
                        t.Errorf("Next: expected %v, got %v, in %v", v.expectNextVersion, nv, i)
×
97
                }
×
98
        }
99
}
100

NEW
101
func TestReadUp(t *testing.T, ctx context.Context, d source.Driver) {
×
102
        tt := []struct {
×
103
                version   uint
×
104
                expectErr error
×
105
                expectUp  bool
×
106
        }{
×
107
                {version: 0, expectErr: os.ErrNotExist},
×
108
                {version: 1, expectErr: nil, expectUp: true},
×
109
                {version: 2, expectErr: os.ErrNotExist},
×
110
                {version: 3, expectErr: nil, expectUp: true},
×
111
                {version: 4, expectErr: nil, expectUp: true},
×
112
                {version: 5, expectErr: os.ErrNotExist},
×
113
                {version: 6, expectErr: os.ErrNotExist},
×
114
                {version: 7, expectErr: nil, expectUp: true},
×
115
                {version: 8, expectErr: os.ErrNotExist},
×
116
        }
×
117

×
118
        for i, v := range tt {
×
NEW
119
                up, identifier, err := d.ReadUp(ctx, v.version)
×
120
                if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) ||
×
121
                        (v.expectErr != os.ErrNotExist && err != v.expectErr) {
×
122
                        t.Errorf("expected %v, got %v, in %v", v.expectErr, err, i)
×
123

×
124
                } else if err == nil {
×
125
                        if len(identifier) == 0 {
×
126
                                t.Errorf("expected identifier not to be empty, in %v", i)
×
127
                        }
×
128

129
                        if v.expectUp && up == nil {
×
130
                                t.Errorf("expected up not to be nil, in %v", i)
×
131
                        } else if !v.expectUp && up != nil {
×
132
                                t.Errorf("expected up to be nil, got %v, in %v", up, i)
×
133
                        }
×
134
                }
135
                if up != nil {
×
136
                        if err := up.Close(); err != nil {
×
137
                                t.Error(err)
×
138
                        }
×
139
                }
140
        }
141
}
142

NEW
143
func TestReadDown(t *testing.T, ctx context.Context, d source.Driver) {
×
144
        tt := []struct {
×
145
                version    uint
×
146
                expectErr  error
×
147
                expectDown bool
×
148
        }{
×
149
                {version: 0, expectErr: os.ErrNotExist},
×
150
                {version: 1, expectErr: nil, expectDown: true},
×
151
                {version: 2, expectErr: os.ErrNotExist},
×
152
                {version: 3, expectErr: os.ErrNotExist},
×
153
                {version: 4, expectErr: nil, expectDown: true},
×
154
                {version: 5, expectErr: nil, expectDown: true},
×
155
                {version: 6, expectErr: os.ErrNotExist},
×
156
                {version: 7, expectErr: nil, expectDown: true},
×
157
                {version: 8, expectErr: os.ErrNotExist},
×
158
        }
×
159

×
160
        for i, v := range tt {
×
NEW
161
                down, identifier, err := d.ReadDown(ctx, v.version)
×
162
                if (v.expectErr == os.ErrNotExist && !errors.Is(err, os.ErrNotExist)) ||
×
163
                        (v.expectErr != os.ErrNotExist && err != v.expectErr) {
×
164
                        t.Errorf("expected %v, got %v, in %v", v.expectErr, err, i)
×
165

×
166
                } else if err == nil {
×
167
                        if len(identifier) == 0 {
×
168
                                t.Errorf("expected identifier not to be empty, in %v", i)
×
169
                        }
×
170

171
                        if v.expectDown && down == nil {
×
172
                                t.Errorf("expected down not to be nil, in %v", i)
×
173
                        } else if !v.expectDown && down != nil {
×
174
                                t.Errorf("expected down to be nil, got %v, in %v", down, i)
×
175
                        }
×
176
                }
177
                if down != nil {
×
178
                        if err := down.Close(); err != nil {
×
179
                                t.Error(err)
×
180
                        }
×
181
                }
182
        }
183
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc