diff options
Diffstat (limited to 'internal/encoding/ssh/filexfer/attrs_test.go')
-rw-r--r-- | internal/encoding/ssh/filexfer/attrs_test.go | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/internal/encoding/ssh/filexfer/attrs_test.go b/internal/encoding/ssh/filexfer/attrs_test.go new file mode 100644 index 0000000..c03015c --- /dev/null +++ b/internal/encoding/ssh/filexfer/attrs_test.go @@ -0,0 +1,231 @@ +package filexfer + +import ( + "bytes" + "testing" +) + +func TestAttributes(t *testing.T) { + const ( + size = 0x123456789ABCDEF0 + uid = 1000 + gid = 100 + perms = 0x87654321 + atime = 0x2A2B2C2D + mtime = 0x42434445 + ) + + extAttr := ExtendedAttribute{ + Type: "foo", + Data: "bar", + } + + attr := &Attributes{ + Size: size, + UID: uid, + GID: gid, + Permissions: perms, + ATime: atime, + MTime: mtime, + ExtendedAttributes: []ExtendedAttribute{ + extAttr, + }, + } + + type test struct { + name string + flags uint32 + encoded []byte + } + + tests := []test{ + { + name: "empty", + encoded: []byte{ + 0x00, 0x00, 0x00, 0x00, + }, + }, + { + name: "size", + flags: AttrSize, + encoded: []byte{ + 0x00, 0x00, 0x00, 0x01, + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + }, + }, + { + name: "uidgid", + flags: AttrUIDGID, + encoded: []byte{ + 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x03, 0xE8, + 0x00, 0x00, 0x00, 100, + }, + }, + { + name: "permissions", + flags: AttrPermissions, + encoded: []byte{ + 0x00, 0x00, 0x00, 0x04, + 0x87, 0x65, 0x43, 0x21, + }, + }, + { + name: "acmodtime", + flags: AttrACModTime, + encoded: []byte{ + 0x00, 0x00, 0x00, 0x08, + 0x2A, 0x2B, 0x2C, 0x2D, + 0x42, 0x43, 0x44, 0x45, + }, + }, + { + name: "extended", + flags: AttrExtended, + encoded: []byte{ + 0x80, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x03, 'f', 'o', 'o', + 0x00, 0x00, 0x00, 0x03, 'b', 'a', 'r', + }, + }, + { + name: "size uidgid permisssions acmodtime extended", + flags: AttrSize | AttrUIDGID | AttrPermissions | AttrACModTime | AttrExtended, + encoded: []byte{ + 0x80, 0x00, 0x00, 0x0F, + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x00, 0x00, 0x03, 0xE8, + 0x00, 0x00, 0x00, 100, + 0x87, 0x65, 0x43, 0x21, + 0x2A, 0x2B, 0x2C, 0x2D, + 0x42, 0x43, 0x44, 0x45, + 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x03, 'f', 'o', 'o', + 0x00, 0x00, 0x00, 0x03, 'b', 'a', 'r', + }, + }, + } + + for _, tt := range tests { + attr := *attr + + t.Run(tt.name, func(t *testing.T) { + attr.Flags = tt.flags + + buf, err := attr.MarshalBinary() + if err != nil { + t.Fatal("unexpected error:", err) + } + + if !bytes.Equal(buf, tt.encoded) { + t.Fatalf("MarshalBinary() = %X, but wanted %X", buf, tt.encoded) + } + + attr = Attributes{} + + if err := attr.UnmarshalBinary(buf); err != nil { + t.Fatal("unexpected error:", err) + } + + if attr.Flags != tt.flags { + t.Errorf("UnmarshalBinary(): Flags was %x, but wanted %x", attr.Flags, tt.flags) + } + + if attr.Flags&AttrSize != 0 && attr.Size != size { + t.Errorf("UnmarshalBinary(): Size was %x, but wanted %x", attr.Size, size) + } + + if attr.Flags&AttrUIDGID != 0 { + if attr.UID != uid { + t.Errorf("UnmarshalBinary(): UID was %x, but wanted %x", attr.UID, uid) + } + + if attr.GID != gid { + t.Errorf("UnmarshalBinary(): GID was %x, but wanted %x", attr.GID, gid) + } + } + + if attr.Flags&AttrPermissions != 0 && attr.Permissions != perms { + t.Errorf("UnmarshalBinary(): Permissions was %#v, but wanted %#v", attr.Permissions, perms) + } + + if attr.Flags&AttrACModTime != 0 { + if attr.ATime != atime { + t.Errorf("UnmarshalBinary(): ATime was %x, but wanted %x", attr.ATime, atime) + } + + if attr.MTime != mtime { + t.Errorf("UnmarshalBinary(): MTime was %x, but wanted %x", attr.MTime, mtime) + } + } + + if attr.Flags&AttrExtended != 0 { + extAttrs := attr.ExtendedAttributes + + if count := len(extAttrs); count != 1 { + t.Fatalf("UnmarshalBinary(): len(ExtendedAttributes) was %d, but wanted %d", count, 1) + } + + if got := extAttrs[0]; got != extAttr { + t.Errorf("UnmarshalBinary(): ExtendedAttributes[0] was %#v, but wanted %#v", got, extAttr) + } + } + }) + } +} + +func TestNameEntry(t *testing.T) { + const ( + filename = "foo" + longname = "bar" + perms = 0x87654321 + ) + + e := &NameEntry{ + Filename: filename, + Longname: longname, + Attrs: Attributes{ + Flags: AttrPermissions, + Permissions: perms, + }, + } + + buf, err := e.MarshalBinary() + if err != nil { + t.Fatal("unexpected error:", err) + } + + want := []byte{ + 0x00, 0x00, 0x00, 0x03, 'f', 'o', 'o', + 0x00, 0x00, 0x00, 0x03, 'b', 'a', 'r', + 0x00, 0x00, 0x00, 0x04, + 0x87, 0x65, 0x43, 0x21, + } + + if !bytes.Equal(buf, want) { + t.Fatalf("MarshalBinary() = %X, but wanted %X", buf, want) + } + + *e = NameEntry{} + + if err := e.UnmarshalBinary(buf); err != nil { + t.Fatal("unexpected error:", err) + } + + if e.Filename != filename { + t.Errorf("UnmarhsalFrom(): Filename was %q, but expected %q", e.Filename, filename) + } + + if e.Longname != longname { + t.Errorf("UnmarhsalFrom(): Longname was %q, but expected %q", e.Longname, longname) + } + + if e.Attrs.Flags != AttrPermissions { + t.Errorf("UnmarshalBinary(): Attrs.Flag was %#x, but expected %#x", e.Attrs.Flags, AttrPermissions) + } + + if e.Attrs.Permissions != perms { + t.Errorf("UnmarshalBinary(): Attrs.Permissions was %#v, but expected %#v", e.Attrs.Permissions, perms) + } +} |