Newer
Older
package server
import (
"bytes"
"fmt"
"testing"
"github.com/bio-routing/bio-rd/protocols/isis/packet"
"github.com/bio-routing/bio-rd/protocols/isis/types"
btesting "github.com/bio-routing/bio-rd/testing"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)
type mockDev struct {
wantFailProcessP2PHello bool
wantFailProcessIngressPacket bool
wantFailProcessLSPDU bool
wantFailProcessCSNP bool
wantFailProcessPSNP bool
callCountProcessP2PHello int
callCountProcessIngressPacket int
callCountProcessLSPDU int
callCountProcessCSNP int
callCountProcessPSNP int
}
func newMockDev() *mockDev {
return &mockDev{}
}
func (md *mockDev) receiverRoutine() {
md.callCountReceiverRoutine++
}
func (md *mockDev) helloRoutine() {
md.callCountHelloRoutine++
}
func (md *mockDev) processP2PHello(*packet.P2PHello, types.MACAddress) error {
md.callCountProcessP2PHello++
if md.wantFailProcessP2PHello {
return fmt.Errorf("processP2PHello failed")
}
return nil
}
func (md *mockDev) processIngressPacket() error {
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
md.callCountProcessIngressPacket++
if md.wantFailProcessIngressPacket {
return fmt.Errorf("processIngressPacket failed")
}
return nil
}
func (md *mockDev) processLSPDU(l *packet.LSPDU, srv types.MACAddress) error {
md.callCountProcessLSPDU++
if md.wantFailProcessLSPDU {
return fmt.Errorf("processLSPDU failed")
}
return nil
}
func (md *mockDev) processCSNP(l *packet.CSNP, srv types.MACAddress) error {
md.callCountProcessCSNP++
if md.wantFailProcessCSNP {
return fmt.Errorf("ProcessCSNP failed")
}
return nil
}
func (md *mockDev) processPSNP(l *packet.PSNP, srv types.MACAddress) error {
md.callCountProcessPSNP++
if md.wantFailProcessPSNP {
return fmt.Errorf("ProcessPSNP failed")
}
return nil
}
func TestReceiverRoutine(t *testing.T) {
tests := []struct {
name string
dev *dev
dev: &dev{
name: "eth0",
srv: &Server{
log: log.New(),
},
self: &mockDev{
wantFailProcessIngressPacket: true,
expected: "level=error msg=\"processIngressPacket failed\"",
dev: &dev{
name: "eth0",
srv: &Server{
log: log.New(),
},
self: &mockDev{},
},
},
}
for _, test := range tests {
test.dev.srv.log.Out = bytes.NewBuffer([]byte{})
test.dev.srv.log.Formatter = btesting.NewLogFormatter()
test.dev.wg.Add(1)
if test.stopped {
close(test.dev.done)
}
go test.dev.receiverRoutine()
test.dev.wg.Wait()
assert.Equal(t, test.expected, string(test.dev.srv.log.Out.(*bytes.Buffer).Bytes()), test.name)
}
}
func TestProcessIngressPacket(t *testing.T) {
tests := []struct {
name string
dev *dev
mockDev *mockDev
wantFail bool
expectedErr string
expected *mockDev
}{
{
name: "Recv Fail",
dev: &dev{
name: "eth0",
sys: &mockSys{
wantFailRecvPacket: true,
},
},
mockDev: &mockDev{},
wantFail: true,
expectedErr: "receiving packet failed: Fail",
expected: &mockDev{},
},
name: "Decode Fail",
dev: &dev{
name: "eth0",
sys: &mockSys{
recvPktPkt: []byte{
// LLC
0xfe, // DSAP
0xfe, // SSAP
0x03, // Control Fields
// Header
0x83,
20,
1,
0,
17, // PDU Type P2P Hello
1,
},
},
wantFail: true,
expectedErr: "Unable to decode packet from [10 20 30 40 50 60] on eth0: [254 254 3 131 20 1 0 17 1]: Unable to decode header: Unable to decode fields: Unable to read from buffer: EOF",
expected: &mockDev{},
},
{
name: "Invalid P2P Hello",
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
dev: &dev{
name: "eth0",
sys: &mockSys{
recvPktPkt: []byte{
// LLC
0xfe, // DSAP
0xfe, // SSAP
0x03, // Control Fields
// Header
0x83,
20,
1,
0,
17, // PDU Type P2P Hello
1,
0,
0,
// P2P Hello
02,
0, 0, 0, 0, 0, 2,
0, 27,
0, 50,
1,
//TLVs
240, 5, 0x02, 0x00, 0x00, 0x01, 0x4b,
129, 2, 0xcc, 0x8e,
132, 4, 192, 168, 1, 0,
1, 6, 0x05, 0x49, 0x00, 0x01, 0x00, 0x10,
211, 3, 0, 0, 0,
},
},
},
mockDev: &mockDev{
wantFailProcessP2PHello: true,
},
wantFail: true,
expected: &mockDev{
wantFailProcessP2PHello: true,
callCountProcessP2PHello: 1,
},
expectedErr: "Unable to process P2P Hello: processP2PHello failed",
},
{
name: "LSPDU fail",
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
dev: &dev{
name: "eth0",
sys: &mockSys{
recvPktPkt: []byte{
// LLC
0xfe, // DSAP
0xfe, // SSAP
0x03, // Control Fields
// Header
0x83,
20,
1,
0,
0x14, // PDU Type L2 LSPDU
1,
0,
0,
0, 30, // Length
0, 200, // Lifetime
10, 20, 30, 40, 50, 60, 0, 10, // LSPID
0, 0, 1, 0, // Sequence Number
0, 0, // Checksum
3, // Typeblock
137, 5, 1, 2, 3, 4, 5, // Hostname TLV
12, 2, 0, 2, // Checksum TLV
// P2P Hello
02,
0, 0, 0, 0, 0, 2,
0, 27,
0, 50,
1,
//TLVs
240, 5, 0x02, 0x00, 0x00, 0x01, 0x4b,
129, 2, 0xcc, 0x8e,
132, 4, 192, 168, 1, 0,
1, 6, 0x05, 0x49, 0x00, 0x01, 0x00, 0x10,
211, 3, 0, 0, 0,
},
},
},
mockDev: &mockDev{
wantFailProcessLSPDU: true,
},
wantFail: true,
expected: &mockDev{
wantFailProcessLSPDU: true,
callCountProcessLSPDU: 1,
},
expectedErr: "Unable to process LSPDU: processLSPDU failed",
},
{
name: "CSNP fail",
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
dev: &dev{
name: "eth0",
sys: &mockSys{
recvPktPkt: []byte{
// LLC
0xfe, // DSAP
0xfe, // SSAP
0x03, // Control Fields
// Header
0x83,
20,
1,
0,
0x19, // PDU Type L2 CSNP
1,
0,
0,
0, 41, // PDU Length
10, 20, 30, 40, 50, 60, 0, // Source ID
11, 22, 33, 44, 55, 66, 0, 100, // StartLSPID
11, 22, 33, 77, 88, 99, 0, 200, // EndLSPID
9, // TLV Type
16, // TLV Length
1, 0, // Remaining Lifetime
11, 22, 33, 44, 55, 66, // SystemID
0, 20, // Pseudonode ID
0, 0, 0, 20, // Sequence Number
2, 0, // Checksum
},
},
},
mockDev: &mockDev{
wantFailProcessCSNP: true,
},
wantFail: true,
expected: &mockDev{
wantFailProcessCSNP: true,
callCountProcessCSNP: 1,
},
expectedErr: "Unable to process CSNP: ProcessCSNP failed",
},
{
name: "PSNP fail",
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
dev: &dev{
name: "eth0",
sys: &mockSys{
recvPktPkt: []byte{
// LLC
0xfe, // DSAP
0xfe, // SSAP
0x03, // Control Fields
// Header
0x83,
20,
1,
0,
0x1b, // PDU Type L2 PSNP
1,
0,
0,
0, 33, // Length
10, 20, 30, 40, 50, 60, 0, // Source ID
1, 0, // Remaining Lifetime
11, 22, 33, 44, 55, 66, // SystemID
0, // Pseudonode ID
20, // LSPNumber
0, 0, 0, 20, // Sequence Number
2, 0, // Checksum
},
},
},
mockDev: &mockDev{
wantFailProcessPSNP: true,
},
wantFail: true,
expected: &mockDev{
wantFailProcessPSNP: true,
callCountProcessPSNP: 1,
},
expectedErr: "Unable to process PSNP: ProcessPSNP failed",
},
{
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
name: "PSNP Ok",
dev: &dev{
name: "eth0",
sys: &mockSys{
recvPktPkt: []byte{
// LLC
0xfe, // DSAP
0xfe, // SSAP
0x03, // Control Fields
// Header
0x83,
20,
1,
0,
0x1b, // PDU Type L2 PSNP
1,
0,
0,
0, 33, // Length
10, 20, 30, 40, 50, 60, 0, // Source ID
1, 0, // Remaining Lifetime
11, 22, 33, 44, 55, 66, // SystemID
0, // Pseudonode ID
20, // LSPNumber
0, 0, 0, 20, // Sequence Number
2, 0, // Checksum
},
},
wantFail: false,
expected: &mockDev{
callCountProcessPSNP: 1,
},
},
}
for _, test := range tests {
test.dev.self = test.mockDev
if err != nil && !test.wantFail {
t.Errorf("Unexpected failure for test %q", test.name)
continue
}
if test.wantFail && err == nil {
t.Errorf("Unexpected success for test %q", test.name)
continue
}
if err != nil {
assert.Equal(t, test.expectedErr, err.Error(), test.name)
}
assert.Equal(t, test.expected, test.dev.self, test.name)
}
}