From eba15772ec4489f8572cd28fdf98096aabbd9ec7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 11 Oct 2024 11:33:44 +0000 Subject: [PATCH] chore: build with Go 1.23 - bump deps / requirements - remove internal FailFS implementation and use the vendor-provided one - clean up an overly-complicated unit test Fixes: Issue #236 --- .github/workflows/go.yml | 2 +- examples/go-client/go.mod | 12 +- examples/go-client/go.sum | 16 +- go.mod | 4 +- go.sum | 4 +- internal/git/git_public_test.go | 17 +- internal/mocks/vfs/failfs.go | 485 ------------------------ internal/mocks/vfs/failfs_test.go | 67 ---- internal/repository/copy_public_test.go | 168 ++++---- 9 files changed, 118 insertions(+), 657 deletions(-) delete mode 100644 internal/mocks/vfs/failfs.go delete mode 100644 internal/mocks/vfs/failfs_test.go diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c701f72..02acf8c 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -15,7 +15,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23' - name: Install Task uses: arduino/setup-task@v2 with: diff --git a/examples/go-client/go.mod b/examples/go-client/go.mod index 4101ff8..07d6997 100644 --- a/examples/go-client/go.mod +++ b/examples/go-client/go.mod @@ -1,26 +1,26 @@ module example.com/client -go 1.22 +go 1.23 -toolchain go1.22.2 +toolchain go1.23.3 replace github.com/retr0h/gilt/v2 => ../../../gilt/ require ( - github.com/lmittmann/tint v1.0.4 + github.com/lmittmann/tint v1.0.5 github.com/retr0h/gilt/v2 v2.2.0 ) require ( - github.com/avfs/avfs v0.33.0 // indirect + github.com/avfs/avfs v0.34.0 // indirect github.com/danjacques/gofslock v0.0.0-20230728142113-ae8f59f9e88b // indirect github.com/gabriel-vasile/mimetype v1.4.3 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.22.0 // indirect + github.com/go-playground/validator/v10 v10.22.1 // indirect github.com/leodido/go-urn v1.4.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.21.0 // indirect + golang.org/x/sys v0.26.0 // indirect golang.org/x/text v0.14.0 // indirect ) diff --git a/examples/go-client/go.sum b/examples/go-client/go.sum index 81e8f46..3e386dd 100644 --- a/examples/go-client/go.sum +++ b/examples/go-client/go.sum @@ -1,5 +1,5 @@ -github.com/avfs/avfs v0.33.0 h1:5WQXbUbr6VS7aani39ZN2Vrd/s3wLnyih1Sc4ExWTxs= -github.com/avfs/avfs v0.33.0/go.mod h1:Q59flcFRYe9KYkNMfrLUJney3yeKGQpcWRyxsDBW7vI= +github.com/avfs/avfs v0.34.0 h1:1smP9udOqkYM0PyTb44vZZwzrrMaNQOxNL18kZ7f5L4= +github.com/avfs/avfs v0.34.0/go.mod h1:LnzrUO5acMU5NCkohHcUN15YrnkxiJ/lRLQOZSp39ow= github.com/danjacques/gofslock v0.0.0-20230728142113-ae8f59f9e88b h1:BBkZ6LZYtzMQ2Oo5LkovMmUp0gxAD+AnXzfknZlFTBo= github.com/danjacques/gofslock v0.0.0-20230728142113-ae8f59f9e88b/go.mod h1:9LABMmUSkKzt6FVQNEWdUTM0bz8Bt8MPyEcuZe0Sr8c= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -12,14 +12,14 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= -github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-playground/validator/v10 v10.22.1 h1:40JcKH+bBNGFczGuoBYgX4I6m/i27HYW8P9FDk5PbgA= +github.com/go-playground/validator/v10 v10.22.1/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= -github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/lmittmann/tint v1.0.5 h1:NQclAutOfYsqs2F1Lenue6OoWCajs5wJcP3DfWVpePw= +github.com/lmittmann/tint v1.0.5/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= @@ -29,8 +29,8 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/go.mod b/go.mod index afd8866..98e8447 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module github.com/retr0h/gilt/v2 -go 1.22 +go 1.23 require ( - github.com/avfs/avfs v0.33.0 + github.com/avfs/avfs v0.34.0 github.com/caarlos0/go-version v0.1.1 github.com/danjacques/gofslock v0.0.0-20230728142113-ae8f59f9e88b github.com/go-playground/validator/v10 v10.22.1 diff --git a/go.sum b/go.sum index d4354fa..af8f486 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/avfs/avfs v0.33.0 h1:5WQXbUbr6VS7aani39ZN2Vrd/s3wLnyih1Sc4ExWTxs= -github.com/avfs/avfs v0.33.0/go.mod h1:Q59flcFRYe9KYkNMfrLUJney3yeKGQpcWRyxsDBW7vI= +github.com/avfs/avfs v0.34.0 h1:1smP9udOqkYM0PyTb44vZZwzrrMaNQOxNL18kZ7f5L4= +github.com/avfs/avfs v0.34.0/go.mod h1:LnzrUO5acMU5NCkohHcUN15YrnkxiJ/lRLQOZSp39ow= github.com/caarlos0/go-version v0.1.1 h1:1bikKHkGGVIIxqCmufhSSs3hpBScgHGacrvsi8FuIfc= github.com/caarlos0/go-version v0.1.1/go.mod h1:Ze5Qx4TsBBi5FyrSKVg1Ibc44KGV/llAaKGp86oTwZ0= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= diff --git a/internal/git/git_public_test.go b/internal/git/git_public_test.go index 5c3958c..1d0186a 100644 --- a/internal/git/git_public_test.go +++ b/internal/git/git_public_test.go @@ -27,6 +27,7 @@ import ( "testing" "github.com/avfs/avfs" + "github.com/avfs/avfs/vfs/failfs" "github.com/avfs/avfs/vfs/memfs" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" @@ -35,7 +36,6 @@ import ( "github.com/retr0h/gilt/v2/internal" "github.com/retr0h/gilt/v2/internal/git" "github.com/retr0h/gilt/v2/internal/mocks/exec" - failfs "github.com/retr0h/gilt/v2/internal/mocks/vfs" ) type GitManagerPublicTestSuite struct { @@ -127,12 +127,15 @@ func (suite *GitManagerPublicTestSuite) TestWorktreeError() { func (suite *GitManagerPublicTestSuite) TestWorktreeErrorWhenAbsErrors() { // Make Abs() calls fail - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "Abs": func(string) (string, error) { return "", errors.New("FailFS!") }, - }, - ) + vfs := failfs.New(suite.appFs) + _ = vfs.SetFailFunc(func(_ avfs.VFSBase, fn avfs.FnVFS, _ *failfs.FailParam) error { + if fn == avfs.FnAbs { + return errors.New("FailFS!") + } + return nil + }) + suite.appFs = vfs + gm := suite.NewTestGitManager() err := gm.Worktree(suite.cloneDir, suite.gitVersion, suite.dstDir) diff --git a/internal/mocks/vfs/failfs.go b/internal/mocks/vfs/failfs.go deleted file mode 100644 index b806c59..0000000 --- a/internal/mocks/vfs/failfs.go +++ /dev/null @@ -1,485 +0,0 @@ -// Copyright (c) 2023 Nicolas Simonds - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package failfs - -import ( - "fmt" - "io/fs" - "reflect" - "time" - - "github.com/avfs/avfs" - "github.com/avfs/avfs/idm/dummyidm" -) - -type FailFS struct { - baseFS avfs.VFS - errOpNotPermitted error - errPermDenied error - features avfs.Features - failFn map[string]interface{} - avfs.Utils[*FailFS] -} - -type FailFile struct { - baseFile avfs.File - vfs *FailFS -} - -func New(baseFS avfs.VFS, failFn map[string]interface{}) *FailFS { - return &FailFS{ - baseFS: baseFS, - errOpNotPermitted: avfs.ErrOpNotPermitted, - errPermDenied: avfs.ErrPermDenied, - features: baseFS.Features() &^ avfs.FeatIdentityMgr, - failFn: failFn, - } -} - -// callFailFn calls the provided failure function with the given arguments. -// It panics if the function signature does not match the provided arguments. -// The caller is 100% responsible for making sure the function signatures match -func (vfs *FailFS) callFailFn(fn interface{}, args ...interface{}) []reflect.Value { - failFnValue := reflect.ValueOf(fn) - if failFnValue.Kind() != reflect.Func { - panic(fmt.Sprintf("failFn is not a function: %v", fn)) - } - - in := make([]reflect.Value, len(args)) - for i, arg := range args { - in[i] = reflect.ValueOf(arg) - } - - results := failFnValue.Call(in) - return results -} - -// FailFS ops - -func (vfs *FailFS) Features() avfs.Features { - return vfs.features -} - -func (vfs *FailFS) HasFeature(feature avfs.Features) bool { - return vfs.features&feature == feature -} - -func (vfs *FailFS) Name() string { - return vfs.baseFS.Name() -} - -func (vfs *FailFS) OSType() avfs.OSType { - return vfs.baseFS.OSType() -} - -func (*FailFS) Type() string { - return "FailFS" -} - -func (vfs *FailFS) CreateSystemDirs(basePath string) error { - return vfs.baseFS.CreateSystemDirs(basePath) -} - -func (vfs *FailFS) CreateHomeDir(u avfs.UserReader) (string, error) { - return vfs.baseFS.CreateHomeDir(u) -} - -func (vfs *FailFS) HomeDirUser(u avfs.UserReader) string { - return vfs.baseFS.HomeDirUser(u) -} - -func (vfs *FailFS) SystemDirs(basePath string) []avfs.DirInfo { - return vfs.baseFS.SystemDirs(basePath) -} - -func (vfs *FailFS) Abs(path string) (string, error) { - if failFn, ok := vfs.failFn["Abs"]; ok { - results := vfs.callFailFn(failFn, path) - var abs string - var err error - abs, _ = results[0].Interface().(string) - if !results[1].IsNil() { - err, _ = results[1].Interface().(error) - } - return abs, err - } - return vfs.baseFS.Abs(path) -} - -func (vfs *FailFS) Base(path string) string { - return vfs.baseFS.Base(path) -} - -func (vfs *FailFS) Chdir(dir string) error { - return vfs.baseFS.Chdir(dir) -} - -func (vfs *FailFS) Chmod(name string, mode fs.FileMode) error { - if failFn, ok := vfs.failFn["Chmod"]; ok { - results := vfs.callFailFn(failFn, name, mode) - var err error - if !results[0].IsNil() { - err, _ = results[0].Interface().(error) - } - return err - } - return vfs.baseFS.Chmod(name, mode) -} - -func (vfs *FailFS) Chown(name string, uid, gid int) error { - return vfs.baseFS.Chown(name, uid, gid) -} - -func (vfs *FailFS) Chtimes(name string, atime, mtime time.Time) error { - return vfs.baseFS.Chtimes(name, atime, mtime) -} - -func (vfs *FailFS) Clean(path string) string { - return vfs.baseFS.Clean(path) -} - -func (vfs *FailFS) Create(name string) (avfs.File, error) { - return vfs.Utils.Create(vfs, name) -} - -func (vfs *FailFS) CreateTemp(dir, pattern string) (avfs.File, error) { - return vfs.baseFS.CreateTemp(dir, pattern) -} - -func (vfs *FailFS) Dir(path string) string { - return vfs.baseFS.Dir(path) -} - -func (vfs *FailFS) EvalSymlinks(path string) (string, error) { - return vfs.baseFS.EvalSymlinks(path) -} - -func (vfs *FailFS) FromSlash(path string) string { - return vfs.baseFS.FromSlash(path) -} - -func (vfs *FailFS) Getwd() (dir string, err error) { - return vfs.baseFS.Getwd() -} - -func (vfs *FailFS) Glob(pattern string) (matches []string, err error) { - return vfs.baseFS.Glob(pattern) -} - -func (vfs *FailFS) Idm() avfs.IdentityMgr { - return dummyidm.NotImplementedIdm -} - -func (vfs *FailFS) IsAbs(path string) bool { - return vfs.baseFS.IsAbs(path) -} - -func (vfs *FailFS) IsPathSeparator(c uint8) bool { - return vfs.baseFS.IsPathSeparator(c) -} - -func (vfs *FailFS) Join(elem ...string) string { - return vfs.baseFS.Join(elem...) -} - -func (vfs *FailFS) Lchown(name string, uid, gid int) error { - return vfs.baseFS.Lchown(name, uid, gid) -} - -func (vfs *FailFS) Link(oldname, newname string) error { - return vfs.baseFS.Link(oldname, newname) -} - -func (vfs *FailFS) Lstat(name string) (fs.FileInfo, error) { - return vfs.baseFS.Lstat(name) -} - -func (vfs *FailFS) Match(pattern, name string) (matched bool, err error) { - return vfs.baseFS.Match(pattern, name) -} - -func (vfs *FailFS) Mkdir(name string, perm fs.FileMode) error { - return vfs.baseFS.Mkdir(name, perm) -} - -func (vfs *FailFS) MkdirAll(path string, perm fs.FileMode) error { - if failFn, ok := vfs.failFn["MkdirAll"]; ok { - results := vfs.callFailFn(failFn, path, perm) - var err error - if !results[0].IsNil() { - err, _ = results[0].Interface().(error) - } - return err - } - return vfs.baseFS.MkdirAll(path, perm) -} - -func (vfs *FailFS) MkdirTemp(dir, prefix string) (name string, err error) { - return vfs.baseFS.MkdirTemp(dir, prefix) -} - -func (vfs *FailFS) Open(name string) (avfs.File, error) { - if failFn, ok := vfs.failFn["Open"]; ok { - results := vfs.callFailFn(failFn, name) - var file avfs.File - var err error - if !results[0].IsNil() { - file, _ = results[0].Interface().(avfs.File) - } - if !results[1].IsNil() { - err, _ = results[1].Interface().(error) - } - return file, err - } - return vfs.Utils.Open(vfs, name) -} - -func (vfs *FailFS) PathSeparator() uint8 { - return vfs.baseFS.PathSeparator() -} - -func (vfs *FailFS) ReadDir(name string) ([]fs.DirEntry, error) { - if failFn, ok := vfs.failFn["ReadDir"]; ok { - results := vfs.callFailFn(failFn, name) - var entries []fs.DirEntry - var err error - if !results[0].IsNil() { - entries, _ = results[0].Interface().([]fs.DirEntry) - } - if !results[1].IsNil() { - err, _ = results[1].Interface().(error) - } - return entries, err - } - return vfs.baseFS.ReadDir(name) -} - -func (vfs *FailFS) ReadFile(filename string) ([]byte, error) { - return vfs.baseFS.ReadFile(filename) -} - -func (vfs *FailFS) Readlink(name string) (string, error) { - return vfs.baseFS.Readlink(name) -} - -func (vfs *FailFS) Rel(basepath, targpath string) (string, error) { - return vfs.baseFS.Rel(basepath, targpath) -} - -func (vfs *FailFS) Remove(name string) error { - return vfs.baseFS.Remove(name) -} - -func (vfs *FailFS) RemoveAll(path string) error { - return vfs.baseFS.RemoveAll(path) -} - -func (vfs *FailFS) Rename(oldname, newname string) error { - return vfs.baseFS.Rename(oldname, newname) -} - -func (vfs *FailFS) SameFile(fi1, fi2 fs.FileInfo) bool { - return vfs.baseFS.SameFile(fi1, fi2) -} - -func (vfs *FailFS) SetUMask(mask fs.FileMode) { - vfs.baseFS.SetUMask(mask) -} - -func (vfs *FailFS) SetUser(name string) (avfs.UserReader, error) { - return vfs.baseFS.SetUser(name) -} - -func (vfs *FailFS) Split(path string) (dir, file string) { - return vfs.baseFS.Split(path) -} - -func (vfs *FailFS) SplitAbs(path string) (dir, file string) { - return vfs.baseFS.SplitAbs(path) -} - -func (vfs *FailFS) Stat(name string) (fs.FileInfo, error) { - if failFn, ok := vfs.failFn["Stat"]; ok { - results := vfs.callFailFn(failFn, name) - var fileInfo fs.FileInfo - var err error - if !results[0].IsNil() { - fileInfo, _ = results[0].Interface().(fs.FileInfo) - } - if !results[1].IsNil() { - err, _ = results[1].Interface().(error) - } - return fileInfo, err - } - return vfs.baseFS.Stat(name) -} - -func (vfs *FailFS) Sub(dir string) (avfs.VFS, error) { - return vfs.baseFS.Sub(dir) -} - -func (vfs *FailFS) Symlink(oldname, newname string) error { - return vfs.baseFS.Symlink(oldname, newname) -} - -func (vfs *FailFS) TempDir() string { - return vfs.baseFS.TempDir() -} - -func (vfs *FailFS) ToSlash(path string) string { - return vfs.baseFS.ToSlash(path) -} - -func (vfs *FailFS) ToSysStat(info fs.FileInfo) avfs.SysStater { - return vfs.baseFS.ToSysStat(info) -} - -func (vfs *FailFS) Truncate(name string, size int64) error { - return vfs.baseFS.Truncate(name, size) -} - -func (vfs *FailFS) UMask() fs.FileMode { - return vfs.baseFS.UMask() -} - -func (vfs *FailFS) User() avfs.UserReader { - return vfs.baseFS.User() -} - -func (vfs *FailFS) WalkDir(root string, fn fs.WalkDirFunc) error { - return vfs.baseFS.WalkDir(root, fn) -} - -func (vfs *FailFS) WriteFile(filename string, data []byte, perm fs.FileMode) error { - return vfs.baseFS.WriteFile(filename, data, perm) -} - -// FailFile ops - -func (vfs *FailFS) OpenFile(name string, flag int, perm fs.FileMode) (avfs.File, error) { - fBase, err := vfs.baseFS.OpenFile(name, flag, perm) - if fBase == nil || reflect.ValueOf(fBase).IsNil() { - return (*FailFile)(nil), err - } - f := &FailFile{baseFile: fBase, vfs: vfs} - return f, err -} - -func (f *FailFile) Chdir() error { - return f.baseFile.Chdir() -} - -func (f *FailFile) Chmod(mode fs.FileMode) error { - if failFn, ok := f.vfs.failFn["file.Chmod"]; ok { - results := f.vfs.callFailFn(failFn, mode) - var err error - if !results[0].IsNil() { - err, _ = results[0].Interface().(error) - } - return err - } - return f.baseFile.Chmod(mode) -} - -func (f *FailFile) Chown(uid, gid int) error { - return f.baseFile.Chown(uid, gid) -} - -func (f *FailFile) Close() error { - return f.baseFile.Close() -} - -func (f *FailFile) Fd() uintptr { - return f.baseFile.Fd() -} - -func (f *FailFile) Name() string { - return f.baseFile.Name() -} - -func (f *FailFile) Read(b []byte) (int, error) { - if failFn, ok := f.vfs.failFn["file.Read"]; ok { - results := f.vfs.callFailFn(failFn, b) - var n int - var err error - n, _ = results[0].Interface().(int) - if !results[1].IsNil() { - err, _ = results[1].Interface().(error) - } - return n, err - } - return f.baseFile.Read(b) -} - -func (f *FailFile) ReadAt(b []byte, off int64) (n int, err error) { - return f.baseFile.ReadAt(b, off) -} - -func (f *FailFile) ReadDir(n int) ([]fs.DirEntry, error) { - return f.baseFile.ReadDir(n) -} - -func (f *FailFile) Readdirnames(n int) (names []string, err error) { - return f.baseFile.Readdirnames(n) -} - -func (f *FailFile) Seek(offset int64, whence int) (ret int64, err error) { - return f.baseFile.Seek(offset, whence) -} - -func (f *FailFile) Stat() (fs.FileInfo, error) { - if failFn, ok := f.vfs.failFn["file.Stat"]; ok { - results := f.vfs.callFailFn(failFn) - var fileInfo fs.FileInfo - var err error - if !results[0].IsNil() { - fileInfo, _ = results[0].Interface().(fs.FileInfo) - } - if !results[1].IsNil() { - err, _ = results[1].Interface().(error) - } - return fileInfo, err - } - return f.baseFile.Stat() -} - -func (f *FailFile) Sync() error { - if failFn, ok := f.vfs.failFn["file.Sync"]; ok { - results := f.vfs.callFailFn(failFn) - var err error - if !results[0].IsNil() { - err, _ = results[0].Interface().(error) - } - return err - } - return f.baseFile.Sync() -} - -func (f *FailFile) Truncate(size int64) error { - return f.baseFile.Truncate(size) -} - -func (f *FailFile) Write(b []byte) (n int, err error) { - return f.baseFile.Write(b) -} - -func (f *FailFile) WriteAt(b []byte, off int64) (n int, err error) { - return f.baseFile.WriteAt(b, off) -} - -func (f *FailFile) WriteString(s string) (n int, err error) { - return f.Write([]byte(s)) -} diff --git a/internal/mocks/vfs/failfs_test.go b/internal/mocks/vfs/failfs_test.go deleted file mode 100644 index cde54f7..0000000 --- a/internal/mocks/vfs/failfs_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2023 Nicolas Simonds - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -package failfs_test - -import ( - "testing" - - "github.com/avfs/avfs" - "github.com/avfs/avfs/test" - "github.com/avfs/avfs/vfs/memfs" - failfs "github.com/retr0h/gilt/v2/internal/mocks/vfs" -) - -var ( - // Tests that failfs.failfs struct implements avfs.VFS interface. - _ avfs.VFS = &failfs.FailFS{} - - // Tests that failfs.FailFile struct implements avfs.File interface. - _ avfs.File = &failfs.FailFile{} -) - -func initTest(t *testing.T) *test.Suite { - vfsSetup := memfs.New() - vfs := failfs.New(vfsSetup, nil) - - ts := test.NewSuiteFS(t, vfsSetup, vfs) - - return ts -} - -func TestFailFS(t *testing.T) { - ts := initTest(t) - ts.TestVFSAll(t) -} - -func TestFailFSConfig(t *testing.T) { - vfsWrite := memfs.New() - vfs := failfs.New(vfsWrite, nil) - - wantFeatures := vfs.Features() &^ avfs.FeatIdentityMgr - if vfs.Features() != wantFeatures { - t.Errorf("Features : want Features to be %s, got %s", wantFeatures, vfs.Features()) - } - - name := vfs.Name() - if name != "" { - t.Errorf("Name : want name to be empty, got %v", name) - } - - osType := vfs.OSType() - if osType != vfsWrite.OSType() { - t.Errorf("OSType : want os type to be %v, got %v", vfsWrite.OSType(), osType) - } -} diff --git a/internal/repository/copy_public_test.go b/internal/repository/copy_public_test.go index 0449a6a..343b14f 100644 --- a/internal/repository/copy_public_test.go +++ b/internal/repository/copy_public_test.go @@ -28,12 +28,12 @@ import ( "testing" "github.com/avfs/avfs" + "github.com/avfs/avfs/vfs/failfs" "github.com/avfs/avfs/vfs/memfs" "github.com/avfs/avfs/vfs/rofs" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - failfs "github.com/retr0h/gilt/v2/internal/mocks/vfs" "github.com/retr0h/gilt/v2/internal/repository" ) @@ -103,12 +103,15 @@ func (suite *CopyPublicTestSuite) TestCopyFileErrorStat() { } createFileSpecs(specs) // Make Stat() calls fail - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "file.Stat": func() (fs.FileInfo, error) { return nil, errors.New("FailFS!") }, - }, - ) + vfs := failfs.New(suite.appFs) + _ = vfs.SetFailFunc(func(_ avfs.VFSBase, fn avfs.FnVFS, _ *failfs.FailParam) error { + if fn == avfs.FnFileStat { + return errors.New("FailFS!") + } + return nil + }) + suite.appFs = vfs + assertFile := suite.appFs.Join(suite.dstDir, "1.txt") cm := suite.NewTestCopyManager() err := cm.CopyFile(specs[0].srcFile, assertFile) @@ -144,12 +147,15 @@ func (suite *CopyPublicTestSuite) TestCopyFileErrorSettingDestfilePerms() { } createFileSpecs(specs) // Make Chmod() calls fail - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "file.Chmod": func(fs.FileMode) error { return errors.New("FailFS!") }, - }, - ) + vfs := failfs.New(suite.appFs) + _ = vfs.SetFailFunc(func(_ avfs.VFSBase, fn avfs.FnVFS, _ *failfs.FailParam) error { + if fn == avfs.FnFileChmod { + return errors.New("FailFS!") + } + return nil + }) + suite.appFs = vfs + assertFile := suite.appFs.Join(suite.dstDir, "1.txt") cm := suite.NewTestCopyManager() err := cm.CopyFile(specs[0].srcFile, assertFile) @@ -159,12 +165,15 @@ func (suite *CopyPublicTestSuite) TestCopyFileErrorSettingDestfilePerms() { func (suite *CopyPublicTestSuite) TestCopyFileErrorCopy() { // Make the file unreadable - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "file.Read": func([]byte) (int, error) { return 0, errors.New("FailFS!") }, - }, - ) + vfs := failfs.New(suite.appFs) + _ = vfs.SetFailFunc(func(_ avfs.VFSBase, fn avfs.FnVFS, _ *failfs.FailParam) error { + if fn == avfs.FnFileRead { + return errors.New("FailFS!") + } + return nil + }) + suite.appFs = vfs + cm := suite.NewTestCopyManager() specs := []FileSpec{ { @@ -190,12 +199,15 @@ func (suite *CopyPublicTestSuite) TestCopyFileErrorSync() { } createFileSpecs(specs) // Make Sync() calls fail - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "file.Sync": func() error { return errors.New("FailFS!") }, - }, - ) + vfs := failfs.New(suite.appFs) + _ = vfs.SetFailFunc(func(_ avfs.VFSBase, fn avfs.FnVFS, _ *failfs.FailParam) error { + if fn == avfs.FnFileSync { + return errors.New("FailFS!") + } + return nil + }) + suite.appFs = vfs + assertFile := suite.appFs.Join(suite.dstDir, "1.txt") cm := suite.NewTestCopyManager() err := cm.CopyFile(specs[0].srcFile, assertFile) @@ -213,17 +225,18 @@ func (suite *CopyPublicTestSuite) TestCopyFileErrorFinalizingDestfilePerms() { } createFileSpecs(specs) // Make the second Chmod() call fail - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "file.Chmod": func(mode fs.FileMode) error { - if mode == 0o600 { - return nil - } - return errors.New("FailFS!") - }, - }, - ) + vfs := failfs.New(suite.appFs) + _ = vfs.SetFailFunc(func(_ avfs.VFSBase, fn avfs.FnVFS, fp *failfs.FailParam) error { + if fn == avfs.FnFileChmod { + if fp.Perm == 0o600 { + return nil + } + return errors.New("FailFS!") + } + return nil + }) + suite.appFs = vfs + assertFile := suite.appFs.Join(suite.dstDir, "1.txt") cm := suite.NewTestCopyManager() err := cm.CopyFile(specs[0].srcFile, assertFile) @@ -358,12 +371,15 @@ func (suite *CopyPublicTestSuite) TestCopyDirReturnsErrorCreatingDestDir() { }, } createFileSpecs(specs) - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "MkdirAll": func(string, fs.FileMode) error { return errors.New("FailFS!") }, - }, - ) + vfs := failfs.New(suite.appFs) + _ = vfs.SetFailFunc(func(_ avfs.VFSBase, fn avfs.FnVFS, _ *failfs.FailParam) error { + if fn == avfs.FnMkdirAll { + return errors.New("FailFS!") + } + return nil + }) + suite.appFs = vfs + cm := suite.NewTestCopyManager() err := cm.CopyDir(specs[0].srcDir, suite.dstDir) assert.Error(suite.T(), err) @@ -379,12 +395,15 @@ func (suite *CopyPublicTestSuite) TestCopyDirReturnsErrorReadingSrcDir() { }, } createFileSpecs(specs) - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "ReadDir": func(string) ([]fs.DirEntry, error) { return nil, errors.New("FailFS!") }, - }, - ) + vfs := failfs.New(suite.appFs) + _ = vfs.SetFailFunc(func(_ avfs.VFSBase, fn avfs.FnVFS, _ *failfs.FailParam) error { + if fn == avfs.FnReadDir { + return errors.New("FailFS!") + } + return nil + }) + suite.appFs = vfs + cm := suite.NewTestCopyManager() err := cm.CopyDir(specs[0].srcDir, suite.dstDir) assert.Error(suite.T(), err) @@ -400,19 +419,18 @@ func (suite *CopyPublicTestSuite) TestCopyDirReturnsErrorCheckingSrcFile() { }, } createFileSpecs(specs) - // FailFS cannot fall-through, so preload the responses it is expected to give - srcDirStat, _ := suite.appFs.Stat(specs[0].srcDir) - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "Stat": func(path string) (fs.FileInfo, error) { - if path == specs[0].srcDir { - return srcDirStat, nil - } - return nil, errors.New("FailFS!") - }, - }, - ) + vfs := failfs.New(suite.appFs) + _ = vfs.SetFailFunc(func(_ avfs.VFSBase, fn avfs.FnVFS, fp *failfs.FailParam) error { + if fn == avfs.FnStat { + if fp.Path == specs[0].srcDir { + return nil + } + return errors.New("FailFS!") + } + return nil + }) + suite.appFs = vfs + cm := suite.NewTestCopyManager() err := cm.CopyDir(specs[0].srcDir, suite.dstDir) assert.Error(suite.T(), err) @@ -432,18 +450,7 @@ func (suite *CopyPublicTestSuite) TestCopyDirNestedReturnsErrorOnCopyDir() { }, } createFileSpecs(specs) - dstDirHandle, _ := suite.appFs.Open(suite.dstDir) - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "Open": func(path string) (avfs.File, error) { - if path == suite.dstDir { - return dstDirHandle, errors.New("FailFS!") - } - return dstDirHandle, nil - }, - }, - ) + cm := suite.NewTestCopyManager() err := cm.CopyDir(suite.appFs.Join(suite.cloneDir, "srcDir"), suite.dstDir) assert.Error(suite.T(), err) @@ -459,12 +466,15 @@ func (suite *CopyPublicTestSuite) TestCopyDirNestedReturnsErrorOnCopyFile() { }, } createFileSpecs(specs) - suite.appFs = failfs.New( - suite.appFs, - map[string]interface{}{ - "file.Read": func([]byte) (int, error) { return 0, errors.New("FailFS!") }, - }, - ) + vfs := failfs.New(suite.appFs) + _ = vfs.SetFailFunc(func(_ avfs.VFSBase, fn avfs.FnVFS, _ *failfs.FailParam) error { + if fn == avfs.FnFileRead { + return errors.New("FailFS!") + } + return nil + }) + suite.appFs = vfs + cm := suite.NewTestCopyManager() err := cm.CopyDir(suite.appFs.Join(suite.cloneDir, "srcDir"), suite.dstDir) assert.Error(suite.T(), err)