mirror of
https://github.com/kopia/kopia.git
synced 2026-01-24 14:28:06 -05:00
* refactor: move from io/ioutil to io and os package The io/ioutil package has been deprecated as of Go 1.16, see https://golang.org/doc/go1.16#ioutil. This commit replaces the existing io/ioutil functions with their new definitions in io and os packages. Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * chore: remove //nolint:gosec for os.ReadFile At the time of this commit, the G304 rule of gosec does not include the `os.ReadFile` function. We remove `//nolint:gosec` temporarily until https://github.com/securego/gosec/pull/706 is merged. Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
162 lines
3.5 KiB
Go
162 lines
3.5 KiB
Go
package testutil
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"math/rand"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/kopia/kopia/internal/clock"
|
|
)
|
|
|
|
const (
|
|
maxOutputLinesToLog = 4000
|
|
logsDirPermissions = 0o750
|
|
)
|
|
|
|
var interestingLengths = []int{10, 50, 100, 240, 250, 260, 270}
|
|
|
|
// GetInterestingTempDirectoryName returns interesting directory name used for testing.
|
|
func GetInterestingTempDirectoryName() (string, error) {
|
|
td, err := os.MkdirTemp("", "kopia-test")
|
|
if err != nil {
|
|
return "", errors.Wrap(err, "unable to create temp directory")
|
|
}
|
|
|
|
// nolint:gosec
|
|
targetLen := interestingLengths[rand.Intn(len(interestingLengths))]
|
|
|
|
// make sure the base directory is quite long to trigger very long filenames on Windows.
|
|
if n := len(td); n < targetLen {
|
|
td = filepath.Join(td, strings.Repeat("f", targetLen-n))
|
|
// nolint:gomnd
|
|
if err := os.MkdirAll(td, 0o700); err != nil {
|
|
return "", errors.Wrap(err, "unable to create temp directory")
|
|
}
|
|
}
|
|
|
|
return td, nil
|
|
}
|
|
|
|
// TempDirectory returns an interesting temporary directory and cleans it up before test
|
|
// completes.
|
|
func TempDirectory(tb testing.TB) string {
|
|
tb.Helper()
|
|
|
|
d, err := GetInterestingTempDirectoryName()
|
|
if err != nil {
|
|
tb.Fatal(err)
|
|
}
|
|
|
|
tb.Cleanup(func() {
|
|
if !tb.Failed() {
|
|
os.RemoveAll(d) // nolint:errcheck
|
|
} else {
|
|
tb.Logf("temporary files left in %v", d)
|
|
}
|
|
})
|
|
|
|
return d
|
|
}
|
|
|
|
// TempLogDirectory returns a temporary directory used for storing logs.
|
|
// If KOPIA_LOGS_DIR is provided.
|
|
func TempLogDirectory(t *testing.T) string {
|
|
t.Helper()
|
|
|
|
cleanName := strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(
|
|
t.Name(),
|
|
"/", "_"), "\\", "_"), ":", "_")
|
|
|
|
t.Helper()
|
|
|
|
logsBaseDir := os.Getenv("KOPIA_LOGS_DIR")
|
|
if logsBaseDir == "" {
|
|
logsBaseDir = filepath.Join(os.TempDir(), "kopia-logs")
|
|
}
|
|
|
|
logsDir := filepath.Join(logsBaseDir, cleanName+"."+clock.Now().Local().Format("20060102150405"))
|
|
|
|
require.NoError(t, os.MkdirAll(logsDir, logsDirPermissions))
|
|
|
|
t.Cleanup(func() {
|
|
if os.Getenv("KOPIA_KEEP_LOGS") != "" {
|
|
t.Logf("logs preserved in %v", logsDir)
|
|
return
|
|
}
|
|
|
|
if t.Failed() && os.Getenv("KOPIA_DISABLE_LOG_DUMP_ON_FAILURE") == "" {
|
|
dumpLogs(t, logsDir)
|
|
}
|
|
|
|
os.RemoveAll(logsDir) // nolint:errcheck
|
|
})
|
|
|
|
return logsDir
|
|
}
|
|
|
|
func dumpLogs(t *testing.T, dirname string) {
|
|
t.Helper()
|
|
|
|
entries, err := ioutil.ReadDir(dirname)
|
|
if err != nil {
|
|
t.Errorf("unable to read %v: %v", dirname, err)
|
|
|
|
return
|
|
}
|
|
|
|
for _, e := range entries {
|
|
if e.IsDir() {
|
|
dumpLogs(t, filepath.Join(dirname, e.Name()))
|
|
continue
|
|
}
|
|
|
|
dumpLogFile(t, filepath.Join(dirname, e.Name()))
|
|
}
|
|
}
|
|
|
|
func dumpLogFile(t *testing.T, fname string) {
|
|
t.Helper()
|
|
|
|
data, err := os.ReadFile(fname)
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
|
|
t.Logf("LOG FILE: %v %v", fname, trimOutput(string(data)))
|
|
}
|
|
|
|
func trimOutput(s string) string {
|
|
lines := splitLines(s)
|
|
if len(lines) <= maxOutputLinesToLog {
|
|
return s
|
|
}
|
|
|
|
lines2 := append([]string(nil), lines[0:(maxOutputLinesToLog/2)]...) // nolint:gomnd
|
|
lines2 = append(lines2, fmt.Sprintf("/* %v lines removed */", len(lines)-maxOutputLinesToLog))
|
|
lines2 = append(lines2, lines[len(lines)-(maxOutputLinesToLog/2):]...) // nolint:gomnd
|
|
|
|
return strings.Join(lines2, "\n")
|
|
}
|
|
|
|
func splitLines(s string) []string {
|
|
s = strings.TrimSpace(s)
|
|
if s == "" {
|
|
return nil
|
|
}
|
|
|
|
var result []string
|
|
for _, l := range strings.Split(s, "\n") {
|
|
result = append(result, strings.TrimRight(l, "\r"))
|
|
}
|
|
|
|
return result
|
|
}
|