Make migrations log output to stdout
Migrations were logging to a mix of stdout and stderr. This was due to the individual migration binaries logging non-error output to stdout, while the migration library (which downloads and executed these migrations) was logging to stderr. This inconsistency can be confusing. Also, previous versions of go-ipfs wrote non-error output to stdout. This PR fixes this so that non-error output from the migrations library is written to stdout. Added test to look for expected log output.
gammazero committed
Apr 5, 2021 at 20:19 UTC
7c8df87cd0710db66b36d875dd2545c180af1e8a
2 files changed
+35
-16
repo/fsrepo/migrations/migrations.go
+17
-15
@@ -38,7 +38,9 @@ func RunMigration(ctx context.Context, fetcher Fetcher, targetVer int, ipfsDir s
38
return fmt.Errorf("downgrade not allowed from %d to %d", fromVer, targetVer)
39
}
40
41
- log.Print("Looking for suitable migration binaries.")
41
+ logger := log.New(os.Stdout, "", 0)
42
+
43
+ logger.Print("Looking for suitable migration binaries.")
44
45
migrations, binPaths, err := findMigrations(ctx, fromVer, targetVer)
46
if err != nil {
@@ -54,7 +56,7 @@ func RunMigration(ctx context.Context, fetcher Fetcher, targetVer int, ipfsDir s
56
}
57
}
58
57
- log.Println("Need", len(missing), "migrations, downloading.")
59
+ logger.Println("Need", len(missing), "migrations, downloading.")
60
61
tmpDir, err := ioutil.TempDir("", "migrations")
62
if err != nil {
@@ -62,9 +64,9 @@ func RunMigration(ctx context.Context, fetcher Fetcher, targetVer int, ipfsDir s
64
}
65
defer os.RemoveAll(tmpDir)
66
65
- fetched, err := fetchMigrations(ctx, fetcher, missing, tmpDir)
67
+ fetched, err := fetchMigrations(ctx, fetcher, missing, tmpDir, logger)
68
if err != nil {
67
- log.Print("Failed to download migrations.")
69
+ logger.Print("Failed to download migrations.")
70
return err
71
}
72
for i := range missing {
@@ -77,13 +79,13 @@ func RunMigration(ctx context.Context, fetcher Fetcher, targetVer int, ipfsDir s
79
revert = true
80
}
81
for _, migration := range migrations {
80
- log.Println("Running migration", migration, "...")
81
- err = runMigration(ctx, binPaths[migration], ipfsDir, revert)
82
+ logger.Println("Running migration", migration, "...")
83
+ err = runMigration(ctx, binPaths[migration], ipfsDir, revert, logger)
84
if err != nil {
85
return fmt.Errorf("migration %s failed: %s", migration, err)
86
}
87
}
86
- log.Printf("Success: fs-repo migrated to version %d.\n", targetVer)
88
+ logger.Printf("Success: fs-repo migrated to version %d.\n", targetVer)
89
90
return nil
91
}
@@ -142,14 +144,14 @@ func findMigrations(ctx context.Context, from, to int) ([]string, map[string]str
144
return migrations, binPaths, nil
145
}
146
145
-func runMigration(ctx context.Context, binPath, ipfsDir string, revert bool) error {
147
+func runMigration(ctx context.Context, binPath, ipfsDir string, revert bool, logger *log.Logger) error {
148
pathArg := fmt.Sprintf("-path=%s", ipfsDir)
149
var cmd *exec.Cmd
150
if revert {
149
- log.Println(" => Running:", binPath, pathArg, "-verbose=true -revert")
151
+ logger.Println(" => Running:", binPath, pathArg, "-verbose=true -revert")
152
cmd = exec.CommandContext(ctx, binPath, pathArg, "-verbose=true", "-revert")
153
} else {
152
- log.Println(" => Running:", binPath, pathArg, "-verbose=true")
154
+ logger.Println(" => Running:", binPath, pathArg, "-verbose=true")
155
cmd = exec.CommandContext(ctx, binPath, pathArg, "-verbose=true")
156
}
157
cmd.Stdout = os.Stdout
@@ -159,7 +161,7 @@ func runMigration(ctx context.Context, binPath, ipfsDir string, revert bool) err
161
162
// fetchMigrations downloads the requested migrations, and returns a slice with
163
// the paths of each binary, in the same order specified by needed.
162
-func fetchMigrations(ctx context.Context, fetcher Fetcher, needed []string, destDir string) ([]string, error) {
164
+func fetchMigrations(ctx context.Context, fetcher Fetcher, needed []string, destDir string, logger *log.Logger) ([]string, error) {
165
osv, err := osWithVariant()
166
if err != nil {
167
return nil, err
@@ -173,21 +175,21 @@ func fetchMigrations(ctx context.Context, fetcher Fetcher, needed []string, dest
175
bins := make([]string, len(needed))
176
// Download and unpack all requested migrations concurrently.
177
for i, name := range needed {
176
- log.Printf("Downloading migration: %s...", name)
178
+ logger.Printf("Downloading migration: %s...", name)
179
go func(i int, name string) {
180
defer wg.Done()
181
dist := path.Join(distMigsRoot, name)
182
ver, err := LatestDistVersion(ctx, fetcher, dist, false)
183
if err != nil {
182
- log.Printf("could not get latest version of migration %s: %s", name, err)
184
+ logger.Printf("could not get latest version of migration %s: %s", name, err)
185
return
186
}
187
loc, err := FetchBinary(ctx, fetcher, dist, ver, name, destDir)
188
if err != nil {
187
- log.Printf("could not download %s: %s", name, err)
189
+ logger.Printf("could not download %s: %s", name, err)
190
return
191
}
190
- log.Printf("Downloaded and unpacked migration: %s (%s)", loc, ver)
192
+ logger.Printf("Downloaded and unpacked migration: %s (%s)", loc, ver)
193
bins[i] = loc
194
}(i, name)
195
}
repo/fsrepo/migrations/migrations_test.go
+18
-1
@@ -2,7 +2,9 @@ package migrations
2
3
import (
4
"context"
5
+ "fmt"
6
"io/ioutil"
7
+ "log"
8
"os"
9
"path/filepath"
10
"strings"
@@ -126,7 +128,10 @@ func TestFetchMigrations(t *testing.T) {
128
defer os.RemoveAll(tmpDir)
129
130
needed := []string{"fs-repo-1-to-2", "fs-repo-2-to-3"}
129
- fetched, err := fetchMigrations(ctx, fetcher, needed, tmpDir)
131
+ buf := new(strings.Builder)
132
+ buf.Grow(256)
133
+ logger := log.New(buf, "", 0)
134
+ fetched, err := fetchMigrations(ctx, fetcher, needed, tmpDir, logger)
135
if err != nil {
136
t.Fatal(err)
137
}
@@ -137,6 +142,18 @@ func TestFetchMigrations(t *testing.T) {
142
t.Error("expected file to exist:", bin)
143
}
144
}
145
+
146
+ // Check expected log output
147
+ for _, mig := range needed {
148
+ logOut := fmt.Sprintf("Downloading migration: %s", mig)
149
+ if !strings.Contains(buf.String(), logOut) {
150
+ t.Fatalf("did not find expected log output %q", logOut)
151
+ }
152
+ logOut = fmt.Sprintf("Downloaded and unpacked migration: %s", filepath.Join(tmpDir, mig))
153
+ if !strings.Contains(buf.String(), logOut) {
154
+ t.Fatalf("did not find expected log output %q", logOut)
155
+ }
156
+ }
157
}
158
159
func TestRunMigrations(t *testing.T) {