1
2
3
4
5 package nettest_test
6
7 import (
8 "bytes"
9 "errors"
10 "internal/nettest"
11 "io"
12 "net"
13 "net/netip"
14 "os"
15 "testing"
16 "testing/synctest"
17 "time"
18 )
19
20 func TestPacketConnListenConflict(t *testing.T) {
21 synctest.Test(t, func(t *testing.T) {
22 addr := net.UDPAddrFromAddrPort(netip.MustParseAddrPort("10.0.0.1:1000"))
23 pnet := nettest.NewPacketNet()
24 conn, err := pnet.NewConn(addr)
25 if err != nil {
26 t.Fatalf("with no existing listener, pnet.NewConn(%v) = %v; want success", addr, err)
27 }
28 _, err = pnet.NewConn(addr)
29 if err == nil {
30 t.Fatalf("with existing listener, pnet.NewConn(%v) = nil; want error", addr)
31 }
32 conn.Close()
33 _, err = pnet.NewConn(addr)
34 if err != nil {
35 t.Fatalf("after closing existing listener, pnet.NewConn(%v) = %v; want success", addr, err)
36 }
37 })
38 }
39
40 func TestPacketConnReadWrite(t *testing.T) {
41 synctest.Test(t, func(t *testing.T) {
42 pnet := nettest.NewPacketNet()
43 c1 := mustNewPacketConn(t, pnet, "10.0.0.1:1000")
44 c2 := mustNewPacketConn(t, pnet, "10.0.0.2:2000")
45 c3 := mustNewPacketConn(t, pnet, "10.0.0.3:3000")
46
47 wantPacketConnWriteTo(t, c1, []byte("1->3"), c3.LocalAddr())
48 wantPacketConnWriteTo(t, c2, []byte("2->3"), c3.LocalAddr())
49 wantPacketConnWriteTo(t, c3, []byte("3->1"), c1.LocalAddr())
50
51 wantPacketConnReadBytes(t, c1, []byte("3->1"), c3.LocalAddr())
52 wantPacketConnReadBytes(t, c3, []byte("1->3"), c1.LocalAddr())
53 wantPacketConnReadBytes(t, c3, []byte("2->3"), c2.LocalAddr())
54 wantPacketConnReadBlocked(t, c1)
55 wantPacketConnReadBlocked(t, c2)
56 wantPacketConnReadBlocked(t, c3)
57
58
59 wantPacketConnWriteTo(t, c1, []byte("1->lost"), net.UDPAddrFromAddrPort(netip.MustParseAddrPort("10.0.0.100:1000")))
60 })
61 }
62
63 func TestPacketConnWriteAddressErrors(t *testing.T) {
64 t.Skip("TODO: figure out if these should be errors")
65
66 synctest.Test(t, func(t *testing.T) {
67 pnet := nettest.NewPacketNet()
68 c4 := mustNewPacketConn(t, pnet, "10.0.0.1:1000")
69 c6 := mustNewPacketConn(t, pnet, "[::1]:1000")
70
71 wantPacketConnWriteErr(t, c4, c6.LocalAddr(), anyError)
72 wantPacketConnWriteErr(t, c6, c4.LocalAddr(), anyError)
73
74
75 wantPacketConnWriteErr(t, c4, net.UDPAddrFromAddrPort(netip.MustParseAddrPort("10.0.0.1:1000")), anyError)
76 })
77 }
78
79 func TestPacketConnClose(t *testing.T) {
80 synctest.Test(t, func(t *testing.T) {
81 pnet := nettest.NewPacketNet()
82 pconn := mustNewPacketConn(t, pnet, "10.0.0.1:1000")
83
84 wantPacketConnWriteTo(t, pconn, []byte("hello"), pconn.LocalAddr())
85
86 if err := pconn.Close(); err != nil {
87 t.Errorf("pconn.Close() = %v, want success", err)
88 }
89 if err := pconn.Close(); !isOpError(err, net.ErrClosed) {
90 t.Errorf("pconn.Close() = %v, want ErrClosed", err)
91 }
92
93 wantPacketConnReadErr(t, pconn, net.ErrClosed)
94 wantPacketConnWriteErr(t, pconn, pconn.LocalAddr(), net.ErrClosed)
95 })
96 }
97
98 func TestPacketConnReadDeadline(t *testing.T) {
99 for _, setDeadline := range []struct {
100 name string
101 f func(*nettest.PacketConn, time.Time) error
102 }{{
103 name: "SetDeadline",
104 f: (*nettest.PacketConn).SetDeadline,
105 }, {
106 name: "SetReadDeadline",
107 f: (*nettest.PacketConn).SetReadDeadline,
108 }} {
109 t.Run(setDeadline.name, func(t *testing.T) {
110 testDeadline(t, func() deadlineTest {
111 pnet := nettest.NewPacketNet()
112 rconn := mustNewPacketConn(t, pnet, "10.0.0.1:1000")
113 wconn := mustNewPacketConn(t, pnet, "10.0.0.2:2000")
114 return deadlineTest{
115 what: "ReadFrom()",
116 block: func() error {
117 _, _, err := rconn.ReadFrom(make([]byte, 1))
118 return err
119 },
120 unblock: func() {
121 wconn.WriteTo([]byte("x"), rconn.LocalAddr())
122 },
123 setDeadline: func(d time.Duration) {
124 setDeadline.f(rconn, time.Now().Add(d))
125 },
126 }
127 })
128 })
129 }
130 }
131
132 func TestPacketConnWriteDeadline(t *testing.T) {
133 synctest.Test(t, func(t *testing.T) {
134 pnet := nettest.NewPacketNet()
135 rconn := mustNewPacketConn(t, pnet, "10.0.0.1:1000")
136 wconn := mustNewPacketConn(t, pnet, "10.0.0.2:2000")
137
138
139 wconn.SetWriteDeadline(time.Now().Add(-1 * time.Second))
140
141 wantPacketConnWriteTo(t, wconn, []byte("data"), rconn.LocalAddr())
142 wantPacketConnReadBytes(t, rconn, []byte("data"), wconn.LocalAddr())
143 })
144 }
145
146 func TestPacketConnSetReadError(t *testing.T) {
147 synctest.Test(t, func(t *testing.T) {
148 wantErr := errors.New("error")
149 pnet := nettest.NewPacketNet()
150 rconn := mustNewPacketConn(t, pnet, "10.0.0.1:1000")
151 wconn := mustNewPacketConn(t, pnet, "10.0.0.2:2000")
152 rconn.SetReadError(wantErr)
153
154
155 wantPacketConnWriteTo(t, wconn, []byte("one"), rconn.LocalAddr())
156 wantPacketConnReadBytes(t, rconn, []byte("one"), wconn.LocalAddr())
157 wantPacketConnReadErr(t, rconn, wantErr)
158
159
160 wantPacketConnWriteTo(t, wconn, []byte("two"), rconn.LocalAddr())
161 wantPacketConnReadBytes(t, rconn, []byte("two"), wconn.LocalAddr())
162 wantPacketConnReadErr(t, rconn, wantErr)
163
164
165 rconn.SetReadError(nil)
166 wantPacketConnReadBlocked(t, rconn)
167
168
169 rconn.SetReadError(wantErr)
170 rconn.Close()
171 wantPacketConnReadErr(t, rconn, net.ErrClosed)
172 })
173 }
174
175 func TestPacketConnSetWriteError(t *testing.T) {
176 synctest.Test(t, func(t *testing.T) {
177 wantErr := errors.New("error")
178 pnet := nettest.NewPacketNet()
179 rconn := mustNewPacketConn(t, pnet, "10.0.0.1:1000")
180 wconn := mustNewPacketConn(t, pnet, "10.0.0.2:2000")
181 wconn.SetWriteError(wantErr)
182
183
184 wantPacketConnWriteErr(t, wconn, rconn.LocalAddr(), wantErr)
185 wantPacketConnReadBlocked(t, rconn)
186
187
188 wconn.SetWriteError(nil)
189 wantPacketConnWriteTo(t, wconn, []byte("one"), rconn.LocalAddr())
190
191
192 wconn.SetWriteError(wantErr)
193 wantPacketConnWriteErr(t, wconn, rconn.LocalAddr(), wantErr)
194 wantPacketConnReadBytes(t, rconn, []byte("one"), wconn.LocalAddr())
195
196
197 wconn.Close()
198 wantPacketConnWriteErr(t, wconn, rconn.LocalAddr(), net.ErrClosed)
199 })
200 }
201
202 func TestPacketConnSetCloseError(t *testing.T) {
203 synctest.Test(t, func(t *testing.T) {
204 wantErr := errors.New("error")
205 pnet := nettest.NewPacketNet()
206 rconn := mustNewPacketConn(t, pnet, "10.0.0.1:1000")
207 wconn := mustNewPacketConn(t, pnet, "10.0.0.2:2000")
208 wconn.SetCloseError(wantErr)
209
210 wantPacketConnWriteTo(t, wconn, []byte("one"), rconn.LocalAddr())
211 if err := wconn.Close(); !isOpError(err, wantErr) {
212 t.Fatalf("wconn.Close = %v, want OpError{Err: %v}", err, wantErr)
213 }
214 if err := wconn.Close(); !isOpError(err, net.ErrClosed) {
215 t.Fatalf("wconn.Close = %v, want OpError{Err: net.ErrClosed}", err)
216 }
217 wantPacketConnReadBytes(t, rconn, []byte("one"), wconn.LocalAddr())
218 })
219 }
220
221 func TestPacketConnCanRead(t *testing.T) {
222 synctest.Test(t, func(t *testing.T) {
223 pnet := nettest.NewPacketNet()
224 rconn := mustNewPacketConn(t, pnet, "10.0.0.1:1000")
225 wconn := mustNewPacketConn(t, pnet, "10.0.0.2:2000")
226 if got, want := rconn.CanRead(), false; got != want {
227 t.Fatalf("before writing data: rconn.CanRead() = %v, want %v", got, want)
228 }
229 wconn.WriteTo([]byte("a"), rconn.LocalAddr())
230 if got, want := rconn.CanRead(), true; got != want {
231 t.Fatalf("after writing data: rconn.CanRead() = %v, want %v", got, want)
232 }
233 rconn.ReadFrom(make([]byte, 1))
234 if got, want := rconn.CanRead(), false; got != want {
235 t.Fatalf("after reading data: rconn.CanRead() = %v, want %v", got, want)
236 }
237 })
238 }
239
240 func TestPacketConnIsClosed(t *testing.T) {
241 synctest.Test(t, func(t *testing.T) {
242 pnet := nettest.NewPacketNet()
243 conn := mustNewPacketConn(t, pnet, "10.0.0.1:1000")
244 if got, want := conn.IsClosed(), false; got != want {
245 t.Fatalf("before closing: conn.IsClosed() = %v, want %v", got, want)
246 }
247 conn.Close()
248 if got, want := conn.IsClosed(), true; got != want {
249 t.Fatalf("after closing: conn.IsClosed() = %v, want %v", got, want)
250 }
251 })
252 }
253
254 func mustNewPacketConn(t *testing.T, pnet *nettest.PacketNet, addr string) *nettest.PacketConn {
255 t.Helper()
256 c, err := pnet.NewConn(net.UDPAddrFromAddrPort(netip.MustParseAddrPort(addr)))
257 if err != nil {
258 t.Fatal(err)
259 }
260 return c
261 }
262
263 func wantPacketConnWriteTo(t *testing.T, c *nettest.PacketConn, b []byte, dst net.Addr) {
264 t.Helper()
265 if n, err := c.WriteTo(b, dst); n != len(b) || err != nil {
266 t.Fatalf("conn.WriteTo(%q, %v) = %v, %v; want %v, nil", b, dst, n, err, len(b))
267 }
268 }
269
270 func wantPacketConnWriteErr(t *testing.T, c *nettest.PacketConn, dst net.Addr, want error) {
271 t.Helper()
272 n, err := c.WriteTo(make([]byte, 1), dst)
273 if n != 0 || !isOpError(err, want) {
274 t.Fatalf("c.WriteTo() = %v, %v; want 0, OpError{Err: %q}", n, err, want)
275 }
276 }
277
278 func wantPacketConnReadBytes(t *testing.T, c *nettest.PacketConn, want []byte, wantAddr net.Addr) {
279 t.Helper()
280 udpWantAddr, ok := wantAddr.(*net.UDPAddr)
281 if !ok {
282 t.Fatalf("wantAddr is %T, should be *net.UDPAddr", wantAddr)
283 }
284 got := make([]byte, len(want)+1)
285 n, addr, err := c.ReadFrom(got)
286 got = got[:n]
287 udpAddr, addrOK := addr.(*net.UDPAddr)
288 if n != len(want) || !addrOK || udpAddr.AddrPort() != udpWantAddr.AddrPort() {
289 t.Fatalf("conn.ReadFrom() = %v, %v, %v; want %v, %v, nil", n, addr, err, len(want), wantAddr)
290 }
291 if !bytes.Equal(got, want) {
292 t.Fatalf("conn.ReadFrom() read %q, want %q", got, want)
293 }
294 }
295
296 func wantPacketConnReadErr(t *testing.T, c *nettest.PacketConn, want error) {
297 t.Helper()
298 n, addr, err := c.ReadFrom(make([]byte, 1))
299 if want == io.EOF {
300 if n != 0 || err != io.EOF {
301 t.Fatalf("c.ReadFrom() = %v, %v, %v; want 0, nil, io.EOF", n, addr, err)
302 }
303 } else {
304 if n != 0 || !isOpError(err, want) {
305 t.Fatalf("c.ReadFrom() = %v, %v, %v; want 0, nil, OpError{Err: %q}", n, addr, err, want)
306 }
307 }
308 }
309
310 func wantPacketConnReadBlocked(t *testing.T, c *nettest.PacketConn) {
311 done := false
312 go func() {
313 n, addr, err := c.ReadFrom(make([]byte, 1))
314 if n != 0 || !errors.Is(err, os.ErrDeadlineExceeded) {
315 t.Errorf("c.Read() = %v, %v, %v; want 0, nil, ErrDeadlineExceeded", n, addr, err)
316 }
317 done = true
318 }()
319 synctest.Wait()
320 if done {
321 t.Fatalf("ReadFrom unexpectedly returned before setting deadline")
322 }
323 c.SetReadDeadline(time.Now().Add(-1 * time.Second))
324 synctest.Wait()
325 c.SetReadDeadline(time.Time{})
326 if !done {
327 t.Fatalf("ReadFrom unexpectedly did not return after setting deadline")
328 }
329 }
330
View as plain text