aboutsummaryrefslogtreecommitdiff
path: root/internal/encoding/ssh/filexfer/attrs_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/encoding/ssh/filexfer/attrs_test.go')
-rw-r--r--internal/encoding/ssh/filexfer/attrs_test.go231
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)
+ }
+}