Add new field DeviceID and tests

This commit is contained in:
Alexander Neumann 2017-04-05 20:42:15 +02:00
parent 67a2ac292b
commit ffcb015581
2 changed files with 114 additions and 1 deletions

View File

@ -37,11 +37,12 @@ type Node struct {
User string `json:"user,omitempty"`
Group string `json:"group,omitempty"`
Inode uint64 `json:"inode,omitempty"`
DeviceID uint64 `json:"device_id,omitempty"` // device id of the file, stat.st_dev
Size uint64 `json:"size,omitempty"`
Links uint64 `json:"links,omitempty"`
LinkTarget string `json:"linktarget,omitempty"`
ExtendedAttributes []ExtendedAttribute `json:"extended_attributes,omitempty"`
Device uint64 `json:"device,omitempty"`
Device uint64 `json:"device,omitempty"` // in case of Type == "dev", stat.st_rdev
Content IDs `json:"content"`
Subtree *ID `json:"subtree,omitempty"`
@ -376,6 +377,9 @@ func (node Node) Equals(other Node) bool {
if node.Inode != other.Inode {
return false
}
if node.DeviceID != other.DeviceID {
return false
}
if node.Size != other.Size {
return false
}

View File

@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"runtime"
"syscall"
"testing"
"time"
@ -241,3 +242,111 @@ func AssertFsTimeEqual(t *testing.T, label string, nodeType string, t1 time.Time
Assert(t, equal, "%s: %s doesn't match (%v != %v)", label, nodeType, t1, t2)
}
func stat(t testing.TB, filename string) (fi os.FileInfo, ok bool) {
fi, err := os.Lstat(filename)
if err != nil && os.IsNotExist(err) {
return fi, false
}
if err != nil {
t.Fatal(err)
}
return fi, true
}
func checkFile(t testing.TB, stat *syscall.Stat_t, node *restic.Node) {
if uint32(node.Mode.Perm()) != stat.Mode&0777 {
t.Errorf("Mode does not match, want %v, got %v", stat.Mode&0777, node.Mode)
}
if node.Inode != stat.Ino {
t.Errorf("Inode does not match, want %v, got %v", stat.Ino, node.Inode)
}
if node.DeviceID != stat.Dev {
t.Errorf("Dev does not match, want %v, got %v", stat.Dev, node.DeviceID)
}
if node.Size != uint64(stat.Size) {
t.Errorf("Size does not match, want %v, got %v", stat.Size, node.Size)
}
if node.Links != stat.Nlink {
t.Errorf("Links does not match, want %v, got %v", stat.Nlink, node.Links)
}
if node.ModTime != time.Unix(stat.Mtim.Unix()) {
t.Errorf("ModTime does not match, want %v, got %v", time.Unix(stat.Mtim.Unix()), node.ModTime)
}
if node.ChangeTime != time.Unix(stat.Ctim.Unix()) {
t.Errorf("ChangeTime does not match, want %v, got %v", time.Unix(stat.Ctim.Unix()), node.ChangeTime)
}
if node.AccessTime != time.Unix(stat.Atim.Unix()) {
t.Errorf("AccessTime does not match, want %v, got %v", time.Unix(stat.Atim.Unix()), node.AccessTime)
}
if node.UID != stat.Uid {
t.Errorf("UID does not match, want %v, got %v", stat.Uid, node.UID)
}
if node.GID != stat.Gid {
t.Errorf("UID does not match, want %v, got %v", stat.Gid, node.GID)
}
}
func checkDevice(t testing.TB, stat *syscall.Stat_t, node *restic.Node) {
if node.Device != stat.Rdev {
t.Errorf("Rdev does not match, want %v, got %v", stat.Rdev, node.Device)
}
}
func TestNodeFromFileInfo(t *testing.T) {
var tests = []struct {
filename string
canSkip bool
}{
{"node_test.go", false},
{"/dev/null", true},
{"/dev/sda", true},
}
for _, test := range tests {
t.Run("", func(t *testing.T) {
fi, found := stat(t, test.filename)
if !found && test.canSkip {
t.Skipf("%v not found in filesystem")
return
}
if fi.Sys() == nil {
t.Skip("fi.Sys() is nil")
return
}
s, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
t.Skip("fi type is %T, not stat_t", fi.Sys())
return
}
node, err := restic.NodeFromFileInfo(test.filename, fi)
if err != nil {
t.Fatal(err)
}
switch node.Type {
case "file":
checkFile(t, s, node)
case "dev", "chardev":
checkFile(t, s, node)
checkDevice(t, s, node)
default:
t.Fatalf("invalid node type %q", node.Type)
}
})
}
}