]>
Commit | Line | Data |
---|---|---|
6988a057 JH |
1 | package hotline |
2 | ||
3 | import ( | |
3178ae58 | 4 | "fmt" |
6988a057 JH |
5 | "github.com/stretchr/testify/assert" |
6 | "testing" | |
7 | ) | |
8 | ||
9 | func TestReadFields(t *testing.T) { | |
10 | type args struct { | |
11 | paramCount []byte | |
12 | buf []byte | |
13 | } | |
14 | tests := []struct { | |
15 | name string | |
16 | args args | |
17 | want []Field | |
18 | wantErr bool | |
19 | }{ | |
20 | { | |
21 | name: "valid field data", | |
22 | args: args{ | |
23 | paramCount: []byte{0x00, 0x02}, | |
24 | buf: []byte{ | |
d005ef04 | 25 | 0x00, 0x65, // ID: FieldData |
6988a057 JH |
26 | 0x00, 0x04, // Size: 2 bytes |
27 | 0x01, 0x02, 0x03, 0x04, // Data | |
d005ef04 | 28 | 0x00, 0x66, // ID: FieldUserName |
6988a057 JH |
29 | 0x00, 0x02, // Size: 2 bytes |
30 | 0x00, 0x01, // Data | |
31 | }, | |
32 | }, | |
33 | want: []Field{ | |
34 | { | |
95159e55 JH |
35 | ID: [2]byte{0x00, 0x65}, |
36 | FieldSize: [2]byte{0x00, 0x04}, | |
6988a057 JH |
37 | Data: []byte{0x01, 0x02, 0x03, 0x04}, |
38 | }, | |
39 | { | |
95159e55 JH |
40 | ID: [2]byte{0x00, 0x66}, |
41 | FieldSize: [2]byte{0x00, 0x02}, | |
6988a057 JH |
42 | Data: []byte{0x00, 0x01}, |
43 | }, | |
44 | }, | |
45 | wantErr: false, | |
46 | }, | |
47 | { | |
48 | name: "empty bytes", | |
49 | args: args{ | |
50 | paramCount: []byte{0x00, 0x00}, | |
51 | buf: []byte{}, | |
52 | }, | |
53 | want: []Field(nil), | |
54 | wantErr: false, | |
55 | }, | |
56 | { | |
57 | name: "when field size does not match data length", | |
58 | args: args{ | |
59 | paramCount: []byte{0x00, 0x01}, | |
60 | buf: []byte{ | |
d005ef04 | 61 | 0x00, 0x65, // ID: FieldData |
6988a057 JH |
62 | 0x00, 0x04, // Size: 4 bytes |
63 | 0x01, 0x02, 0x03, // Data | |
64 | }, | |
65 | }, | |
66 | want: []Field{}, | |
67 | wantErr: true, | |
68 | }, | |
69 | { | |
70 | name: "when field size of second field does not match data length", | |
71 | args: args{ | |
72 | paramCount: []byte{0x00, 0x01}, | |
73 | buf: []byte{ | |
d005ef04 | 74 | 0x00, 0x65, // ID: FieldData |
6988a057 JH |
75 | 0x00, 0x02, // Size: 2 bytes |
76 | 0x01, 0x02, // Data | |
d005ef04 | 77 | 0x00, 0x65, // ID: FieldData |
6988a057 JH |
78 | 0x00, 0x04, // Size: 4 bytes |
79 | 0x01, 0x02, 0x03, // Data | |
80 | }, | |
81 | }, | |
82 | want: []Field{}, | |
83 | wantErr: true, | |
84 | }, | |
85 | { | |
86 | name: "when field data has extra bytes", | |
87 | args: args{ | |
88 | paramCount: []byte{0x00, 0x01}, | |
89 | buf: []byte{ | |
d005ef04 | 90 | 0x00, 0x65, // ID: FieldData |
6988a057 JH |
91 | 0x00, 0x02, // Size: 2 bytes |
92 | 0x01, 0x02, 0x03, // Data | |
93 | }, | |
94 | }, | |
95 | want: []Field{}, | |
96 | wantErr: true, | |
97 | }, | |
98 | } | |
99 | for _, tt := range tests { | |
100 | t.Run(tt.name, func(t *testing.T) { | |
101 | got, err := ReadFields(tt.args.paramCount, tt.args.buf) | |
102 | if (err != nil) != tt.wantErr { | |
103 | t.Errorf("ReadFields() error = %v, wantErr %v", err, tt.wantErr) | |
104 | return | |
105 | } | |
106 | ||
107 | if !assert.Equal(t, tt.want, got) { | |
108 | t.Errorf("ReadFields() got = %v, want %v", got, tt.want) | |
109 | } | |
110 | }) | |
111 | } | |
112 | } | |
113 | ||
3178ae58 JH |
114 | func Test_transactionScanner(t *testing.T) { |
115 | type args struct { | |
116 | data []byte | |
117 | in1 bool | |
118 | } | |
119 | tests := []struct { | |
120 | name string | |
121 | args args | |
122 | wantAdvance int | |
123 | wantToken []byte | |
124 | wantErr assert.ErrorAssertionFunc | |
125 | }{ | |
126 | { | |
127 | name: "when too few bytes are provided to read the transaction size", | |
128 | args: args{ | |
129 | data: []byte{}, | |
130 | in1: false, | |
131 | }, | |
132 | wantAdvance: 0, | |
133 | wantToken: []byte(nil), | |
134 | wantErr: assert.NoError, | |
135 | }, | |
136 | { | |
137 | name: "when too few bytes are provided to read the full payload", | |
138 | args: args{ | |
139 | data: []byte{ | |
140 | 0, | |
141 | 1, | |
142 | 0, 0, | |
143 | 0, 00, 00, 04, | |
144 | 00, 00, 00, 00, | |
145 | 00, 00, 00, 10, | |
146 | 00, 00, 00, 10, | |
147 | }, | |
148 | in1: false, | |
149 | }, | |
150 | wantAdvance: 0, | |
151 | wantToken: []byte(nil), | |
152 | wantErr: assert.NoError, | |
153 | }, | |
154 | { | |
155 | name: "when a full transaction is provided", | |
156 | args: args{ | |
157 | data: []byte{ | |
158 | 0, | |
159 | 1, | |
160 | 0, 0, | |
161 | 0, 00, 00, 0x04, | |
162 | 00, 00, 00, 0x00, | |
163 | 00, 00, 00, 0x10, | |
164 | 00, 00, 00, 0x10, | |
165 | 00, 02, | |
d005ef04 | 166 | 00, 0x6c, // 108 - FieldTransferSize |
3178ae58 JH |
167 | 00, 02, |
168 | 0x63, 0x3b, | |
d005ef04 | 169 | 00, 0x6b, // 107 = FieldRefNum |
3178ae58 JH |
170 | 00, 0x04, |
171 | 00, 0x02, 0x93, 0x47, | |
172 | }, | |
173 | in1: false, | |
174 | }, | |
175 | wantAdvance: 36, | |
176 | wantToken: []byte{ | |
177 | 0, | |
178 | 1, | |
179 | 0, 0, | |
180 | 0, 00, 00, 0x04, | |
181 | 00, 00, 00, 0x00, | |
182 | 00, 00, 00, 0x10, | |
183 | 00, 00, 00, 0x10, | |
184 | 00, 02, | |
d005ef04 | 185 | 00, 0x6c, // 108 - FieldTransferSize |
3178ae58 JH |
186 | 00, 02, |
187 | 0x63, 0x3b, | |
d005ef04 | 188 | 00, 0x6b, // 107 = FieldRefNum |
3178ae58 JH |
189 | 00, 0x04, |
190 | 00, 0x02, 0x93, 0x47, | |
191 | }, | |
192 | wantErr: assert.NoError, | |
193 | }, | |
194 | { | |
195 | name: "when a full transaction plus extra bytes are provided", | |
196 | args: args{ | |
197 | data: []byte{ | |
198 | 0, | |
199 | 1, | |
200 | 0, 0, | |
201 | 0, 00, 00, 0x04, | |
202 | 00, 00, 00, 0x00, | |
203 | 00, 00, 00, 0x10, | |
204 | 00, 00, 00, 0x10, | |
205 | 00, 02, | |
d005ef04 | 206 | 00, 0x6c, // 108 - FieldTransferSize |
3178ae58 JH |
207 | 00, 02, |
208 | 0x63, 0x3b, | |
d005ef04 | 209 | 00, 0x6b, // 107 = FieldRefNum |
3178ae58 JH |
210 | 00, 0x04, |
211 | 00, 0x02, 0x93, 0x47, | |
212 | 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
213 | }, | |
214 | in1: false, | |
215 | }, | |
216 | wantAdvance: 36, | |
217 | wantToken: []byte{ | |
218 | 0, | |
219 | 1, | |
220 | 0, 0, | |
221 | 0, 00, 00, 0x04, | |
222 | 00, 00, 00, 0x00, | |
223 | 00, 00, 00, 0x10, | |
224 | 00, 00, 00, 0x10, | |
225 | 00, 02, | |
d005ef04 | 226 | 00, 0x6c, // 108 - FieldTransferSize |
3178ae58 JH |
227 | 00, 02, |
228 | 0x63, 0x3b, | |
d005ef04 | 229 | 00, 0x6b, // 107 = FieldRefNum |
3178ae58 JH |
230 | 00, 0x04, |
231 | 00, 0x02, 0x93, 0x47, | |
232 | }, | |
233 | wantErr: assert.NoError, | |
234 | }, | |
235 | { | |
236 | name: "when two full transactions are provided", | |
237 | args: args{ | |
238 | data: []byte{ | |
239 | 0, | |
240 | 1, | |
241 | 0, 0, | |
242 | 0, 00, 00, 0x04, | |
243 | 00, 00, 00, 0x00, | |
244 | 00, 00, 00, 0x10, | |
245 | 00, 00, 00, 0x10, | |
246 | 00, 02, | |
d005ef04 | 247 | 00, 0x6c, // 108 - FieldTransferSize |
3178ae58 JH |
248 | 00, 02, |
249 | 0x63, 0x3b, | |
d005ef04 | 250 | 00, 0x6b, // 107 = FieldRefNum |
3178ae58 JH |
251 | 00, 0x04, |
252 | 00, 0x02, 0x93, 0x47, | |
253 | 0, | |
254 | 1, | |
255 | 0, 0, | |
256 | 0, 00, 00, 0x04, | |
257 | 00, 00, 00, 0x00, | |
258 | 00, 00, 00, 0x10, | |
259 | 00, 00, 00, 0x10, | |
260 | 00, 02, | |
d005ef04 | 261 | 00, 0x6c, // 108 - FieldTransferSize |
3178ae58 JH |
262 | 00, 02, |
263 | 0x63, 0x3b, | |
d005ef04 | 264 | 00, 0x6b, // 107 = FieldRefNum |
3178ae58 JH |
265 | 00, 0x04, |
266 | 00, 0x02, 0x93, 0x47, | |
267 | }, | |
268 | in1: false, | |
269 | }, | |
270 | wantAdvance: 36, | |
271 | wantToken: []byte{ | |
272 | 0, | |
273 | 1, | |
274 | 0, 0, | |
275 | 0, 00, 00, 0x04, | |
276 | 00, 00, 00, 0x00, | |
277 | 00, 00, 00, 0x10, | |
278 | 00, 00, 00, 0x10, | |
279 | 00, 02, | |
d005ef04 | 280 | 00, 0x6c, // 108 - FieldTransferSize |
3178ae58 JH |
281 | 00, 02, |
282 | 0x63, 0x3b, | |
d005ef04 | 283 | 00, 0x6b, // 107 = FieldRefNum |
3178ae58 JH |
284 | 00, 0x04, |
285 | 00, 0x02, 0x93, 0x47, | |
286 | }, | |
287 | wantErr: assert.NoError, | |
288 | }, | |
289 | } | |
290 | for _, tt := range tests { | |
291 | t.Run(tt.name, func(t *testing.T) { | |
292 | gotAdvance, gotToken, err := transactionScanner(tt.args.data, tt.args.in1) | |
293 | if !tt.wantErr(t, err, fmt.Sprintf("transactionScanner(%v, %v)", tt.args.data, tt.args.in1)) { | |
294 | return | |
295 | } | |
296 | assert.Equalf(t, tt.wantAdvance, gotAdvance, "transactionScanner(%v, %v)", tt.args.data, tt.args.in1) | |
297 | assert.Equalf(t, tt.wantToken, gotToken, "transactionScanner(%v, %v)", tt.args.data, tt.args.in1) | |
298 | }) | |
299 | } | |
300 | } | |
854a92fc | 301 | |
95159e55 | 302 | func TestTransaction_Read(t1 *testing.T) { |
854a92fc JH |
303 | type fields struct { |
304 | clientID *[]byte | |
305 | Flags byte | |
306 | IsReply byte | |
307 | Type []byte | |
308 | ID []byte | |
309 | ErrorCode []byte | |
310 | TotalSize []byte | |
311 | DataSize []byte | |
312 | ParamCount []byte | |
313 | Fields []Field | |
95159e55 | 314 | readOffset int |
854a92fc JH |
315 | } |
316 | type args struct { | |
317 | p []byte | |
318 | } | |
319 | tests := []struct { | |
95159e55 JH |
320 | name string |
321 | fields fields | |
322 | args args | |
323 | want int | |
324 | wantErr assert.ErrorAssertionFunc | |
325 | wantBytes []byte | |
854a92fc JH |
326 | }{ |
327 | { | |
95159e55 JH |
328 | name: "returns transaction bytes", |
329 | fields: fields{ | |
330 | Flags: 0x00, | |
331 | IsReply: 0x01, | |
332 | Type: []byte{0, 0}, | |
333 | ID: []byte{0x9a, 0xcb, 0x04, 0x42}, | |
334 | ErrorCode: []byte{0, 0, 0, 0}, | |
335 | Fields: []Field{ | |
336 | NewField(FieldData, []byte("TEST")), | |
337 | }, | |
338 | }, | |
854a92fc | 339 | args: args{ |
95159e55 | 340 | p: make([]byte, 1024), |
854a92fc | 341 | }, |
95159e55 JH |
342 | want: 30, |
343 | wantErr: assert.NoError, | |
344 | wantBytes: []byte{0x0, 0x1, 0x0, 0x0, 0x9a, 0xcb, 0x4, 0x42, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x0, 0x1, 0x0, 0x65, 0x0, 0x4, 0x54, 0x45, 0x53, 0x54}, | |
345 | }, | |
346 | { | |
347 | name: "returns transaction bytes from readOffset", | |
348 | fields: fields{ | |
349 | Flags: 0x00, | |
350 | IsReply: 0x01, | |
351 | Type: []byte{0, 0}, | |
352 | ID: []byte{0x9a, 0xcb, 0x04, 0x42}, | |
353 | ErrorCode: []byte{0, 0, 0, 0}, | |
354 | Fields: []Field{ | |
355 | NewField(FieldData, []byte("TEST")), | |
356 | }, | |
357 | readOffset: 20, | |
358 | }, | |
359 | args: args{ | |
360 | p: make([]byte, 1024), | |
361 | }, | |
362 | want: 10, | |
363 | wantErr: assert.NoError, | |
364 | wantBytes: []byte{0x0, 0x1, 0x0, 0x65, 0x0, 0x4, 0x54, 0x45, 0x53, 0x54}, | |
365 | }, | |
366 | { | |
367 | name: "returns io.EOF when all bytes read", | |
368 | fields: fields{ | |
369 | Flags: 0x00, | |
370 | IsReply: 0x01, | |
371 | Type: []byte{0, 0}, | |
372 | ID: []byte{0x9a, 0xcb, 0x04, 0x42}, | |
373 | ErrorCode: []byte{0, 0, 0, 0}, | |
374 | Fields: []Field{ | |
375 | NewField(FieldData, []byte("TEST")), | |
376 | }, | |
377 | readOffset: 30, | |
378 | }, | |
379 | args: args{ | |
380 | p: make([]byte, 1024), | |
381 | }, | |
382 | want: 0, | |
383 | wantErr: assert.Error, | |
384 | wantBytes: []byte{}, | |
854a92fc JH |
385 | }, |
386 | } | |
387 | for _, tt := range tests { | |
388 | t1.Run(tt.name, func(t1 *testing.T) { | |
389 | t := &Transaction{ | |
390 | clientID: tt.fields.clientID, | |
391 | Flags: tt.fields.Flags, | |
392 | IsReply: tt.fields.IsReply, | |
393 | Type: tt.fields.Type, | |
394 | ID: tt.fields.ID, | |
395 | ErrorCode: tt.fields.ErrorCode, | |
396 | TotalSize: tt.fields.TotalSize, | |
397 | DataSize: tt.fields.DataSize, | |
398 | ParamCount: tt.fields.ParamCount, | |
399 | Fields: tt.fields.Fields, | |
95159e55 | 400 | readOffset: tt.fields.readOffset, |
854a92fc | 401 | } |
95159e55 JH |
402 | got, err := t.Read(tt.args.p) |
403 | if !tt.wantErr(t1, err, fmt.Sprintf("Read(%v)", tt.args.p)) { | |
854a92fc JH |
404 | return |
405 | } | |
95159e55 JH |
406 | assert.Equalf(t1, tt.want, got, "Read(%v)", tt.args.p) |
407 | assert.Equalf(t1, tt.wantBytes, tt.args.p[:got], "Read(%v)", tt.args.p) | |
854a92fc JH |
408 | }) |
409 | } | |
410 | } |