diff --git a/pkg/mock/fileUtils.go b/pkg/mock/fileUtils.go index 07e96ce41..6ca4d5a8d 100644 --- a/pkg/mock/fileUtils.go +++ b/pkg/mock/fileUtils.go @@ -13,9 +13,14 @@ import ( var dirContent []byte -// FilesMock implements the functions from piperutils.Files with an in-memory file system. +type fileProperties struct { + content *[]byte + mode *os.FileMode +} + +//FilesMock implements the functions from piperutils.Files with an in-memory file system. type FilesMock struct { - files map[string]*[]byte + files map[string]*fileProperties writtenFiles map[string]*[]byte removedFiles map[string]*[]byte currentDir string @@ -24,7 +29,7 @@ type FilesMock struct { func (f *FilesMock) init() { if f.files == nil { - f.files = map[string]*[]byte{} + f.files = map[string]*fileProperties{} } if f.removedFiles == nil { f.removedFiles = map[string]*[]byte{} @@ -44,21 +49,39 @@ func (f *FilesMock) toAbsPath(path string) string { return path } -// AddFile establishes the existence of a virtual file. +// AddFile establishes the existence of a virtual file. The file is +// added with mode 644 func (f *FilesMock) AddFile(path string, contents []byte) { - f.associateContent(path, &contents) + f.AddFileWithMode(path, contents, 0644) } -// AddDir establishes the existence of a virtual directory. +// AddFileWithMode establishes the existence of a virtual file. +func (f *FilesMock) AddFileWithMode(path string, contents []byte, mode os.FileMode) { + f.associateContent(path, &contents, &mode) +} + +// AddDir establishes the existence of a virtual directory. The directory +// is add with default mode 755 func (f *FilesMock) AddDir(path string) { - f.associateContent(path, &dirContent) + f.AddDirWithMode(path, 0755) } -func (f *FilesMock) associateContent(path string, content *[]byte) { +// AddDirWithMode establishes the existence of a virtual directory. +func (f *FilesMock) AddDirWithMode(path string, mode os.FileMode) { + f.associateContent(path, &dirContent, &mode) +} + +func (f *FilesMock) associateContent(path string, content *[]byte, mode *os.FileMode) { f.init() path = strings.ReplaceAll(path, "/", f.Separator) path = strings.ReplaceAll(path, "\\", f.Separator) - f.files[f.toAbsPath(path)] = content + path = f.toAbsPath(path) + if _, ok := f.files[path]; !ok { + f.files[path] = &fileProperties{} + } + props := f.files[path] + props.content = content + props.mode = mode } // HasFile returns true if the virtual file system contains an entry for the given path. @@ -87,20 +110,20 @@ func (f *FilesMock) FileExists(path string) (bool, error) { if f.files == nil { return false, nil } - content, exists := f.files[f.toAbsPath(path)] + props, exists := f.files[f.toAbsPath(path)] if !exists { return false, nil } - return content != &dirContent, nil + return props.content != &dirContent, nil } // DirExists returns true, if the given path is a previously added directory, or a parent directory for any of the // previously added files. func (f *FilesMock) DirExists(path string) (bool, error) { path = f.toAbsPath(path) - for entry, content := range f.files { + for entry, props := range f.files { var dirComponents []string - if content == &dirContent { + if props.content == &dirContent { dirComponents = strings.Split(entry, f.Separator) } else { dirComponents = strings.Split(filepath.Dir(entry), f.Separator) @@ -125,37 +148,37 @@ func (f *FilesMock) DirExists(path string) (bool, error) { // Copy checks if content has been associated with the given src path, and if so copies it under the given path dst. func (f *FilesMock) Copy(src, dst string) (int64, error) { f.init() - content, exists := f.files[f.toAbsPath(src)] - if !exists || content == &dirContent { + props, exists := f.files[f.toAbsPath(src)] + if !exists || props.content == &dirContent { return 0, fmt.Errorf("cannot copy '%s': %w", src, os.ErrNotExist) } - f.AddFile(dst, *content) - return int64(len(*content)), nil + f.AddFileWithMode(dst, *props.content, *props.mode) + return int64(len(*props.content)), nil } // FileRead returns the content previously associated with the given path via AddFile(), or an error if no // content has been associated. func (f *FilesMock) FileRead(path string) ([]byte, error) { f.init() - content, exists := f.files[f.toAbsPath(path)] + props, exists := f.files[f.toAbsPath(path)] if !exists { return nil, fmt.Errorf("could not read '%s'", path) } // check if trying to open a directory for reading - if content == &dirContent { + if props.content == &dirContent { return nil, fmt.Errorf("could not read '%s': %w", path, os.ErrInvalid) } - return *content, nil + return *props.content, nil } // FileWrite just forwards to AddFile(), i.e. the content is associated with the given path. -func (f *FilesMock) FileWrite(path string, content []byte, _ os.FileMode) error { +func (f *FilesMock) FileWrite(path string, content []byte, mode os.FileMode) error { f.init() // NOTE: FilesMock could be extended to have a set of paths for which FileWrite should fail. // This is why AddFile() exists separately, to differentiate the notion of setting up the mocking // versus implementing the methods from Files. f.writtenFiles[f.toAbsPath(path)] = &content - f.AddFile(path, content) + f.AddFileWithMode(path, content, mode) return nil } @@ -166,21 +189,21 @@ func (f *FilesMock) FileRemove(path string) error { return fmt.Errorf("the file '%s' does not exist: %w", path, os.ErrNotExist) } absPath := f.toAbsPath(path) - content, exists := f.files[absPath] + props, exists := f.files[absPath] if !exists { return fmt.Errorf("the file '%s' does not exist: %w", path, os.ErrNotExist) } delete(f.files, absPath) - f.removedFiles[absPath] = content + f.removedFiles[absPath] = props.content return nil } // MkdirAll creates a directory in the in-memory file system, so that this path is established to exist. -func (f *FilesMock) MkdirAll(path string, _ os.FileMode) error { +func (f *FilesMock) MkdirAll(path string, mode os.FileMode) error { // NOTE: FilesMock could be extended to have a set of paths for which MkdirAll should fail. // This is why AddDir() exists separately, to differentiate the notion of setting up the mocking // versus implementing the methods from Files. - f.AddDir(path) + f.AddDirWithMode(path, mode) return nil }