github.com/pkg/sftp@v1.13.6/internal/encoding/ssh/filexfer/attrs_test.go (about)

     1  package sshfx
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  )
     7  
     8  func TestAttributes(t *testing.T) {
     9  	const (
    10  		size  uint64   = 0x123456789ABCDEF0
    11  		uid            = 1000
    12  		gid            = 100
    13  		perms FileMode = 0x87654321
    14  		atime          = 0x2A2B2C2D
    15  		mtime          = 0x42434445
    16  	)
    17  
    18  	extAttr := ExtendedAttribute{
    19  		Type: "foo",
    20  		Data: "bar",
    21  	}
    22  
    23  	attr := &Attributes{
    24  		Size:        size,
    25  		UID:         uid,
    26  		GID:         gid,
    27  		Permissions: perms,
    28  		ATime:       atime,
    29  		MTime:       mtime,
    30  		ExtendedAttributes: []ExtendedAttribute{
    31  			extAttr,
    32  		},
    33  	}
    34  
    35  	type test struct {
    36  		name    string
    37  		flags   uint32
    38  		encoded []byte
    39  	}
    40  
    41  	tests := []test{
    42  		{
    43  			name: "empty",
    44  			encoded: []byte{
    45  				0x00, 0x00, 0x00, 0x00,
    46  			},
    47  		},
    48  		{
    49  			name:  "size",
    50  			flags: AttrSize,
    51  			encoded: []byte{
    52  				0x00, 0x00, 0x00, 0x01,
    53  				0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0,
    54  			},
    55  		},
    56  		{
    57  			name:  "uidgid",
    58  			flags: AttrUIDGID,
    59  			encoded: []byte{
    60  				0x00, 0x00, 0x00, 0x02,
    61  				0x00, 0x00, 0x03, 0xE8,
    62  				0x00, 0x00, 0x00, 100,
    63  			},
    64  		},
    65  		{
    66  			name:  "permissions",
    67  			flags: AttrPermissions,
    68  			encoded: []byte{
    69  				0x00, 0x00, 0x00, 0x04,
    70  				0x87, 0x65, 0x43, 0x21,
    71  			},
    72  		},
    73  		{
    74  			name:  "acmodtime",
    75  			flags: AttrACModTime,
    76  			encoded: []byte{
    77  				0x00, 0x00, 0x00, 0x08,
    78  				0x2A, 0x2B, 0x2C, 0x2D,
    79  				0x42, 0x43, 0x44, 0x45,
    80  			},
    81  		},
    82  		{
    83  			name:  "extended",
    84  			flags: AttrExtended,
    85  			encoded: []byte{
    86  				0x80, 0x00, 0x00, 0x00,
    87  				0x00, 0x00, 0x00, 0x01,
    88  				0x00, 0x00, 0x00, 0x03, 'f', 'o', 'o',
    89  				0x00, 0x00, 0x00, 0x03, 'b', 'a', 'r',
    90  			},
    91  		},
    92  		{
    93  			name:  "size uidgid permisssions acmodtime extended",
    94  			flags: AttrSize | AttrUIDGID | AttrPermissions | AttrACModTime | AttrExtended,
    95  			encoded: []byte{
    96  				0x80, 0x00, 0x00, 0x0F,
    97  				0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0,
    98  				0x00, 0x00, 0x03, 0xE8,
    99  				0x00, 0x00, 0x00, 100,
   100  				0x87, 0x65, 0x43, 0x21,
   101  				0x2A, 0x2B, 0x2C, 0x2D,
   102  				0x42, 0x43, 0x44, 0x45,
   103  				0x00, 0x00, 0x00, 0x01,
   104  				0x00, 0x00, 0x00, 0x03, 'f', 'o', 'o',
   105  				0x00, 0x00, 0x00, 0x03, 'b', 'a', 'r',
   106  			},
   107  		},
   108  	}
   109  
   110  	for _, tt := range tests {
   111  		attr := *attr
   112  
   113  		t.Run(tt.name, func(t *testing.T) {
   114  			attr.Flags = tt.flags
   115  
   116  			buf, err := attr.MarshalBinary()
   117  			if err != nil {
   118  				t.Fatal("unexpected error:", err)
   119  			}
   120  
   121  			if !bytes.Equal(buf, tt.encoded) {
   122  				t.Fatalf("MarshalBinary() = %X, but wanted %X", buf, tt.encoded)
   123  			}
   124  
   125  			attr = Attributes{}
   126  
   127  			if err := attr.UnmarshalBinary(buf); err != nil {
   128  				t.Fatal("unexpected error:", err)
   129  			}
   130  
   131  			if attr.Flags != tt.flags {
   132  				t.Errorf("UnmarshalBinary(): Flags was %x, but wanted %x", attr.Flags, tt.flags)
   133  			}
   134  
   135  			if attr.Flags&AttrSize != 0 && attr.Size != size {
   136  				t.Errorf("UnmarshalBinary(): Size was %x, but wanted %x", attr.Size, size)
   137  			}
   138  
   139  			if attr.Flags&AttrUIDGID != 0 {
   140  				if attr.UID != uid {
   141  					t.Errorf("UnmarshalBinary(): UID was %x, but wanted %x", attr.UID, uid)
   142  				}
   143  
   144  				if attr.GID != gid {
   145  					t.Errorf("UnmarshalBinary(): GID was %x, but wanted %x", attr.GID, gid)
   146  				}
   147  			}
   148  
   149  			if attr.Flags&AttrPermissions != 0 && attr.Permissions != perms {
   150  				t.Errorf("UnmarshalBinary(): Permissions was %#v, but wanted %#v", attr.Permissions, perms)
   151  			}
   152  
   153  			if attr.Flags&AttrACModTime != 0 {
   154  				if attr.ATime != atime {
   155  					t.Errorf("UnmarshalBinary(): ATime was %x, but wanted %x", attr.ATime, atime)
   156  				}
   157  
   158  				if attr.MTime != mtime {
   159  					t.Errorf("UnmarshalBinary(): MTime was %x, but wanted %x", attr.MTime, mtime)
   160  				}
   161  			}
   162  
   163  			if attr.Flags&AttrExtended != 0 {
   164  				extAttrs := attr.ExtendedAttributes
   165  
   166  				if count := len(extAttrs); count != 1 {
   167  					t.Fatalf("UnmarshalBinary(): len(ExtendedAttributes) was %d, but wanted %d", count, 1)
   168  				}
   169  
   170  				if got := extAttrs[0]; got != extAttr {
   171  					t.Errorf("UnmarshalBinary(): ExtendedAttributes[0] was %#v, but wanted %#v", got, extAttr)
   172  				}
   173  			}
   174  		})
   175  	}
   176  }
   177  
   178  func TestNameEntry(t *testing.T) {
   179  	const (
   180  		filename          = "foo"
   181  		longname          = "bar"
   182  		perms    FileMode = 0x87654321
   183  	)
   184  
   185  	e := &NameEntry{
   186  		Filename: filename,
   187  		Longname: longname,
   188  		Attrs: Attributes{
   189  			Flags:       AttrPermissions,
   190  			Permissions: perms,
   191  		},
   192  	}
   193  
   194  	buf, err := e.MarshalBinary()
   195  	if err != nil {
   196  		t.Fatal("unexpected error:", err)
   197  	}
   198  
   199  	want := []byte{
   200  		0x00, 0x00, 0x00, 0x03, 'f', 'o', 'o',
   201  		0x00, 0x00, 0x00, 0x03, 'b', 'a', 'r',
   202  		0x00, 0x00, 0x00, 0x04,
   203  		0x87, 0x65, 0x43, 0x21,
   204  	}
   205  
   206  	if !bytes.Equal(buf, want) {
   207  		t.Fatalf("MarshalBinary() = %X, but wanted %X", buf, want)
   208  	}
   209  
   210  	*e = NameEntry{}
   211  
   212  	if err := e.UnmarshalBinary(buf); err != nil {
   213  		t.Fatal("unexpected error:", err)
   214  	}
   215  
   216  	if e.Filename != filename {
   217  		t.Errorf("UnmarhsalFrom(): Filename was %q, but expected %q", e.Filename, filename)
   218  	}
   219  
   220  	if e.Longname != longname {
   221  		t.Errorf("UnmarhsalFrom(): Longname was %q, but expected %q", e.Longname, longname)
   222  	}
   223  
   224  	if e.Attrs.Flags != AttrPermissions {
   225  		t.Errorf("UnmarshalBinary(): Attrs.Flag was %#x, but expected %#x", e.Attrs.Flags, AttrPermissions)
   226  	}
   227  
   228  	if e.Attrs.Permissions != perms {
   229  		t.Errorf("UnmarshalBinary(): Attrs.Permissions was %#v, but expected %#v", e.Attrs.Permissions, perms)
   230  	}
   231  }