storj/satellite/configlock_test.go

101 lines
3.7 KiB
Go
Raw Normal View History

// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package satellite_test
import (
"bufio"
"flag"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"storj.io/common/fpath"
"storj.io/common/testcontext"
)
//go:generate go test -run TestConfigLock -generate-config-lock
var createLock = flag.Bool("generate-config-lock", false, "")
// TestConfigLock tests or updates the satellite config lock file.
func TestConfigLock(t *testing.T) {
ctx := testcontext.NewWithTimeout(t, 5*time.Minute)
defer ctx.Cleanup()
// run the satellite executable to create a config file
tempDir := ctx.Dir("", "satellite-cfg-lock-")
satelliteExe := ctx.Compile("storj.io/storj/cmd/satellite")
satelliteCmd := exec.Command(satelliteExe, "--config-dir", tempDir, "--defaults", "release", "setup")
out, err := satelliteCmd.CombinedOutput()
assert.NoErrorf(t, err, "Error running satellite", string(out))
cleanedupConfig := filepath.Join(tempDir, "config-normalized.yaml")
// normalize certain OS-specific paths that occurn in the config
normalizeConfig(t, filepath.Join(tempDir, "config.yaml"), cleanedupConfig, tempDir)
// either compare or save the lock file
lockPath := filepath.Join("..", "scripts", "testdata", "satellite-config.yaml.lock")
if *createLock { // update satellite-config.yaml.lock
// copy using ReadFile/WriteFile, since os.Rename() won't work across drives
input, err := ioutil.ReadFile(cleanedupConfig)
assert.NoErrorf(t, err, "Error reading file for move")
err = ioutil.WriteFile(lockPath, input, 0644)
assert.NoErrorf(t, err, "Error writing file for move")
} else { //compare to satellite-config.yaml.lock
configs1 := readLines(t, lockPath)
configs2 := readLines(t, cleanedupConfig)
if diff := cmp.Diff(configs1, configs2); diff != "" {
t.Errorf(`The satellite config does not match the lock file. (-want +got):\n%s
NOTIFY the #config-changes channel so they can plan for changing it in the release process.
Once you have notified them and got their confirmation, you can update the lock file by running:
"go generate ./satellite"`, diff)
}
}
}
// readLines takes a file path and returns the contents split by lines.
func readLines(t *testing.T, filePath string) []string {
file, err := ioutil.ReadFile(filePath)
assert.NoErrorf(t, err, "Error opening %s", filePath)
return strings.Split(strings.ReplaceAll(string(file), "\r\n", "\n"), "\n")
}
// normalizeConfig replace platform specific storj paths as if they ran as Linux root.
func normalizeConfig(t *testing.T, configIn, configOut, tempDir string) {
in, err := os.Open(configIn)
assert.NoErrorf(t, err, "Error opening %s", in)
defer func() { assert.NoErrorf(t, in.Close(), "Error closing %s", in) }()
out, err := os.Create(configOut)
assert.NoErrorf(t, err, "Error opening %s", out)
defer func() { assert.NoErrorf(t, out.Close(), "Error closing %s", out) }()
scanner := bufio.NewScanner(in)
writer := bufio.NewWriter(out)
defer func() { assert.NoErrorf(t, writer.Flush(), "Error flushing %s", out) }()
appDir := fpath.ApplicationDir()
for scanner.Scan() {
line := scanner.Text()
//fix metrics.app and tracing.app
line = strings.Replace(line, ".exe", "", 1)
//fix server.revocation-dburl
line = strings.Replace(line, tempDir, "testdata", 1)
//fix identity.cert-path and identity.key-path
if strings.Contains(line, appDir) {
line = strings.Replace(line, appDir, "/root/.local/share", 1)
line = strings.ToLower(strings.ReplaceAll(line, "\\", "/"))
}
_, err = writer.WriteString(line + "\n")
assert.NoErrorf(t, err, "Error writing %s", out)
}
assert.NoErrorf(t, scanner.Err(), "Error reading %s", in)
}