forked from simonvetter/modbus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
udp_test.go
166 lines (152 loc) · 3.96 KB
/
udp_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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package modbus
import (
"net"
"os"
"testing"
"time"
)
func TestUDPSockWrapper(t *testing.T) {
var err error
var usw *udpSockWrapper
var sock1 *net.UDPConn
var sock2 *net.UDPConn
var addr *net.UDPAddr
var txchan chan []byte
var rxbuf []byte
var count int
addr, err = net.ResolveUDPAddr("udp", "localhost:5502")
if err != nil {
t.Errorf("failed to resolve udp address: %v", err)
return
}
txchan = make(chan []byte, 4)
// get a pair of UDP sockets ready to talk to each other
sock1, err = net.ListenUDP("udp", addr)
if err != nil {
t.Errorf("failed to listen on udp socket: %v", err)
return
}
err = sock1.SetReadDeadline(time.Now().Add(1 * time.Second))
if err != nil {
t.Errorf("failed to set deadline on udp socket: %v", err)
return
}
sock2, err = net.DialUDP("udp", nil, addr)
if err != nil {
t.Errorf("failed to open udp socket: %v", err)
return
}
// the feedTestPipe goroutine will forward any slice of bytes
// pushed into txchan over UDP to our test UDP sock wrapper object
go feedTestPipe(t, txchan, sock2)
usw = newUDPSockWrapper(sock1)
// push a valid RTU response (illegal data address) to the test pipe
txchan <- []byte{
0x31, 0x82, // unit id and response code
0x02, // exception code
0xc1, 0x6e, // CRC
}
// then push random junk
txchan <-[]byte{
0xaa, 0xbb, 0xcc,
}
// then some more
txchan <-[]byte{
0xdd, 0xee,
}
// attempt to read 3 bytes: we should get them as the first datagram
// is 5 bytes long
rxbuf = make([]byte, 3)
count, err = usw.Read(rxbuf)
if err != nil {
t.Errorf("usw.Read() should have succeeded, got: %v", err)
}
if count != 3 {
t.Errorf("expected 3 bytes, got: %v", count)
}
for idx, val := range []byte{
0x31, 0x82, 0x02,
} {
if rxbuf[idx] != val {
t.Errorf("expected 0x%02x at pos %v, got: 0x%02x",
val, idx, rxbuf[idx])
}
}
// attempt to read 1 byte: we should get the 4th byte of the
// first datagram, of which we've been holding on to bytes #4 and 5
rxbuf = make([]byte, 1)
count, err = usw.Read(rxbuf)
if err != nil {
t.Errorf("usw.Read() should have succeeded, got: %v", err)
}
if count != 1 {
t.Errorf("expected 1 byte, got: %v", count)
}
if rxbuf[0] != 0xc1 {
t.Errorf("expected 0xc1 at pos 0, got: 0x%02x", rxbuf[0])
}
// attempt to read 5 bytes: we should get the last byte of the
// first datagram, which the udpSockWrapper object still holds in
// its buffer
rxbuf = make([]byte, 5)
count, err = usw.Read(rxbuf)
if err != nil {
t.Errorf("usw.Read() should have succeeded, got: %v", err)
}
if count != 1 {
t.Errorf("expected 1 byte, got: %v", count)
}
if rxbuf[0] != 0x6e {
t.Errorf("expected 0x6e at pos 0, got: 0x%02x", rxbuf[0])
}
// attempt to read 10 bytes: we should get all 3 bytes of the 2nd
// datagram
rxbuf = make([]byte, 10)
count, err = usw.Read(rxbuf)
if err != nil {
t.Errorf("usw.Read() should have succeeded, got: %v", err)
}
if count != 3 {
t.Errorf("expected 3 bytes, got: %v", count)
}
for idx, val := range []byte{
0xaa, 0xbb, 0xcc,
} {
if rxbuf[idx] != val {
t.Errorf("expected 0x%02x at pos %v, got: 0x%02x",
val, idx, rxbuf[idx])
}
}
// attempt to read 40 bytes: we should get both bytes of the 3rd
// datagram
rxbuf = make([]byte, 40)
count, err = usw.Read(rxbuf)
if err != nil {
t.Errorf("usw.Read() should have succeeded, got: %v", err)
}
if count != 2 {
t.Errorf("expected 2 bytes, got: %v", count)
}
for idx, val := range []byte{
0xdd, 0xee,
} {
if rxbuf[idx] != val {
t.Errorf("expected 0x%02x at pos %v, got: 0x%02x",
val, idx, rxbuf[idx])
}
}
// attempt to read 7 bytes: we should get a read timeout as we've
// consumed all bytes from all datagrams and no more are coming
rxbuf = make([]byte, 7)
count, err = usw.Read(rxbuf)
if !os.IsTimeout(err) {
t.Errorf("usw.Read() should have failed with a timeout error, got: %v", err)
}
if count != 0 {
t.Errorf("expected 0 bytes, got: %v", count)
}
// cleanup
sock1.Close()
sock2.Close()
return
}