1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
package failover
import (
"context"
"errors"
"io"
"testing"
"time"
"herkulessi.de/git/eduvpn-common/internal/test"
)
// mockedPinger is a ping sender that always returns nil for sending
// but returns EOF for reading
type mockedPinger struct {
cleanRead bool
}
func (mp *mockedPinger) Read(_ time.Time) error {
if mp.cleanRead {
return nil
}
return io.EOF
}
func (mp *mockedPinger) Send(_ int) error {
return nil
}
func TestMonitor(t *testing.T) {
cases := []struct {
interval time.Duration
pDropped int
readRxBytes func() (int64, error)
gateway string
mtuSize int
disableDefaults bool
mockedPinger func(gateway string, mtu int) (sender, error)
wantDropped bool
wantErr string
}{
{
mtuSize: 1,
wantDropped: false,
wantErr: "invalid MTU size given, MTU has to be at least: 28 bytes",
},
{
readRxBytes: func() (int64, error) {
return 0, errors.New("error test")
},
mockedPinger: func(_ string, _ int) (sender, error) {
return &mockedPinger{}, nil
},
wantDropped: false,
wantErr: "error test",
},
// default case, not dropped
{
mockedPinger: func(_ string, _ int) (sender, error) {
return &mockedPinger{}, nil
},
},
// default case where it could read a ping response, and read rx bytes always returns 0
// should be not dropped
{
readRxBytes: func() (int64, error) {
return 0, nil
},
mockedPinger: func(_ string, _ int) (sender, error) {
return &mockedPinger{cleanRead: true}, nil
},
},
// readRxBytes always returns 0
// we want dropped as the mock pinger does nothing
{
readRxBytes: func() (int64, error) {
return 0, nil
},
gateway: "127.0.0.1",
mockedPinger: func(_ string, _ int) (sender, error) {
return &mockedPinger{}, nil
},
wantDropped: true,
},
}
for _, c := range cases {
var counter int64
// some defaults
if c.interval == 0 {
c.interval = 2 * time.Millisecond
}
if c.pDropped == 0 {
c.pDropped = 5
}
if c.gateway == "" {
c.gateway = "127.0.0.1"
}
if c.mtuSize == 0 {
c.mtuSize = 28
}
if c.readRxBytes == nil {
c.readRxBytes = func() (int64, error) {
defer func() {
counter++
}()
return counter, nil
}
}
dcm := NewDroppedMonitor(c.interval, c.pDropped, c.readRxBytes)
if c.mockedPinger != nil {
dcm.newPinger = c.mockedPinger
}
dropped, err := dcm.Start(context.Background(), c.gateway, c.mtuSize)
if dropped != c.wantDropped {
t.Fatalf("dropped is not equal to want dropped, got: %v, want: %v", dropped, c.wantDropped)
}
test.AssertError(t, err, c.wantErr)
}
}
|