1
0
Fork 0
mirror of https://github.com/restic/restic.git synced 2025-01-03 13:45:20 +00:00

fs: test correct xattr handling for symlinks

This commit is contained in:
Michael Eischer 2024-11-29 23:45:17 +01:00
parent 088bfac903
commit 4a9603d253
2 changed files with 84 additions and 3 deletions

View file

@ -17,6 +17,7 @@ type fsLocalMetadataTestcase struct {
follow bool follow bool
setup func(t *testing.T, path string) setup func(t *testing.T, path string)
nodeType restic.NodeType nodeType restic.NodeType
check func(t *testing.T, node *restic.Node)
} }
func testHandleVariants(t *testing.T, test func(t *testing.T)) { func testHandleVariants(t *testing.T, test func(t *testing.T)) {
@ -90,13 +91,15 @@ func runFSLocalTestcase(t *testing.T, test fsLocalMetadataTestcase) {
} }
f, err := testFs.OpenFile(path, flags, true) f, err := testFs.OpenFile(path, flags, true)
rtest.OK(t, err) rtest.OK(t, err)
checkMetadata(t, f, path, test.follow, test.nodeType) node := checkMetadata(t, f, path, test.follow, test.nodeType)
if test.check != nil {
test.check(t, node)
}
rtest.OK(t, f.Close()) rtest.OK(t, f.Close())
}) })
} }
func checkMetadata(t *testing.T, f File, path string, follow bool, nodeType restic.NodeType) { func checkMetadata(t *testing.T, f File, path string, follow bool, nodeType restic.NodeType) *restic.Node {
fi, err := f.Stat() fi, err := f.Stat()
rtest.OK(t, err) rtest.OK(t, err)
var fi2 os.FileInfo var fi2 os.FileInfo
@ -114,6 +117,8 @@ func checkMetadata(t *testing.T, f File, path string, follow bool, nodeType rest
// ModTime is likely unique per file, thus it provides a good indication that it is from the correct file // ModTime is likely unique per file, thus it provides a good indication that it is from the correct file
rtest.Equals(t, fi.ModTime, node.ModTime, "node ModTime") rtest.Equals(t, fi.ModTime, node.ModTime, "node ModTime")
rtest.Equals(t, nodeType, node.Type, "node Type") rtest.Equals(t, nodeType, node.Type, "node Type")
return node
} }
func assertFIEqual(t *testing.T, want os.FileInfo, got *ExtendedFileInfo) { func assertFIEqual(t *testing.T, want os.FileInfo, got *ExtendedFileInfo) {

View file

@ -0,0 +1,76 @@
//go:build darwin || freebsd || linux || solaris || windows
package fs
import (
"os"
"runtime"
"strings"
"testing"
"github.com/restic/restic/internal/restic"
rtest "github.com/restic/restic/internal/test"
)
func TestXattrNoFollow(t *testing.T) {
xattrs := []restic.ExtendedAttribute{
{
Name: "user.foo",
Value: []byte("bar"),
},
}
if runtime.GOOS == "windows" {
// windows seems to convert the xattr name to upper case
for i := range xattrs {
xattrs[i].Name = strings.ToUpper(xattrs[i].Name)
}
}
setXattrs := func(path string) {
node := &restic.Node{
Type: restic.NodeTypeFile,
ExtendedAttributes: xattrs,
}
rtest.OK(t, nodeRestoreExtendedAttributes(node, path))
}
checkXattrs := func(expected []restic.ExtendedAttribute) func(t *testing.T, node *restic.Node) {
return func(t *testing.T, node *restic.Node) {
rtest.Equals(t, expected, node.ExtendedAttributes, "xattr mismatch for file")
}
}
setupSymlinkTest := func(t *testing.T, path string) {
rtest.OK(t, os.WriteFile(path+"file", []byte("example"), 0o600))
setXattrs(path + "file")
rtest.OK(t, os.Symlink(path+"file", path))
}
for _, test := range []fsLocalMetadataTestcase{
{
name: "file",
setup: func(t *testing.T, path string) {
rtest.OK(t, os.WriteFile(path, []byte("example"), 0o600))
setXattrs(path)
},
nodeType: restic.NodeTypeFile,
check: checkXattrs(xattrs),
},
{
name: "symlink",
setup: setupSymlinkTest,
nodeType: restic.NodeTypeSymlink,
check: checkXattrs([]restic.ExtendedAttribute{}),
},
{
name: "symlink file",
follow: true,
setup: setupSymlinkTest,
nodeType: restic.NodeTypeFile,
check: checkXattrs(xattrs),
},
} {
testHandleVariants(t, func(t *testing.T) {
runFSLocalTestcase(t, test)
})
}
}