diff --git a/.github/workflows/test-build-deploy.yml b/.github/workflows/test-build-deploy.yml index 5fb05c50..5a341936 100644 --- a/.github/workflows/test-build-deploy.yml +++ b/.github/workflows/test-build-deploy.yml @@ -11,7 +11,7 @@ jobs: lint: runs-on: ubuntu-24.04 container: - image: quay.io/cortexproject/build-image:master-0ddced051 + image: quay.io/cortexproject/build-image:master-59491e9aae steps: - name: Checkout Repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -48,7 +48,7 @@ jobs: test: runs-on: ubuntu-24.04 container: - image: quay.io/cortexproject/build-image:master-0ddced051 + image: quay.io/cortexproject/build-image:master-59491e9aae steps: - name: Checkout Repo uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..26b4afdb --- /dev/null +++ b/.golangci.yml @@ -0,0 +1 @@ +version: "2" diff --git a/Makefile b/Makefile index f33c8ea7..d99e44b9 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ check-protos: protos git diff --exit-code || (echo "Please rebuild protobuf code by running 'make protos'" && false) lint: - golangci-lint run --new-from-rev d2f56921e6b0 + golangci-lint run test: go test ./... diff --git a/exec/exec.go b/exec/exec.go deleted file mode 100644 index c4b7721a..00000000 --- a/exec/exec.go +++ /dev/null @@ -1,35 +0,0 @@ -package exec - -import ( - "io" - "os/exec" -) - -// Cmd is a hook for mocking -type Cmd interface { - StdoutPipe() (io.ReadCloser, error) - StderrPipe() (io.ReadCloser, error) - Start() error - Wait() error - Kill() error - Output() ([]byte, error) - Run() error - SetEnv([]string) -} - -// Command is a hook for mocking -var Command = func(name string, args ...string) Cmd { - return &realCmd{exec.Command(name, args...)} -} - -type realCmd struct { - *exec.Cmd -} - -func (c *realCmd) Kill() error { - return c.Cmd.Process.Kill() -} - -func (c *realCmd) SetEnv(env []string) { - c.Cmd.Env = env -} diff --git a/fs/fs.go b/fs/fs.go deleted file mode 100644 index e56bc91d..00000000 --- a/fs/fs.go +++ /dev/null @@ -1,99 +0,0 @@ -package fs - -import ( - "io" - "os" - "syscall" -) - -// Interface is the filesystem interface type. -type Interface interface { - ReadDir(string) ([]os.DirEntry, error) - ReadDirNames(string) ([]string, error) - ReadDirCount(string) (int, error) - ReadFile(string) ([]byte, error) - Lstat(string, *syscall.Stat_t) error - Stat(string, *syscall.Stat_t) error - Open(string) (io.ReadWriteCloser, error) -} - -type realFS struct{} - -// FS is the way you should access the filesystem. -var fs Interface = realFS{} - -func (realFS) ReadDir(path string) ([]os.DirEntry, error) { - return os.ReadDir(path) -} - -func (realFS) ReadDirNames(path string) ([]string, error) { - fh, err := os.Open(path) - if err != nil { - return nil, err - } - defer fh.Close() - return fh.Readdirnames(-1) -} - -func (realFS) ReadFile(path string) ([]byte, error) { - return os.ReadFile(path) -} - -func (realFS) Lstat(path string, stat *syscall.Stat_t) error { - return syscall.Lstat(path, stat) -} - -func (realFS) Stat(path string, stat *syscall.Stat_t) error { - return syscall.Stat(path, stat) -} - -func (realFS) Open(path string) (io.ReadWriteCloser, error) { - return os.Open(path) -} - -// trampolines here to allow users to do fs.ReadDir etc - -// ReadDir see ioutil.ReadDir -func ReadDir(path string) ([]os.DirEntry, error) { - return fs.ReadDir(path) -} - -// ReadDirNames see os.File.ReadDirNames -func ReadDirNames(path string) ([]string, error) { - return fs.ReadDirNames(path) -} - -// ReadDirCount is an optimized way to call len(ReadDirNames) -func ReadDirCount(path string) (int, error) { - return fs.ReadDirCount(path) -} - -// ReadFile see ioutil.ReadFile -func ReadFile(path string) ([]byte, error) { - return fs.ReadFile(path) -} - -// Lstat see syscall.Lstat -func Lstat(path string, stat *syscall.Stat_t) error { - return fs.Lstat(path, stat) -} - -// Stat see syscall.Stat -func Stat(path string, stat *syscall.Stat_t) error { - return fs.Stat(path, stat) -} - -// Open see os.Open -func Open(path string) (io.ReadWriteCloser, error) { - return fs.Open(path) -} - -// Mock is used to switch out the filesystem for a mock. -func Mock(mock Interface) { - fs = mock -} - -// Restore puts back the real filesystem. -func Restore() { - fs = realFS{} -} diff --git a/fs/fs_test.go b/fs/fs_test.go deleted file mode 100644 index 002944a7..00000000 --- a/fs/fs_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package fs - -import ( - "os" - "testing" -) - -const devNullCount = 500 - -func openDevNullFiles(b *testing.B, n int) []*os.File { - var arr []*os.File - for i := 0; i < n; i++ { - fh, err := os.Open("/dev/null") - if err != nil { - b.Fatalf("Cannot open /dev/null.") - } - arr = append(arr, fh) - } - return arr - -} -func closeDevNullFiles(b *testing.B, arr []*os.File) { - for i := range arr { - err := arr[i].Close() - if err != nil { - b.Fatalf("Cannot close /dev/null.") - } - } -} - -func BenchmarkReadDirNames(b *testing.B) { - arr := openDevNullFiles(b, devNullCount) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - names, err := ReadDirNames("/proc/self/fd") - if err != nil { - b.Fatalf("ReadDirNames failed: %v", err) - } - count := len(names) - if count < devNullCount || count > devNullCount+10 { - b.Fatalf("ReadDirNames failed: count=%d", count) - } - } - b.StopTimer() - - closeDevNullFiles(b, arr) -} - -func BenchmarkReadDirCount(b *testing.B) { - arr := openDevNullFiles(b, devNullCount) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - count, err := ReadDirCount("/proc/self/fd") - if err != nil { - b.Fatalf("ReadDirCount failed: %v", err) - } - if count < devNullCount || count > devNullCount+10 { - b.Fatalf("ReadDirCount failed: count=%d", count) - } - } - b.StopTimer() - - closeDevNullFiles(b, arr) -} - -func TestReadDirNames(t *testing.T) { - names, err := ReadDirNames("/proc/self/fd") - if err != nil { - t.Fatalf("ReadDirNames failed: %v", err) - } - count, err := ReadDirCount("/proc/self/fd") - if err != nil { - t.Fatalf("ReadDirCount failed: %v", err) - } - if len(names) != count { - t.Fatalf("ReadDirNames and ReadDirCount give inconsitent results: %d != %d", len(names), count) - } - -} diff --git a/fs/readdircount_linux_amd64.go b/fs/readdircount_linux_amd64.go deleted file mode 100644 index f3f2b121..00000000 --- a/fs/readdircount_linux_amd64.go +++ /dev/null @@ -1,62 +0,0 @@ -// +build linux,amd64 - -package fs - -import ( - "fmt" - "os" - "unsafe" - - "syscall" -) - -func countDirEntries(buf []byte, n int) int { - count := 0 - buf = buf[:n] - for len(buf) > 0 { - // see man page getdents(2) for struct linux_dirent64 - reclenOffset := unsafe.Offsetof(syscall.Dirent{}.Reclen) - reclen := *(*uint16)(unsafe.Pointer(&buf[reclenOffset])) - - inoOffset := unsafe.Offsetof(syscall.Dirent{}.Ino) - ino := *(*uint64)(unsafe.Pointer(&buf[inoOffset])) - - if int(reclen) > len(buf) { - return count - } - buf = buf[reclen:] - if ino == 0 { - continue - } - count++ - } - return count -} - -// ReadDirCount is similar to ReadDirNames() and then counting with len() but -// it is optimized to avoid parsing the entries -func (realFS) ReadDirCount(dir string) (int, error) { - buf := make([]byte, 4096) - fh, err := os.Open(dir) - if err != nil { - return 0, err - } - defer fh.Close() - - openFilesCount := 0 - for { - n, err := syscall.ReadDirent(int(fh.Fd()), buf) - if err != nil { - return 0, fmt.Errorf("ReadDirent() failed: %v", err) - } - if n == 0 { - break - } - - openFilesCount += countDirEntries(buf, n) - } - - // "." and ".." don't count as files to be counted - nDotFiles := 2 - return openFilesCount - nDotFiles, err -} diff --git a/fs/readdircount_unsupported.go b/fs/readdircount_unsupported.go deleted file mode 100644 index b89ad12b..00000000 --- a/fs/readdircount_unsupported.go +++ /dev/null @@ -1,9 +0,0 @@ -// +build !linux !amd64 - -package fs - -// ReadDirCount, unoptimized version -func (realFS) ReadDirCount(path string) (int, error) { - names, err := ReadDirNames(path) - return len(names), err -} diff --git a/go.mod b/go.mod index 35d329af..a65a48d2 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,9 @@ module github.com/weaveworks/common -go 1.22 - -toolchain go1.23.2 +go 1.24 require ( github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 - github.com/davecgh/go-spew v1.1.1 github.com/felixge/httpsnoop v1.0.3 github.com/go-kit/log v0.2.1 github.com/gogo/googleapis v1.1.0 @@ -19,7 +16,6 @@ require ( github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9 github.com/opentracing/opentracing-go v1.1.0 github.com/pkg/errors v0.9.1 - github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_golang v1.15.1 github.com/prometheus/exporter-toolkit v0.8.2 github.com/rantav/go-grpc-channelz v0.0.4 @@ -41,6 +37,7 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd // indirect github.com/coreos/go-systemd/v22 v22.4.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-chi/chi/v5 v5.0.7 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect @@ -51,6 +48,7 @@ require ( github.com/mattn/go-isatty v0.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect diff --git a/httpgrpc/server/server_test.go b/httpgrpc/server/server_test.go index 7fcf780f..f34f6305 100644 --- a/httpgrpc/server/server_test.go +++ b/httpgrpc/server/server_test.go @@ -46,7 +46,8 @@ func newTestServer(handler http.Handler) (*testServer, error) { func TestBasic(t *testing.T) { server, err := newTestServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - fmt.Fprint(w, "world") + _, err := fmt.Fprint(w, "world") + require.NoError(t, err) })) require.NoError(t, err) defer server.grpcServer.GracefulStop() @@ -115,12 +116,16 @@ func TestTracePropagation(t *testing.T) { jaeger := jaegercfg.Configuration{} closer, err := jaeger.InitGlobalTracer("test") require.NoError(t, err) - defer closer.Close() + defer func() { + err := closer.Close() + require.NoError(t, err) + }() server, err := newTestServer(middleware.Tracer{}.Wrap( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { span := opentracing.SpanFromContext(r.Context()) - fmt.Fprint(w, span.BaggageItem("name")) + _, err := fmt.Fprint(w, span.BaggageItem("name")) + require.NoError(t, err) }), )) diff --git a/mflag/flag.go b/mflag/flag.go index bebfd18e..72441721 100644 --- a/mflag/flag.go +++ b/mflag/flag.go @@ -538,7 +538,7 @@ func (fs *FlagSet) PrintDefaults() { // Add a blank line between cmd description and list of options if fs.FlagCount() > 0 { - fmt.Fprintln(writer, "") + fmt.Fprintln(writer, "") //nolint:errcheck } fs.VisitAll(func(flag *Flag) { @@ -553,17 +553,17 @@ func (fs *FlagSet) PrintDefaults() { if isZeroValue(val) { format := " -%s" - fmt.Fprintf(writer, format, strings.Join(names, ", -")) + fmt.Fprintf(writer, format, strings.Join(names, ", -")) //nolint:errcheck } else { format := " -%s=%s" - fmt.Fprintf(writer, format, strings.Join(names, ", -"), val) + fmt.Fprintf(writer, format, strings.Join(names, ", -"), val) //nolint:errcheck } for _, line := range strings.Split(flag.Usage, "\n") { - fmt.Fprintln(writer, "\t", line) + fmt.Fprintln(writer, "\t", line) //nolint:errcheck } } }) - writer.Flush() + writer.Flush() //nolint:errcheck } // PrintDefaults prints to standard error the default values of all defined command-line flags. @@ -574,9 +574,9 @@ func PrintDefaults() { // defaultUsage is the default function to print a usage message. func defaultUsage(fs *FlagSet) { if fs.name == "" { - fmt.Fprintf(fs.Out(), "Usage:\n") + fmt.Fprintf(fs.Out(), "Usage:\n") //nolint:errcheck } else { - fmt.Fprintf(fs.Out(), "Usage of %s:\n", fs.name) + fmt.Fprintf(fs.Out(), "Usage of %s:\n", fs.name) //nolint:errcheck } fs.PrintDefaults() } @@ -588,14 +588,14 @@ func defaultUsage(fs *FlagSet) { // Usage prints to standard error a usage message documenting all defined command-line flags. // The function is a variable that may be changed to point to a custom function. var Usage = func() { - fmt.Fprintf(CommandLine.Out(), "Usage of %s:\n", os.Args[0]) + fmt.Fprintf(CommandLine.Out(), "Usage of %s:\n", os.Args[0]) //nolint:errcheck PrintDefaults() } // ShortUsage prints to standard error a usage message documenting the standard command layout // The function is a variable that may be changed to point to a custom function. var ShortUsage = func() { - fmt.Fprintf(CommandLine.output, "Usage of %s:\n", os.Args[0]) + fmt.Fprintf(CommandLine.output, "Usage of %s:\n", os.Args[0]) //nolint:errcheck } // FlagCount returns the number of flags that have been defined. @@ -901,8 +901,8 @@ func (fs *FlagSet) Var(value Value, names []string, usage string) { } else { msg = fmt.Sprintf("%s flag redefined: %s", fs.name, name) } - fmt.Fprintln(fs.Out(), msg) - panic(msg) // Happens only if flags are declared with identical names + fmt.Fprintln(fs.Out(), msg) //nolint:errcheck + panic(msg) // Happens only if flags are declared with identical names } if fs.formal == nil { fs.formal = make(map[string]*Flag) @@ -925,11 +925,11 @@ func Var(value Value, names []string, usage string) { // returns the error. func (fs *FlagSet) failf(format string, a ...interface{}) error { err := fmt.Errorf(format, a...) - fmt.Fprintln(fs.Out(), err) + fmt.Fprintln(fs.Out(), err) //nolint:errcheck if os.Args[0] == fs.name { - fmt.Fprintf(fs.Out(), "See '%s --help'.\n", os.Args[0]) + fmt.Fprintf(fs.Out(), "See '%s --help'.\n", os.Args[0]) //nolint:errcheck } else { - fmt.Fprintf(fs.Out(), "See '%s %s --help'.\n", os.Args[0], fs.name) + fmt.Fprintf(fs.Out(), "See '%s %s --help'.\n", os.Args[0], fs.name) //nolint:errcheck } return err } @@ -1058,9 +1058,9 @@ func (fs *FlagSet) parseOne() (bool, string, error) { } } if replacement != "" { - fmt.Fprintf(fs.Out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement) + fmt.Fprintf(fs.Out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement) //nolint:errcheck } else { - fmt.Fprintf(fs.Out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name) + fmt.Fprintf(fs.Out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name) //nolint:errcheck } } } @@ -1152,7 +1152,7 @@ func (fs *FlagSet) ReportError(str string, withHelp bool) { str += ".\nSee '" + os.Args[0] + " " + fs.Name() + " --help'" } } - fmt.Fprintf(fs.Out(), "%s: %s.\n", os.Args[0], str) + fmt.Fprintf(fs.Out(), "%s: %s.\n", os.Args[0], str) //nolint:errcheck } // Parsed reports whether fs.Parse has been called. @@ -1241,7 +1241,7 @@ func Merge(dest *FlagSet, flagsets ...*FlagSet) error { } else { err = fmt.Errorf("%s flag redefined: %s", fset.name, k) } - fmt.Fprintln(fset.Out(), err.Error()) + fmt.Fprintln(fset.Out(), err.Error()) //nolint:errcheck // Happens only if flags are declared with identical names switch dest.errorHandling { case ContinueOnError: diff --git a/middleware/logging.go b/middleware/logging.go index fcb8453f..ba6455e8 100644 --- a/middleware/logging.go +++ b/middleware/logging.go @@ -141,6 +141,6 @@ func dumpRequest(req *http.Request, httpHeadersToExclude map[string]bool) ([]byt return nil, err } - ret := bytes.Replace(b.Bytes(), []byte("\r\n"), []byte("; "), -1) + ret := bytes.ReplaceAll(b.Bytes(), []byte("\r\n"), []byte("; ")) return ret, nil } diff --git a/network/interface.go b/network/interface.go deleted file mode 100644 index 9a94b9ac..00000000 --- a/network/interface.go +++ /dev/null @@ -1,33 +0,0 @@ -package network - -import ( - "fmt" - "net" -) - -// GetFirstAddressOf returns the first IPv4 address of the supplied interface name. -func GetFirstAddressOf(name string) (string, error) { - inf, err := net.InterfaceByName(name) - if err != nil { - return "", err - } - - addrs, err := inf.Addrs() - if err != nil { - return "", err - } - if len(addrs) <= 0 { - return "", fmt.Errorf("No address found for %s", name) - } - - for _, addr := range addrs { - switch v := addr.(type) { - case *net.IPNet: - if ip := v.IP.To4(); ip != nil { - return v.IP.String(), nil - } - } - } - - return "", fmt.Errorf("No address found for %s", name) -} diff --git a/test/diff.go b/test/diff.go deleted file mode 100644 index 5678972b..00000000 --- a/test/diff.go +++ /dev/null @@ -1,24 +0,0 @@ -package test - -import ( - "github.com/davecgh/go-spew/spew" - "github.com/pmezard/go-difflib/difflib" -) - -// Diff diffs two arbitrary data structures, giving human-readable output. -func Diff(want, have interface{}) string { - config := spew.NewDefaultConfig() - // Set ContinueOnMethod to true if you cannot see a difference and - // want to look beyond the String() method - config.ContinueOnMethod = false - config.SortKeys = true - config.SpewKeys = true - text, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ - A: difflib.SplitLines(config.Sdump(want)), - B: difflib.SplitLines(config.Sdump(have)), - FromFile: "want", - ToFile: "have", - Context: 3, - }) - return "\n" + text -} diff --git a/test/exec/exec.go b/test/exec/exec.go deleted file mode 100644 index 03a5de06..00000000 --- a/test/exec/exec.go +++ /dev/null @@ -1,62 +0,0 @@ -package exec - -import ( - "bytes" - "io" - - "github.com/weaveworks/common/exec" -) - -type mockCmd struct { - io.ReadCloser -} - -// NewMockCmdString creates a new mock Cmd which has s on its stdout pipe -func NewMockCmdString(s string) exec.Cmd { - return &mockCmd{ - ReadCloser: struct { - io.Reader - io.Closer - }{ - bytes.NewBufferString(s), - io.NopCloser(nil), - }, - } -} - -// NewMockCmd creates a new mock Cmd with rc as its stdout pipe -func NewMockCmd(rc io.ReadCloser) exec.Cmd { - return &mockCmd{ - ReadCloser: rc, - } -} - -func (c *mockCmd) Start() error { - return nil -} - -func (c *mockCmd) Wait() error { - return nil -} - -func (c *mockCmd) StdoutPipe() (io.ReadCloser, error) { - return c.ReadCloser, nil -} - -func (c *mockCmd) StderrPipe() (io.ReadCloser, error) { - return io.NopCloser(bytes.NewReader(nil)), nil -} - -func (c *mockCmd) Kill() error { - return nil -} - -func (c *mockCmd) Output() ([]byte, error) { - return io.ReadAll(c.ReadCloser) -} - -func (c *mockCmd) Run() error { - return nil -} - -func (c *mockCmd) SetEnv([]string) {} diff --git a/test/fs/fs.go b/test/fs/fs.go deleted file mode 100644 index afe3350c..00000000 --- a/test/fs/fs.go +++ /dev/null @@ -1,305 +0,0 @@ -package fs - -import ( - "bytes" - "fmt" - "io" - "os" - "strings" - "syscall" - "time" - - "github.com/weaveworks/common/fs" -) - -type mockInode struct{} - -type dir struct { - mockInode - name string - entries map[string]Entry -} - -// File is a mock file -type File struct { - mockInode - FName string - FContents string - FReader io.Reader - FWriter io.Writer - FCloser io.Closer - FStat syscall.Stat_t -} - -// Entry is an entry in the mock filesystem -type Entry interface { - os.DirEntry - fs.Interface - Add(path string, e Entry) error - Remove(path string) error -} - -// Dir creates a new directory with the given entries. -func Dir(name string, entries ...Entry) Entry { - result := dir{ - name: name, - entries: map[string]Entry{}, - } - - for _, entry := range entries { - result.entries[entry.Name()] = entry - } - - return result -} - -func split(path string) (string, string) { - if !strings.HasPrefix(path, "/") { - panic(path) - } - - comps := strings.SplitN(path, "/", 3) - if len(comps) == 2 { - return comps[1], "/" - } - - return comps[1], "/" + comps[2] -} - -func (mockInode) Size() int64 { return 0 } -func (mockInode) Mode() os.FileMode { return 0 } -func (mockInode) ModTime() time.Time { return time.Now() } -func (mockInode) Sys() interface{} { return nil } - -func (p dir) Name() string { return p.name } -func (p dir) IsDir() bool { return true } - -func (p dir) ReadDir(path string) ([]os.DirEntry, error) { - if path == "/" { - result := []os.DirEntry{} - for _, v := range p.entries { - result = append(result, v) - } - return result, nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return nil, fmt.Errorf("Not found: %s", path) - } - - return fs.ReadDir(tail) -} - -func (p dir) Type() os.FileMode { - //TODO implement me - panic("implement me") -} - -func (p dir) Info() (os.FileInfo, error) { - //TODO implement me - panic("implement me") -} - -func (p dir) ReadDirNames(path string) ([]string, error) { - if path == "/" { - result := []string{} - for _, v := range p.entries { - result = append(result, v.Name()) - } - return result, nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return nil, fmt.Errorf("Not found: %s", path) - } - - return fs.ReadDirNames(tail) -} - -func (p dir) ReadDirCount(path string) (int, error) { - names, err := p.ReadDirNames(path) - return len(names), err -} - -func (p dir) ReadFile(path string) ([]byte, error) { - if path == "/" { - return nil, fmt.Errorf("I'm a directory") - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return nil, fmt.Errorf("Not found: %s", path) - } - - return fs.ReadFile(tail) -} - -func (p dir) Lstat(path string, stat *syscall.Stat_t) error { - if path == "/" { - *stat = syscall.Stat_t{Mode: syscall.S_IFDIR} - return nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return fmt.Errorf("Not found: %s", path) - } - - return fs.Lstat(tail, stat) -} - -func (p dir) Stat(path string, stat *syscall.Stat_t) error { - if path == "/" { - *stat = syscall.Stat_t{Mode: syscall.S_IFDIR} - return nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return fmt.Errorf("Not found: %s", path) - } - - return fs.Stat(tail, stat) -} - -func (p dir) Open(path string) (io.ReadWriteCloser, error) { - if path == "/" { - return nil, fmt.Errorf("I'm a directory") - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return nil, fmt.Errorf("Not found: %s", path) - } - - return fs.Open(tail) -} - -func (p dir) Add(path string, e Entry) error { - if path == "/" { - p.entries[e.Name()] = e - return nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - fs = Dir(head) - p.entries[head] = fs - } - - return fs.Add(tail, e) -} - -func (p dir) Remove(path string) error { - if _, ok := p.entries[strings.TrimPrefix(path, "/")]; ok { - delete(p.entries, strings.TrimPrefix(path, "/")) - return nil - } - - head, tail := split(path) - fs, ok := p.entries[head] - if !ok { - return nil - } - return fs.Remove(tail) -} - -// Name implements os.FileInfo -func (p File) Name() string { return p.FName } - -// IsDir implements os.FileInfo -func (p File) IsDir() bool { return false } - -// ReadDir implements FS -func (p File) ReadDir(path string) ([]os.FileInfo, error) { - return nil, fmt.Errorf("I'm a file") -} - -// ReadDirNames implements FS -func (p File) ReadDirNames(path string) ([]string, error) { - return nil, fmt.Errorf("I'm a file") -} - -// ReadDirCount implements FS -func (p File) ReadDirCount(path string) (int, error) { - return 0, fmt.Errorf("I'm a file") -} - -// ReadFile implements FS -func (p File) ReadFile(path string) ([]byte, error) { - if path != "/" { - return nil, fmt.Errorf("I'm a file") - } - if p.FReader != nil { - return io.ReadAll(p.FReader) - } - return []byte(p.FContents), nil -} - -// Lstat implements FS -func (p File) Lstat(path string, stat *syscall.Stat_t) error { - if path != "/" { - return fmt.Errorf("I'm a file") - } - *stat = p.FStat - return nil -} - -// Stat implements FS -func (p File) Stat(path string, stat *syscall.Stat_t) error { - if path != "/" { - return fmt.Errorf("I'm a file") - } - *stat = p.FStat - return nil -} - -// Open implements FS -func (p File) Open(path string) (io.ReadWriteCloser, error) { - if path != "/" { - return nil, fmt.Errorf("I'm a file") - } - buf := bytes.NewBuffer([]byte(p.FContents)) - s := struct { - io.Reader - io.Writer - io.Closer - }{ - buf, buf, io.NopCloser(nil), - } - if p.FReader != nil { - s.Reader = p.FReader - } - if p.FWriter != nil { - s.Writer = p.FWriter - } - if p.FCloser != nil { - s.Closer = p.FCloser - } - return s, nil -} - -// Add adds a new node to the fs -func (p File) Add(path string, e Entry) error { - if path != "/" { - return fmt.Errorf("I'm a file") - } - return nil -} - -// Remove removes a node from the fs -func (p File) Remove(path string) error { - if path != "/" { - return fmt.Errorf("I'm a file") - } - return nil -} diff --git a/tools/runner/runner.go b/tools/runner/runner.go index a714ed07..ce4eae9f 100644 --- a/tools/runner/runner.go +++ b/tools/runner/runner.go @@ -142,7 +142,7 @@ func updateScheduler(test string, duration float64) { if resp, err := http.DefaultClient.Do(req); err != nil { fmt.Printf("Error updating scheduler: %v\n", err) } else { - resp.Body.Close() + resp.Body.Close() //nolint:errcheck } }