restore: xattr restore filter tests
Signed-off-by: Tesshu Flower <tflower@redhat.com>
This commit is contained in:
parent
bb4c6d4934
commit
7dd18c66aa
1 changed files with 138 additions and 0 deletions
|
@ -4,12 +4,14 @@
|
||||||
package fs
|
package fs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/restic/restic/internal/filter"
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
rtest "github.com/restic/restic/internal/test"
|
rtest "github.com/restic/restic/internal/test"
|
||||||
)
|
)
|
||||||
|
@ -37,6 +39,56 @@ func setAndVerifyXattr(t *testing.T, file string, attrs []restic.ExtendedAttribu
|
||||||
rtest.Assert(t, nodeActual.Equals(*node), "xattr mismatch got %v expected %v", nodeActual.ExtendedAttributes, node.ExtendedAttributes)
|
rtest.Assert(t, nodeActual.Equals(*node), "xattr mismatch got %v expected %v", nodeActual.ExtendedAttributes, node.ExtendedAttributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setAndVerifyXattrWithSelectFilter(t *testing.T, file string, testAttr []testXattrToRestore, xattrSelectFilter func(_ string) bool) {
|
||||||
|
attrs := make([]restic.ExtendedAttribute, len(testAttr))
|
||||||
|
for i := range testAttr {
|
||||||
|
attrs[i] = testAttr[i].xattr
|
||||||
|
}
|
||||||
|
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
// windows seems to convert the xattr name to upper case
|
||||||
|
for i := range attrs {
|
||||||
|
attrs[i].Name = strings.ToUpper(attrs[i].Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
node := &restic.Node{
|
||||||
|
Type: restic.NodeTypeFile,
|
||||||
|
ExtendedAttributes: attrs,
|
||||||
|
}
|
||||||
|
|
||||||
|
rtest.OK(t, nodeRestoreExtendedAttributes(node, file, xattrSelectFilter))
|
||||||
|
|
||||||
|
nodeActual := &restic.Node{
|
||||||
|
Type: restic.NodeTypeFile,
|
||||||
|
}
|
||||||
|
rtest.OK(t, nodeFillExtendedAttributes(nodeActual, file, false))
|
||||||
|
|
||||||
|
// Check nodeActual to make sure only xattrs we expect are there
|
||||||
|
for _, testAttr := range testAttr {
|
||||||
|
xattrFound := false
|
||||||
|
xattrRestored := false
|
||||||
|
for _, restoredAttr := range nodeActual.ExtendedAttributes {
|
||||||
|
if restoredAttr.Name == testAttr.xattr.Name {
|
||||||
|
xattrFound = true
|
||||||
|
xattrRestored = bytes.Equal(restoredAttr.Value, testAttr.xattr.Value)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if testAttr.shouldRestore {
|
||||||
|
rtest.Assert(t, xattrFound, "xattr %s not restored", testAttr.xattr.Name)
|
||||||
|
rtest.Assert(t, xattrRestored, "xattr %v value not restored", testAttr.xattr)
|
||||||
|
} else {
|
||||||
|
rtest.Assert(t, !xattrFound, "xattr %v should not have been restored", testAttr.xattr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type testXattrToRestore struct {
|
||||||
|
xattr restic.ExtendedAttribute
|
||||||
|
shouldRestore bool
|
||||||
|
}
|
||||||
|
|
||||||
func TestOverwriteXattr(t *testing.T) {
|
func TestOverwriteXattr(t *testing.T) {
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
file := filepath.Join(dir, "file")
|
file := filepath.Join(dir, "file")
|
||||||
|
@ -47,6 +99,10 @@ func TestOverwriteXattr(t *testing.T) {
|
||||||
Name: "user.foo",
|
Name: "user.foo",
|
||||||
Value: []byte("bar"),
|
Value: []byte("bar"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "abc.test",
|
||||||
|
Value: []byte("testxattr"),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
setAndVerifyXattr(t, file, []restic.ExtendedAttribute{
|
setAndVerifyXattr(t, file, []restic.ExtendedAttribute{
|
||||||
|
@ -56,3 +112,85 @@ func TestOverwriteXattr(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOverwriteXattrWithSelectFilter(t *testing.T) {
|
||||||
|
dir := t.TempDir()
|
||||||
|
file := filepath.Join(dir, "file2")
|
||||||
|
rtest.OK(t, os.WriteFile(file, []byte("hello world"), 0o600))
|
||||||
|
|
||||||
|
noopWarnf := func(_ string, _ ...interface{}) {}
|
||||||
|
|
||||||
|
// Set a filter as if the user passed in --include-xattr user.*
|
||||||
|
xattrSelectFilter1 := func(xattrName string) bool {
|
||||||
|
shouldInclude, _ := filter.IncludeByPattern([]string{"user.*"}, noopWarnf)(xattrName)
|
||||||
|
return shouldInclude
|
||||||
|
}
|
||||||
|
|
||||||
|
setAndVerifyXattrWithSelectFilter(t, file, []testXattrToRestore{
|
||||||
|
{
|
||||||
|
xattr: restic.ExtendedAttribute{
|
||||||
|
Name: "user.foo",
|
||||||
|
Value: []byte("bar"),
|
||||||
|
},
|
||||||
|
shouldRestore: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xattr: restic.ExtendedAttribute{
|
||||||
|
Name: "user.test",
|
||||||
|
Value: []byte("testxattr"),
|
||||||
|
},
|
||||||
|
shouldRestore: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xattr: restic.ExtendedAttribute{
|
||||||
|
Name: "security.other",
|
||||||
|
Value: []byte("testing"),
|
||||||
|
},
|
||||||
|
shouldRestore: false,
|
||||||
|
},
|
||||||
|
}, xattrSelectFilter1)
|
||||||
|
|
||||||
|
// Set a filter as if the user passed in --include-xattr user.*
|
||||||
|
xattrSelectFilter2 := func(xattrName string) bool {
|
||||||
|
shouldInclude, _ := filter.IncludeByPattern([]string{"user.o*", "user.comm*"}, noopWarnf)(xattrName)
|
||||||
|
return shouldInclude
|
||||||
|
}
|
||||||
|
|
||||||
|
setAndVerifyXattrWithSelectFilter(t, file, []testXattrToRestore{
|
||||||
|
{
|
||||||
|
xattr: restic.ExtendedAttribute{
|
||||||
|
Name: "user.other",
|
||||||
|
Value: []byte("some"),
|
||||||
|
},
|
||||||
|
shouldRestore: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xattr: restic.ExtendedAttribute{
|
||||||
|
Name: "security.other",
|
||||||
|
Value: []byte("testing"),
|
||||||
|
},
|
||||||
|
shouldRestore: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xattr: restic.ExtendedAttribute{
|
||||||
|
Name: "user.open",
|
||||||
|
Value: []byte("door"),
|
||||||
|
},
|
||||||
|
shouldRestore: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xattr: restic.ExtendedAttribute{
|
||||||
|
Name: "user.common",
|
||||||
|
Value: []byte("testing"),
|
||||||
|
},
|
||||||
|
shouldRestore: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
xattr: restic.ExtendedAttribute{
|
||||||
|
Name: "user.bad",
|
||||||
|
Value: []byte("dontincludeme"),
|
||||||
|
},
|
||||||
|
shouldRestore: false,
|
||||||
|
},
|
||||||
|
}, xattrSelectFilter2)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue