1package openssh
2
3import (
4	"bytes"
5	"testing"
6
7	sshfx "github.com/pkg/sftp/internal/encoding/ssh/filexfer"
8)
9
10var _ sshfx.PacketMarshaller = &StatVFSExtendedPacket{}
11
12func init() {
13	RegisterExtensionStatVFS()
14}
15
16func TestStatVFSExtendedPacket(t *testing.T) {
17	const (
18		id   = 42
19		path = "/foo"
20	)
21
22	ep := &StatVFSExtendedPacket{
23		Path: path,
24	}
25
26	data, err := sshfx.ComposePacket(ep.MarshalPacket(id, nil))
27	if err != nil {
28		t.Fatal("unexpected error:", err)
29	}
30
31	want := []byte{
32		0x00, 0x00, 0x00, 36,
33		200,
34		0x00, 0x00, 0x00, 42,
35		0x00, 0x00, 0x00, 19, 's', 't', 'a', 't', 'v', 'f', 's', '@', 'o', 'p', 'e', 'n', 's', 's', 'h', '.', 'c', 'o', 'm',
36		0x00, 0x00, 0x00, 4, '/', 'f', 'o', 'o',
37	}
38
39	if !bytes.Equal(data, want) {
40		t.Fatalf("MarshalPacket() = %X, but wanted %X", data, want)
41	}
42
43	var p sshfx.ExtendedPacket
44
45	// UnmarshalPacketBody assumes the (length, type, request-id) have already been consumed.
46	if err := p.UnmarshalPacketBody(sshfx.NewBuffer(data[9:])); err != nil {
47		t.Fatal("unexpected error:", err)
48	}
49
50	if p.ExtendedRequest != extensionStatVFS {
51		t.Errorf("UnmarshalPacketBody(): ExtendedRequest was %q, but expected %q", p.ExtendedRequest, extensionStatVFS)
52	}
53
54	ep, ok := p.Data.(*StatVFSExtendedPacket)
55	if !ok {
56		t.Fatalf("UnmarshaledPacketBody(): Data was type %T, but expected *StatVFSExtendedPacket", p.Data)
57	}
58
59	if ep.Path != path {
60		t.Errorf("UnmarshalPacketBody(): Path was %q, but expected %q", ep.Path, path)
61	}
62}
63
64var _ sshfx.PacketMarshaller = &FStatVFSExtendedPacket{}
65
66func init() {
67	RegisterExtensionFStatVFS()
68}
69
70func TestFStatVFSExtendedPacket(t *testing.T) {
71	const (
72		id   = 42
73		path = "/foo"
74	)
75
76	ep := &FStatVFSExtendedPacket{
77		Path: path,
78	}
79
80	data, err := sshfx.ComposePacket(ep.MarshalPacket(id, nil))
81	if err != nil {
82		t.Fatal("unexpected error:", err)
83	}
84
85	want := []byte{
86		0x00, 0x00, 0x00, 37,
87		200,
88		0x00, 0x00, 0x00, 42,
89		0x00, 0x00, 0x00, 20, 'f', 's', 't', 'a', 't', 'v', 'f', 's', '@', 'o', 'p', 'e', 'n', 's', 's', 'h', '.', 'c', 'o', 'm',
90		0x00, 0x00, 0x00, 4, '/', 'f', 'o', 'o',
91	}
92
93	if !bytes.Equal(data, want) {
94		t.Fatalf("MarshalPacket() = %X, but wanted %X", data, want)
95	}
96
97	var p sshfx.ExtendedPacket
98
99	// UnmarshalPacketBody assumes the (length, type, request-id) have already been consumed.
100	if err := p.UnmarshalPacketBody(sshfx.NewBuffer(data[9:])); err != nil {
101		t.Fatal("unexpected error:", err)
102	}
103
104	if p.ExtendedRequest != extensionFStatVFS {
105		t.Errorf("UnmarshalPacketBody(): ExtendedRequest was %q, but expected %q", p.ExtendedRequest, extensionFStatVFS)
106	}
107
108	ep, ok := p.Data.(*FStatVFSExtendedPacket)
109	if !ok {
110		t.Fatalf("UnmarshaledPacketBody(): Data was type %T, but expected *FStatVFSExtendedPacket", p.Data)
111	}
112
113	if ep.Path != path {
114		t.Errorf("UnmarshalPacketBody(): Path was %q, but expected %q", ep.Path, path)
115	}
116}
117
118var _ sshfx.Packet = &StatVFSExtendedReplyPacket{}
119
120func TestStatVFSExtendedReplyPacket(t *testing.T) {
121	const (
122		id   = 42
123		path = "/foo"
124	)
125
126	const (
127		BlockSize = uint64(iota + 13)
128		FragmentSize
129		Blocks
130		BlocksFree
131		BlocksAvail
132		Files
133		FilesFree
134		FilesAvail
135		FilesystemID
136		MountFlags
137		MaxNameLength
138	)
139
140	ep := &StatVFSExtendedReplyPacket{
141		BlockSize:     BlockSize,
142		FragmentSize:  FragmentSize,
143		Blocks:        Blocks,
144		BlocksFree:    BlocksFree,
145		BlocksAvail:   BlocksAvail,
146		Files:         Files,
147		FilesFree:     FilesFree,
148		FilesAvail:    FilesAvail,
149		FilesystemID:  FilesystemID,
150		MountFlags:    MountFlags,
151		MaxNameLength: MaxNameLength,
152	}
153
154	data, err := sshfx.ComposePacket(ep.MarshalPacket(id, nil))
155	if err != nil {
156		t.Fatal("unexpected error:", err)
157	}
158
159	want := []byte{
160		0x00, 0x00, 0x00, 93,
161		201,
162		0x00, 0x00, 0x00, 42,
163		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 13,
164		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 14,
165		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 15,
166		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 16,
167		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 17,
168		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 18,
169		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 19,
170		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 20,
171		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 21,
172		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 22,
173		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 23,
174	}
175
176	if !bytes.Equal(data, want) {
177		t.Fatalf("MarshalPacket() = %X, but wanted %X", data, want)
178	}
179
180	*ep = StatVFSExtendedReplyPacket{}
181
182	p := sshfx.ExtendedReplyPacket{
183		Data: ep,
184	}
185
186	// UnmarshalPacketBody assumes the (length, type, request-id) have already been consumed.
187	if err := p.UnmarshalPacketBody(sshfx.NewBuffer(data[9:])); err != nil {
188		t.Fatal("unexpected error:", err)
189	}
190
191	ep, ok := p.Data.(*StatVFSExtendedReplyPacket)
192	if !ok {
193		t.Fatalf("UnmarshaledPacketBody(): Data was type %T, but expected *StatVFSExtendedReplyPacket", p.Data)
194	}
195
196	if ep.BlockSize != BlockSize {
197		t.Errorf("UnmarshalPacketBody(): BlockSize was %d, but expected %d", ep.BlockSize, BlockSize)
198	}
199
200	if ep.FragmentSize != FragmentSize {
201		t.Errorf("UnmarshalPacketBody(): FragmentSize was %d, but expected %d", ep.FragmentSize, FragmentSize)
202	}
203
204	if ep.Blocks != Blocks {
205		t.Errorf("UnmarshalPacketBody(): Blocks was %d, but expected %d", ep.Blocks, Blocks)
206	}
207
208	if ep.BlocksFree != BlocksFree {
209		t.Errorf("UnmarshalPacketBody(): BlocksFree was %d, but expected %d", ep.BlocksFree, BlocksFree)
210	}
211
212	if ep.BlocksAvail != BlocksAvail {
213		t.Errorf("UnmarshalPacketBody(): BlocksAvail was %d, but expected %d", ep.BlocksAvail, BlocksAvail)
214	}
215
216	if ep.Files != Files {
217		t.Errorf("UnmarshalPacketBody(): Files was %d, but expected %d", ep.Files, Files)
218	}
219
220	if ep.FilesFree != FilesFree {
221		t.Errorf("UnmarshalPacketBody(): FilesFree was %d, but expected %d", ep.FilesFree, FilesFree)
222	}
223
224	if ep.FilesAvail != FilesAvail {
225		t.Errorf("UnmarshalPacketBody(): FilesAvail was %d, but expected %d", ep.FilesAvail, FilesAvail)
226	}
227
228	if ep.FilesystemID != FilesystemID {
229		t.Errorf("UnmarshalPacketBody(): FilesystemID was %d, but expected %d", ep.FilesystemID, FilesystemID)
230	}
231
232	if ep.MountFlags != MountFlags {
233		t.Errorf("UnmarshalPacketBody(): MountFlags was %d, but expected %d", ep.MountFlags, MountFlags)
234	}
235
236	if ep.MaxNameLength != MaxNameLength {
237		t.Errorf("UnmarshalPacketBody(): MaxNameLength was %d, but expected %d", ep.MaxNameLength, MaxNameLength)
238	}
239}
240