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