Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions afero_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ func testDir(fs Fs) string {
}

func tmpFile(fs Fs) File {
// Ensure the temp directory hierarchy exists in the filesystem.
fs.MkdirAll(os.TempDir(), 0o700)
x, err := TempFile(fs, "", "afero")
if err != nil {
panic(fmt.Sprint("unable to work with temp file", err))
Expand Down
8 changes: 7 additions & 1 deletion ioutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package afero

import (
"os"
"path/filepath"
"strings"
"testing"
Expand All @@ -33,6 +34,7 @@ func checkSizePath(t *testing.T, path string, size int64) {

func TestReadFile(t *testing.T) {
testFS = &MemMapFs{}
testFS.MkdirAll(os.TempDir(), 0o700)
fsutil := &Afero{Fs: testFS}

testFS.Create("this_exists.go")
Expand All @@ -53,6 +55,7 @@ func TestReadFile(t *testing.T) {

func TestWriteFile(t *testing.T) {
testFS = &MemMapFs{}
testFS.MkdirAll(os.TempDir(), 0o700)
fsutil := &Afero{Fs: testFS}
f, err := fsutil.TempFile("", "ioutil-test")
if err != nil {
Expand Down Expand Up @@ -83,6 +86,7 @@ func TestWriteFile(t *testing.T) {

func TestReadDir(t *testing.T) {
testFS = &MemMapFs{}
testFS.MkdirAll(os.TempDir(), 0o700)
testFS.Mkdir("/i-am-a-dir", 0o777)
testFS.Create("/this_exists.go")
dirname := "rumpelstilzchen"
Expand Down Expand Up @@ -162,7 +166,9 @@ func TestTempFile(t *testing.T) {
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
file, err := TempFile(NewMemMapFs(), tt.args.dir, tt.args.pattern)
fs := NewMemMapFs()
fs.MkdirAll(os.TempDir(), 0o700)
file, err := TempFile(fs, tt.args.dir, tt.args.pattern)
if err != nil {
t.Errorf("TempFile() error = %v, none expected", err)
return
Expand Down
1 change: 1 addition & 0 deletions lstater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func TestLstatIfPossible(t *testing.T) {
pathFileMem := filepath.Join(memWorkDir, "aferom.txt")

WriteFile(osFs, filepath.Join(workDir, "afero.txt"), []byte("Hi, Afero!"), 0o777)
memFs.MkdirAll(memWorkDir, 0o777)
WriteFile(memFs, filepath.Join(pathFileMem), []byte("Hi, Afero!"), 0o777)

os.Chdir(workDir)
Expand Down
9 changes: 9 additions & 0 deletions memmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,15 @@ func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, erro
return nil, &os.PathError{Op: "open", Path: name, Err: ErrFileExists}
}
if os.IsNotExist(err) && (flag&os.O_CREATE > 0) {
// Check that the parent directory exists before creating the file,
// matching os.OpenFile semantics.
parentDir := normalizePath(filepath.Dir(normalizePath(name)))
m.mu.RLock()
_, parentExists := m.getData()[parentDir]
m.mu.RUnlock()
if !parentExists {
return nil, &os.PathError{Op: "open", Path: name, Err: os.ErrNotExist}
}
file, err = m.Create(name)
chmod = true
}
Expand Down
31 changes: 31 additions & 0 deletions memmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -918,3 +918,34 @@ func TestMemMapFsRename(t *testing.T) {
}
}
}

func TestOpenFileNonExistentDirectory(t *testing.T) {
// Verify that OpenFile with O_CREATE returns an error when the parent
// directory does not exist, matching os.OpenFile behavior.
// See https://github.com/spf13/afero/issues/270
fs := NewMemMapFs()

err := WriteFile(fs, "/nonexistent/dir/file.txt", []byte("content"), 0o644)
if err == nil {
t.Fatal("expected error when writing to a non-existent directory, got nil")
}
if !os.IsNotExist(err) {
t.Fatalf("expected os.ErrNotExist, got: %v", err)
}

// Verify it works when the directory is created first.
fs.MkdirAll("/existing/dir", 0o755)
err = WriteFile(fs, "/existing/dir/file.txt", []byte("content"), 0o644)
if err != nil {
t.Fatalf("expected no error when writing to an existing directory, got: %v", err)
}

// Verify the written content.
data, err := ReadFile(fs, "/existing/dir/file.txt")
if err != nil {
t.Fatalf("failed to read back written file: %v", err)
}
if string(data) != "content" {
t.Fatalf("expected 'content', got %q", string(data))
}
}
2 changes: 2 additions & 0 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func TestDirExists(t *testing.T) {

func TestIsDir(t *testing.T) {
testFS = new(MemMapFs)
testFS.MkdirAll(os.TempDir(), 0o700)

type test struct {
input string
Expand All @@ -90,6 +91,7 @@ func TestIsDir(t *testing.T) {

func TestIsEmpty(t *testing.T) {
testFS = new(MemMapFs)
testFS.MkdirAll(os.TempDir(), 0o700)

zeroSizedFile, _ := createZeroSizedFileInTempDir()
defer deleteFileInTempDir(zeroSizedFile)
Expand Down