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) } }