Source file
src/net/tcpconn_keepalive_test.go
1
2
3
4
5
6
7 package net
8
9 import (
10 "runtime"
11 "testing"
12 )
13
14 func TestTCPConnKeepAliveConfigDialer(t *testing.T) {
15 maybeSkipKeepAliveTest(t)
16
17 t.Cleanup(func() {
18 testPreHookSetKeepAlive = func(*netFD) {}
19 })
20 var (
21 errHook error
22 oldCfg KeepAliveConfig
23 )
24 testPreHookSetKeepAlive = func(nfd *netFD) {
25 oldCfg, errHook = getCurrentKeepAliveSettings(fdType(nfd.pfd.Sysfd))
26 }
27
28 handler := func(ls *localServer, ln Listener) {
29 for {
30 c, err := ln.Accept()
31 if err != nil {
32 return
33 }
34 c.Close()
35 }
36 }
37 ln := newLocalListener(t, "tcp", &ListenConfig{
38 KeepAlive: -1,
39 })
40 ls := (&streamListener{Listener: ln}).newLocalServer()
41 defer ls.teardown()
42 if err := ls.buildup(handler); err != nil {
43 t.Fatal(err)
44 }
45
46 for _, cfg := range testConfigs {
47 d := Dialer{
48 KeepAlive: defaultTCPKeepAliveIdle,
49 KeepAliveConfig: cfg}
50 c, err := d.Dial("tcp", ls.Listener.Addr().String())
51 if err != nil {
52 t.Fatal(err)
53 }
54 defer c.Close()
55
56 if errHook != nil {
57 t.Fatal(errHook)
58 }
59
60 sc, err := c.(*TCPConn).SyscallConn()
61 if err != nil {
62 t.Fatal(err)
63 }
64 if err := sc.Control(func(fd uintptr) {
65 verifyKeepAliveSettings(t, fdType(fd), oldCfg, cfg)
66 }); err != nil {
67 t.Fatal(err)
68 }
69 }
70 }
71
72 func TestTCPConnKeepAliveConfigListener(t *testing.T) {
73 maybeSkipKeepAliveTest(t)
74
75 t.Cleanup(func() {
76 testPreHookSetKeepAlive = func(*netFD) {}
77 })
78 var (
79 errHook error
80 oldCfg KeepAliveConfig
81 )
82 testPreHookSetKeepAlive = func(nfd *netFD) {
83 oldCfg, errHook = getCurrentKeepAliveSettings(fdType(nfd.pfd.Sysfd))
84 }
85
86 ch := make(chan Conn, 1)
87 handler := func(ls *localServer, ln Listener) {
88 c, err := ln.Accept()
89 if err != nil {
90 return
91 }
92 ch <- c
93 }
94 for _, cfg := range testConfigs {
95 ln := newLocalListener(t, "tcp", &ListenConfig{
96 KeepAlive: defaultTCPKeepAliveIdle,
97 KeepAliveConfig: cfg})
98 ls := (&streamListener{Listener: ln}).newLocalServer()
99 defer ls.teardown()
100 if err := ls.buildup(handler); err != nil {
101 t.Fatal(err)
102 }
103 d := Dialer{KeepAlive: -1}
104 c, err := d.Dial("tcp", ls.Listener.Addr().String())
105 if err != nil {
106 t.Fatal(err)
107 }
108 defer c.Close()
109
110 cc := <-ch
111 defer cc.Close()
112 if errHook != nil {
113 t.Fatal(errHook)
114 }
115 sc, err := cc.(*TCPConn).SyscallConn()
116 if err != nil {
117 t.Fatal(err)
118 }
119 if err := sc.Control(func(fd uintptr) {
120 verifyKeepAliveSettings(t, fdType(fd), oldCfg, cfg)
121 }); err != nil {
122 t.Fatal(err)
123 }
124 }
125 }
126
127 func TestTCPConnKeepAliveConfig(t *testing.T) {
128 maybeSkipKeepAliveTest(t)
129
130 handler := func(ls *localServer, ln Listener) {
131 for {
132 c, err := ln.Accept()
133 if err != nil {
134 return
135 }
136 c.Close()
137 }
138 }
139 ls := newLocalServer(t, "tcp")
140 defer ls.teardown()
141 if err := ls.buildup(handler); err != nil {
142 t.Fatal(err)
143 }
144 for _, cfg := range testConfigs {
145 d := Dialer{KeepAlive: -1}
146 c, err := d.Dial("tcp", ls.Listener.Addr().String())
147 if err != nil {
148 t.Fatal(err)
149 }
150 defer c.Close()
151
152 sc, err := c.(*TCPConn).SyscallConn()
153 if err != nil {
154 t.Fatal(err)
155 }
156
157 var (
158 errHook error
159 oldCfg KeepAliveConfig
160 )
161 if err := sc.Control(func(fd uintptr) {
162 oldCfg, errHook = getCurrentKeepAliveSettings(fdType(fd))
163 }); err != nil {
164 t.Fatal(err)
165 }
166 if errHook != nil {
167 t.Fatal(errHook)
168 }
169
170 err = c.(*TCPConn).SetKeepAliveConfig(cfg)
171 if err != nil {
172 if runtime.GOOS == "solaris" {
173
174
175
176 if cfg.Interval >= 0 && cfg.Count >= 0 {
177 t.Fatal(err)
178 }
179 } else {
180 t.Fatal(err)
181 }
182 }
183
184 if err := sc.Control(func(fd uintptr) {
185 verifyKeepAliveSettings(t, fdType(fd), oldCfg, cfg)
186 }); err != nil {
187 t.Fatal(err)
188 }
189 }
190 }
191
View as plain text