1
2
3
4
5 package nettest_test
6
7 import (
8 "errors"
9 "internal/nettest"
10 "net"
11 "os"
12 "sync/atomic"
13 "testing"
14 "testing/synctest"
15 "time"
16 )
17
18 var (
19 _ net.Conn = (*nettest.Conn)(nil)
20 _ net.Listener = (*nettest.Listener)(nil)
21 _ net.PacketConn = (*nettest.PacketConn)(nil)
22 )
23
24 func synctestSubtest(t *testing.T, name string, f func(t *testing.T)) {
25 t.Run(name, func(t *testing.T) {
26 synctest.Test(t, func(t *testing.T) {
27 f(t)
28 })
29 })
30 }
31
32
33
34 type deadlineTest struct {
35 what string
36 block func() error
37 unblock func()
38 setDeadline func(d time.Duration)
39 }
40
41
42 func testDeadline(t *testing.T, setup func() deadlineTest) {
43 synctestSubtest(t, "no deadline", func(t *testing.T) {
44 test := setup()
45 test.unblock()
46 synctest.Wait()
47 if err := test.block(); errors.Is(err, os.ErrDeadlineExceeded) {
48 t.Errorf("%v: %v, want not deadline exceeded", test.what, err)
49 }
50 })
51 synctestSubtest(t, "unblock before setdeadline", func(t *testing.T) {
52 test := setup()
53 test.unblock()
54 synctest.Wait()
55 test.setDeadline(5 * time.Second)
56 if err := test.block(); errors.Is(err, os.ErrDeadlineExceeded) {
57 t.Errorf("%v: %v, want not deadline exceeded", test.what, err)
58 }
59 })
60 synctestSubtest(t, "unblock after blocking", func(t *testing.T) {
61 test := setup()
62 test.setDeadline(5 * time.Second)
63 var done bool
64 go func() {
65 if err := test.block(); errors.Is(err, os.ErrDeadlineExceeded) {
66 t.Errorf("%v: %v, want not deadline exceeded", test.what, err)
67 }
68 done = true
69 }()
70 synctest.Wait()
71 if done {
72 t.Fatalf("%v: unexpectedly returned before unblocking", test.what)
73 }
74 test.unblock()
75 synctest.Wait()
76 if !done {
77 t.Fatalf("%v: did not return after unblocking", test.what)
78 }
79 })
80 synctestSubtest(t, "deadline expires", func(t *testing.T) {
81 test := setup()
82 start := time.Now()
83 const delay = 5 * time.Second
84 test.setDeadline(delay)
85 var done atomic.Bool
86 go func() {
87 if err := test.block(); !errors.Is(err, os.ErrDeadlineExceeded) {
88 t.Errorf("%v: %v, want os.ErrDeadlineExceeded", test.what, err)
89 }
90 if got, want := time.Since(start), delay; got != want {
91 t.Errorf("%v: returned after %v, want %v", test.what, got, want)
92 }
93 done.Store(true)
94 }()
95 synctest.Wait()
96 if done.Load() {
97 t.Fatalf("%v: unexpectedly returned before unblocking", test.what)
98 }
99 time.Sleep(delay)
100 synctest.Wait()
101 if !done.Load() {
102 t.Fatalf("%v: did not return after deadline", test.what)
103 }
104 })
105 synctestSubtest(t, "deadline already expired", func(t *testing.T) {
106 test := setup()
107 test.setDeadline(-1 * time.Second)
108 test.unblock()
109 synctest.Wait()
110 if err := test.block(); !errors.Is(err, os.ErrDeadlineExceeded) {
111 t.Errorf("%v: %v, want os.ErrDeadlineExceeded", test.what, err)
112 }
113 })
114 synctestSubtest(t, "reduce deadline after blocking", func(t *testing.T) {
115 test := setup()
116 test.setDeadline(5 * time.Second)
117 var done bool
118 go func() {
119 if err := test.block(); !errors.Is(err, os.ErrDeadlineExceeded) {
120 t.Errorf("%v: %v, want os.ErrDeadlineExceeded", test.what, err)
121 }
122 done = true
123 }()
124 synctest.Wait()
125 if done {
126 t.Fatalf("%v: unexpectedly returned before reducing deadline", test.what)
127 }
128 test.setDeadline(-1 * time.Second)
129 synctest.Wait()
130 if !done {
131 t.Fatalf("%v: did not return after deadline", test.what)
132 }
133 })
134 }
135
View as plain text