-
Notifications
You must be signed in to change notification settings - Fork 0
/
pinger_test.go
137 lines (122 loc) · 3.46 KB
/
pinger_test.go
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package pinger
import (
"errors"
"log"
"net"
"testing"
"time"
)
func TestPingSuccess(t *testing.T) {
replied, timedOut, spurious, err := test(false, false, false, false)
switch {
case replied:
case timedOut:
t.Errorf("got timeout, expected reply")
case spurious:
t.Errorf("got spurious message, expected timeout")
case err != nil:
t.Errorf("got error %v, expected nil", err)
}
}
func TestPingTimeout(t *testing.T) {
replied, timedOut, spurious, err := test(true, false, false, false)
switch {
case timedOut:
case replied:
t.Errorf("got reply, expected timeout")
case spurious:
t.Errorf("got spurious message, expected timeout")
case err != nil:
t.Errorf("got error %v, expected none", err)
}
}
func TestWriteErrorSendsErrorOnChan(t *testing.T) {
replied, timedOut, spurious, err := test(false, true, false, false)
switch {
case errors.Is(err, errWrite):
t.Logf("got error: %v (of type %T)", err, err)
case err != nil:
t.Errorf("got error of type %T, expected %T", err, errWrite)
case timedOut:
t.Errorf("got timeout, expected error")
case replied:
t.Errorf("got reply, expected error")
case spurious:
t.Errorf("got spurious message, expected timeout")
}
}
func TestReadErrorSendsErrorOnChan(t *testing.T) {
replied, timedOut, spurious, err := test(false, false, true, false)
switch {
case errors.Is(err, errRead):
t.Logf("got error: %v (of type %T)", err, err)
case err != nil:
t.Errorf("got error of type %T, expected %T", err, errWrite)
case timedOut:
t.Errorf("got timeout, expected error")
case replied:
t.Errorf("got reply, expected error")
case spurious:
t.Errorf("got spurious message, expected timeout")
}
}
func TestSpurious(t *testing.T) {
replied, timedOut, spurious, err := test(false, false, false, true)
switch {
case spurious:
case err != nil:
t.Errorf("got error %v, expected none", err)
case timedOut:
t.Errorf("got timeout, expected spurious message handler func callback")
case replied:
t.Errorf("got reply, expected spurious message handler func callback")
}
}
func test(dontReply, returnErrOnWrite, returnErrOnRead, returnSpurious bool) (replied, timedOut, spurious bool, err error) {
replyDone := make(chan struct{})
replyHandler := func(_ net.IP, _ int) {
replyDone <- struct{}{}
}
timeoutDone := make(chan struct{})
timeoutHandler := func(_ net.IP, _ int) {
timeoutDone <- struct{}{}
}
spuriousDone := make(chan struct{})
spuriousHandler := func(_ net.IP) {
spuriousDone <- struct{}{}
}
pinger, err := New(1*time.Millisecond, 1*time.Millisecond, []byte("test-ping"))
if err != nil {
log.Fatalf("Pinger construction error: %v", err)
}
pinger.WithSuccessHandler(replyHandler).
WithTimeoutHandler(timeoutHandler).
WithSpuriousHandler(spuriousHandler)
pinger.pingConnCreateFunc = func() (pingConn, error) {
return &mockPingConn{
replyChan: make(chan reply),
dontReply: dontReply,
returnErrOnWrite: returnErrOnWrite,
returnErrOnRead: returnErrOnRead,
returnSpurious: returnSpurious,
closed: make(chan struct{}),
}, nil
}
if err := pinger.Init(); err != nil {
log.Fatalf("Pinger init error: %v", err)
}
pinger.AddPeer("192.168.1.1")
done := make(chan struct{})
defer close(done)
errChan := pinger.Run(done)
select {
case <-timeoutDone:
return false, true, false, nil
case <-replyDone:
return true, false, false, nil
case <-spuriousDone:
return false, false, true, nil
case err := <-errChan:
return false, false, false, err
}
}