feat; Add initial tests for symlink behaviour of open

This commit is contained in:
Felicitas Pojtinger
2022-01-21 03:10:17 +01:00
parent d5557ebf9c
commit 1a5f12542a
2 changed files with 155 additions and 56 deletions

View File

@@ -451,52 +451,66 @@ func (f *STFS) OpenFile(name string, flag int, perm os.FileMode) (afero.File, er
)
if err != nil {
if err == sql.ErrNoRows {
if !f.readOnly && flag&os.O_CREATE != 0 && flag&os.O_EXCL == 0 {
if _, err := inventory.Stat(
f.metadata,
hdr, err = inventory.Stat(
f.metadata,
filepath.Dir(name),
false,
name,
true,
f.onHeader,
); err != nil {
if err == sql.ErrNoRows {
f.onHeader,
)
if err != nil {
if err == sql.ErrNoRows {
if !f.readOnly && flag&os.O_CREATE != 0 && flag&os.O_EXCL == 0 {
if _, err := inventory.Stat(
f.metadata,
filepath.Dir(name),
false,
f.onHeader,
); err != nil {
if err == sql.ErrNoRows {
return nil, os.ErrNotExist
}
return nil, err
}
if target, err := inventory.Stat(
f.metadata,
name,
true,
f.onHeader,
); err == nil {
if target.Typeflag == tar.TypeDir {
return nil, config.ErrIsDirectory
}
}
if err := f.mknodeWithoutLocking(false, name, perm, false, "", false); err != nil {
return nil, err
}
hdr, err = inventory.Stat(
f.metadata,
name,
false,
f.onHeader,
)
if err != nil {
return nil, err
}
} else {
return nil, os.ErrNotExist
}
} else {
return nil, err
}
if target, err := inventory.Stat(
f.metadata,
name,
true,
f.onHeader,
); err == nil {
if target.Typeflag == tar.TypeDir {
return nil, config.ErrIsDirectory
}
}
if err := f.mknodeWithoutLocking(false, name, perm, false, "", false); err != nil {
return nil, err
}
hdr, err = inventory.Stat(
f.metadata,
name,
false,
f.onHeader,
)
if err != nil {
return nil, err
}
} else {
return nil, os.ErrNotExist
}
} else {
return nil, err
@@ -717,10 +731,24 @@ func (f *STFS) Stat(name string) (os.FileInfo, error) {
)
if err != nil {
if err == sql.ErrNoRows {
return nil, os.ErrNotExist
}
hdr, err = inventory.Stat(
f.metadata,
return nil, err
name,
true,
f.onHeader,
)
if err != nil {
if err == sql.ErrNoRows {
return nil, os.ErrNotExist
}
return nil, err
}
} else {
return nil, err
}
}
return NewFileInfoFromTarHeader(hdr, f.log), nil

View File

@@ -1267,42 +1267,42 @@ var openTests = []struct {
name string
args openArgs
wantErr bool
prepare func(afero.Fs) error
prepare func(symFs) error
check func(afero.File) error
}{
{
"Can open /",
openArgs{"/"},
false,
func(f afero.Fs) error { return nil },
func(f symFs) error { return nil },
func(f afero.File) error { return nil },
},
{
"Can not open ' '",
openArgs{" "},
true,
func(f afero.Fs) error { return nil },
func(f symFs) error { return nil },
func(f afero.File) error { return nil },
},
{
"Can open ''",
openArgs{""},
false,
func(f afero.Fs) error { return nil },
func(f symFs) error { return nil },
func(f afero.File) error { return nil },
},
{
"Can not open /test.txt without creating it",
openArgs{"/test.txt"},
true,
func(f afero.Fs) error { return nil },
func(f symFs) error { return nil },
func(f afero.File) error { return nil },
},
{
"Can open /test.txt after creating it",
openArgs{"/test.txt"},
false,
func(f afero.Fs) error {
func(f symFs) error {
if _, err := f.Create("/test.txt"); err != nil {
return err
}
@@ -1324,14 +1324,36 @@ var openTests = []struct {
"Can not open /mydir/test.txt without creating it",
openArgs{"/mydir/test.txt"},
true,
func(f afero.Fs) error { return nil },
func(f symFs) error { return nil },
func(f afero.File) error { return nil },
},
{
"Can open /mydir after creating it",
openArgs{"/mydir"},
false,
func(f symFs) error {
if err := f.Mkdir("/mydir", os.ModePerm); err != nil {
return err
}
return nil
},
func(f afero.File) error {
want := "/mydir"
got := f.Name()
if want != got {
return fmt.Errorf("invalid name, got %v, want %v", got, want)
}
return nil
},
},
{
"Can open /mydir/test.txt after creating it",
openArgs{"/mydir/test.txt"},
false,
func(f afero.Fs) error {
func(f symFs) error {
if err := f.Mkdir("/mydir", os.ModePerm); err != nil {
return err
}
@@ -1353,6 +1375,50 @@ var openTests = []struct {
return nil
},
},
{
"Can open symlink to root",
openArgs{"/existingsymlink"},
false,
func(sf symFs) error {
if err := sf.SymlinkIfPossible("/", "/existingsymlink"); err != nil {
return nil
}
return nil
},
func(f afero.File) error { return nil },
},
// FIXME: Since we can't differentiate between broken and non-broken symlinks, this does not work yet
// {
// "Can not broken symlink to /brokensymlink",
// openArgs{"/brokensymlink"},
// true,
// func(sf symFs) error {
// if err := sf.SymlinkIfPossible("/test.txt", "/brokensymlink"); err != nil {
// return nil
// }
// return nil
// },
// func(f afero.File) error { return nil },
// },
{
"Can open symlink /existingsymlink to directory",
openArgs{"/existingsymlink"},
false,
func(sf symFs) error {
if err := sf.Mkdir("/mydir", os.ModePerm); err != nil {
return err
}
if err := sf.SymlinkIfPossible("/mydir", "/existingsymlink"); err != nil {
return nil
}
return nil
},
func(f afero.File) error { return nil },
},
}
func TestSTFS_Open(t *testing.T) {
@@ -1360,21 +1426,26 @@ func TestSTFS_Open(t *testing.T) {
tt := tt
runTestForAllFss(t, tt.name, true, true, true, func(t *testing.T, fs fsConfig) {
if err := tt.prepare(fs.fs); err != nil {
t.Errorf("%v prepare() error = %v", fs.fs.Name(), err)
symFs, ok := fs.fs.(symFs)
if !ok {
return
}
if err := tt.prepare(symFs); err != nil {
t.Errorf("%v prepare() error = %v", symFs.Name(), err)
return
}
got, err := fs.fs.Open(tt.args.name)
got, err := symFs.Open(tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("%v.Open() error = %v, wantErr %v", fs.fs.Name(), err, tt.wantErr)
t.Errorf("%v.Open() error = %v, wantErr %v", symFs.Name(), err, tt.wantErr)
return
}
if err := tt.check(got); err != nil {
t.Errorf("%v check() error = %v", fs.fs.Name(), err)
t.Errorf("%v check() error = %v", symFs.Name(), err)
return
}