Fix MemMapFs inconsistent path store

Adds a test that fails for the current MemMapFs when creating files in
nested directories with synonyms for the path (i.e. full path, relative
path, explict relative path).

Also fixes MemMapFs so that test (and all others pass).
This commit is contained in:
Fraser Waters 2023-04-05 11:46:41 +01:00
parent 45ef3465a4
commit 8dfb2824ee
2 changed files with 109 additions and 2 deletions

View File

@ -177,9 +177,13 @@ func normalizePath(path string) string {
return FilePathSeparator return FilePathSeparator
case "..": case "..":
return FilePathSeparator return FilePathSeparator
default:
return path
} }
// If path isn't rooted make it rooted
if !strings.HasPrefix(path, FilePathSeparator) {
path = FilePathSeparator + path
}
return path
} }
func (m *MemMapFs) Open(name string) (File, error) { func (m *MemMapFs) Open(name string) (File, error) {
@ -351,6 +355,7 @@ func (m *MemMapFs) Stat(name string) (os.FileInfo, error) {
func (m *MemMapFs) Chmod(name string, mode os.FileMode) error { func (m *MemMapFs) Chmod(name string, mode os.FileMode) error {
mode &= chmodBits mode &= chmodBits
name = normalizePath(name)
m.mu.RLock() m.mu.RLock()
f, ok := m.getData()[name] f, ok := m.getData()[name]

View File

@ -833,3 +833,105 @@ func TestMemFsRenameDir(t *testing.T) {
t.Errorf("Cannot recreate the subdir in the source dir: %s", err) t.Errorf("Cannot recreate the subdir in the source dir: %s", err)
} }
} }
func TestMemFsMkDir(t *testing.T) {
t.Parallel()
fs := NewMemMapFs()
// Creating a folder at "dir" or "/dir" or "./dir" should create the 'dir' directory at root
err := fs.Mkdir("a", 0o777)
if err != nil {
t.Fatalf("MkDir failed: %s", err)
}
err = fs.Mkdir("/b", 0o777)
if err != nil {
t.Fatalf("MkDir failed: %s", err)
}
err = fs.Mkdir("./c", 0o777)
if err != nil {
t.Fatalf("MkDir failed: %s", err)
}
// Listing root should return all folders
files, err := ReadDir(fs, "/")
if err != nil {
t.Fatalf("ReadDir failed: %s", err)
}
if len(files) != 3 {
t.Fatalf("Expected 3 files, got %d", len(files))
}
var foundA, foundB, foundC bool
for _, file := range files {
if !file.IsDir() {
t.Fatalf("Expected to find a directory not a file: %s", file.Name())
}
if file.Name() == "a" {
foundA = true
} else if file.Name() == "b" {
foundB = true
} else if file.Name() == "c" {
foundC = true
}
}
if !foundA || !foundB || !foundC {
t.Fatalf("Expected to find all files, but didn't")
}
}
func TestMemFsCreateFileNested(t *testing.T) {
t.Parallel()
fs := NewMemMapFs()
err := fs.Mkdir("dir", 0o777)
if err != nil {
t.Fatalf("MkDir failed: %s", err)
}
// Creating a file at "dir/a.txt" or "/dir/a.txt" or "./dir/a.txt" should create in the dir directory
err = WriteFile(fs, "dir/a.txt", []byte("test"), 0o777)
if err != nil {
t.Fatalf("WriteFile failed: %s", err)
}
err = WriteFile(fs, "/dir/b.txt", []byte("test"), 0o777)
if err != nil {
t.Fatalf("WriteFile failed: %s", err)
}
err = WriteFile(fs, "./dir/c.txt", []byte("test"), 0o777)
if err != nil {
t.Fatalf("WriteFile failed: %s", err)
}
// Listing dir should return all the files
files, err := ReadDir(fs, "/dir")
if err != nil {
t.Fatalf("ReadDir failed: %s", err)
}
if len(files) != 3 {
t.Fatalf("Expected 3 files, got %d", len(files))
}
var foundA, foundB, foundC bool
for _, file := range files {
if file.Name() == "a.txt" {
foundA = true
} else if file.Name() == "b.txt" {
foundB = true
} else if file.Name() == "c.txt" {
foundC = true
}
}
if !foundA || !foundB || !foundC {
t.Fatalf("Expected to find all files, but didn't")
}
}