mockserver_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. // Copyright 2013 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build !js
  5. package net
  6. import (
  7. "errors"
  8. "fmt"
  9. "os"
  10. "path/filepath"
  11. "sync"
  12. "testing"
  13. "time"
  14. )
  15. // testUnixAddr uses os.MkdirTemp to get a name that is unique.
  16. func testUnixAddr(t testing.TB) string {
  17. // Pass an empty pattern to get a directory name that is as short as possible.
  18. // If we end up with a name longer than the sun_path field in the sockaddr_un
  19. // struct, we won't be able to make the syscall to open the socket.
  20. d, err := os.MkdirTemp("", "")
  21. if err != nil {
  22. t.Fatal(err)
  23. }
  24. t.Cleanup(func() {
  25. if err := os.RemoveAll(d); err != nil {
  26. t.Error(err)
  27. }
  28. })
  29. return filepath.Join(d, "sock")
  30. }
  31. func newLocalListener(t testing.TB, network string) Listener {
  32. listen := func(net, addr string) Listener {
  33. ln, err := Listen(net, addr)
  34. if err != nil {
  35. t.Helper()
  36. t.Fatal(err)
  37. }
  38. return ln
  39. }
  40. switch network {
  41. case "tcp":
  42. if supportsIPv4() {
  43. if !supportsIPv6() {
  44. return listen("tcp4", "127.0.0.1:0")
  45. }
  46. if ln, err := Listen("tcp4", "127.0.0.1:0"); err == nil {
  47. return ln
  48. }
  49. }
  50. if supportsIPv6() {
  51. return listen("tcp6", "[::1]:0")
  52. }
  53. case "tcp4":
  54. if supportsIPv4() {
  55. return listen("tcp4", "127.0.0.1:0")
  56. }
  57. case "tcp6":
  58. if supportsIPv6() {
  59. return listen("tcp6", "[::1]:0")
  60. }
  61. case "unix", "unixpacket":
  62. return listen(network, testUnixAddr(t))
  63. }
  64. t.Helper()
  65. t.Fatalf("%s is not supported", network)
  66. return nil
  67. }
  68. func newDualStackListener() (lns []*TCPListener, err error) {
  69. var args = []struct {
  70. network string
  71. TCPAddr
  72. }{
  73. {"tcp4", TCPAddr{IP: IPv4(127, 0, 0, 1)}},
  74. {"tcp6", TCPAddr{IP: IPv6loopback}},
  75. }
  76. for i := 0; i < 64; i++ {
  77. var port int
  78. var lns []*TCPListener
  79. for _, arg := range args {
  80. arg.TCPAddr.Port = port
  81. ln, err := ListenTCP(arg.network, &arg.TCPAddr)
  82. if err != nil {
  83. continue
  84. }
  85. port = ln.Addr().(*TCPAddr).Port
  86. lns = append(lns, ln)
  87. }
  88. if len(lns) != len(args) {
  89. for _, ln := range lns {
  90. ln.Close()
  91. }
  92. continue
  93. }
  94. return lns, nil
  95. }
  96. return nil, errors.New("no dualstack port available")
  97. }
  98. type localServer struct {
  99. lnmu sync.RWMutex
  100. Listener
  101. done chan bool // signal that indicates server stopped
  102. cl []Conn // accepted connection list
  103. }
  104. func (ls *localServer) buildup(handler func(*localServer, Listener)) error {
  105. go func() {
  106. handler(ls, ls.Listener)
  107. close(ls.done)
  108. }()
  109. return nil
  110. }
  111. func (ls *localServer) teardown() error {
  112. ls.lnmu.Lock()
  113. defer ls.lnmu.Unlock()
  114. if ls.Listener != nil {
  115. network := ls.Listener.Addr().Network()
  116. address := ls.Listener.Addr().String()
  117. ls.Listener.Close()
  118. for _, c := range ls.cl {
  119. if err := c.Close(); err != nil {
  120. return err
  121. }
  122. }
  123. <-ls.done
  124. ls.Listener = nil
  125. switch network {
  126. case "unix", "unixpacket":
  127. os.Remove(address)
  128. }
  129. }
  130. return nil
  131. }
  132. func newLocalServer(t testing.TB, network string) *localServer {
  133. t.Helper()
  134. ln := newLocalListener(t, network)
  135. return &localServer{Listener: ln, done: make(chan bool)}
  136. }
  137. type streamListener struct {
  138. network, address string
  139. Listener
  140. done chan bool // signal that indicates server stopped
  141. }
  142. func (sl *streamListener) newLocalServer() *localServer {
  143. return &localServer{Listener: sl.Listener, done: make(chan bool)}
  144. }
  145. type dualStackServer struct {
  146. lnmu sync.RWMutex
  147. lns []streamListener
  148. port string
  149. cmu sync.RWMutex
  150. cs []Conn // established connections at the passive open side
  151. }
  152. func (dss *dualStackServer) buildup(handler func(*dualStackServer, Listener)) error {
  153. for i := range dss.lns {
  154. go func(i int) {
  155. handler(dss, dss.lns[i].Listener)
  156. close(dss.lns[i].done)
  157. }(i)
  158. }
  159. return nil
  160. }
  161. func (dss *dualStackServer) teardownNetwork(network string) error {
  162. dss.lnmu.Lock()
  163. for i := range dss.lns {
  164. if network == dss.lns[i].network && dss.lns[i].Listener != nil {
  165. dss.lns[i].Listener.Close()
  166. <-dss.lns[i].done
  167. dss.lns[i].Listener = nil
  168. }
  169. }
  170. dss.lnmu.Unlock()
  171. return nil
  172. }
  173. func (dss *dualStackServer) teardown() error {
  174. dss.lnmu.Lock()
  175. for i := range dss.lns {
  176. if dss.lns[i].Listener != nil {
  177. dss.lns[i].Listener.Close()
  178. <-dss.lns[i].done
  179. }
  180. }
  181. dss.lns = dss.lns[:0]
  182. dss.lnmu.Unlock()
  183. dss.cmu.Lock()
  184. for _, c := range dss.cs {
  185. c.Close()
  186. }
  187. dss.cs = dss.cs[:0]
  188. dss.cmu.Unlock()
  189. return nil
  190. }
  191. func newDualStackServer() (*dualStackServer, error) {
  192. lns, err := newDualStackListener()
  193. if err != nil {
  194. return nil, err
  195. }
  196. _, port, err := SplitHostPort(lns[0].Addr().String())
  197. if err != nil {
  198. lns[0].Close()
  199. lns[1].Close()
  200. return nil, err
  201. }
  202. return &dualStackServer{
  203. lns: []streamListener{
  204. {network: "tcp4", address: lns[0].Addr().String(), Listener: lns[0], done: make(chan bool)},
  205. {network: "tcp6", address: lns[1].Addr().String(), Listener: lns[1], done: make(chan bool)},
  206. },
  207. port: port,
  208. }, nil
  209. }
  210. func (ls *localServer) transponder(ln Listener, ch chan<- error) {
  211. defer close(ch)
  212. switch ln := ln.(type) {
  213. case *TCPListener:
  214. ln.SetDeadline(time.Now().Add(someTimeout))
  215. case *UnixListener:
  216. ln.SetDeadline(time.Now().Add(someTimeout))
  217. }
  218. c, err := ln.Accept()
  219. if err != nil {
  220. if perr := parseAcceptError(err); perr != nil {
  221. ch <- perr
  222. }
  223. ch <- err
  224. return
  225. }
  226. ls.cl = append(ls.cl, c)
  227. network := ln.Addr().Network()
  228. if c.LocalAddr().Network() != network || c.RemoteAddr().Network() != network {
  229. ch <- fmt.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
  230. return
  231. }
  232. c.SetDeadline(time.Now().Add(someTimeout))
  233. c.SetReadDeadline(time.Now().Add(someTimeout))
  234. c.SetWriteDeadline(time.Now().Add(someTimeout))
  235. b := make([]byte, 256)
  236. n, err := c.Read(b)
  237. if err != nil {
  238. if perr := parseReadError(err); perr != nil {
  239. ch <- perr
  240. }
  241. ch <- err
  242. return
  243. }
  244. if _, err := c.Write(b[:n]); err != nil {
  245. if perr := parseWriteError(err); perr != nil {
  246. ch <- perr
  247. }
  248. ch <- err
  249. return
  250. }
  251. }
  252. func transceiver(c Conn, wb []byte, ch chan<- error) {
  253. defer close(ch)
  254. c.SetDeadline(time.Now().Add(someTimeout))
  255. c.SetReadDeadline(time.Now().Add(someTimeout))
  256. c.SetWriteDeadline(time.Now().Add(someTimeout))
  257. n, err := c.Write(wb)
  258. if err != nil {
  259. if perr := parseWriteError(err); perr != nil {
  260. ch <- perr
  261. }
  262. ch <- err
  263. return
  264. }
  265. if n != len(wb) {
  266. ch <- fmt.Errorf("wrote %d; want %d", n, len(wb))
  267. }
  268. rb := make([]byte, len(wb))
  269. n, err = c.Read(rb)
  270. if err != nil {
  271. if perr := parseReadError(err); perr != nil {
  272. ch <- perr
  273. }
  274. ch <- err
  275. return
  276. }
  277. if n != len(wb) {
  278. ch <- fmt.Errorf("read %d; want %d", n, len(wb))
  279. }
  280. }
  281. func newLocalPacketListener(t testing.TB, network string) PacketConn {
  282. listenPacket := func(net, addr string) PacketConn {
  283. c, err := ListenPacket(net, addr)
  284. if err != nil {
  285. t.Helper()
  286. t.Fatal(err)
  287. }
  288. return c
  289. }
  290. switch network {
  291. case "udp":
  292. if supportsIPv4() {
  293. return listenPacket("udp4", "127.0.0.1:0")
  294. }
  295. if supportsIPv6() {
  296. return listenPacket("udp6", "[::1]:0")
  297. }
  298. case "udp4":
  299. if supportsIPv4() {
  300. return listenPacket("udp4", "127.0.0.1:0")
  301. }
  302. case "udp6":
  303. if supportsIPv6() {
  304. return listenPacket("udp6", "[::1]:0")
  305. }
  306. case "unixgram":
  307. return listenPacket(network, testUnixAddr(t))
  308. }
  309. t.Helper()
  310. t.Fatalf("%s is not supported", network)
  311. return nil
  312. }
  313. func newDualStackPacketListener() (cs []*UDPConn, err error) {
  314. var args = []struct {
  315. network string
  316. UDPAddr
  317. }{
  318. {"udp4", UDPAddr{IP: IPv4(127, 0, 0, 1)}},
  319. {"udp6", UDPAddr{IP: IPv6loopback}},
  320. }
  321. for i := 0; i < 64; i++ {
  322. var port int
  323. var cs []*UDPConn
  324. for _, arg := range args {
  325. arg.UDPAddr.Port = port
  326. c, err := ListenUDP(arg.network, &arg.UDPAddr)
  327. if err != nil {
  328. continue
  329. }
  330. port = c.LocalAddr().(*UDPAddr).Port
  331. cs = append(cs, c)
  332. }
  333. if len(cs) != len(args) {
  334. for _, c := range cs {
  335. c.Close()
  336. }
  337. continue
  338. }
  339. return cs, nil
  340. }
  341. return nil, errors.New("no dualstack port available")
  342. }
  343. type localPacketServer struct {
  344. pcmu sync.RWMutex
  345. PacketConn
  346. done chan bool // signal that indicates server stopped
  347. }
  348. func (ls *localPacketServer) buildup(handler func(*localPacketServer, PacketConn)) error {
  349. go func() {
  350. handler(ls, ls.PacketConn)
  351. close(ls.done)
  352. }()
  353. return nil
  354. }
  355. func (ls *localPacketServer) teardown() error {
  356. ls.pcmu.Lock()
  357. if ls.PacketConn != nil {
  358. network := ls.PacketConn.LocalAddr().Network()
  359. address := ls.PacketConn.LocalAddr().String()
  360. ls.PacketConn.Close()
  361. <-ls.done
  362. ls.PacketConn = nil
  363. switch network {
  364. case "unixgram":
  365. os.Remove(address)
  366. }
  367. }
  368. ls.pcmu.Unlock()
  369. return nil
  370. }
  371. func newLocalPacketServer(t testing.TB, network string) *localPacketServer {
  372. t.Helper()
  373. c := newLocalPacketListener(t, network)
  374. return &localPacketServer{PacketConn: c, done: make(chan bool)}
  375. }
  376. type packetListener struct {
  377. PacketConn
  378. }
  379. func (pl *packetListener) newLocalServer() *localPacketServer {
  380. return &localPacketServer{PacketConn: pl.PacketConn, done: make(chan bool)}
  381. }
  382. func packetTransponder(c PacketConn, ch chan<- error) {
  383. defer close(ch)
  384. c.SetDeadline(time.Now().Add(someTimeout))
  385. c.SetReadDeadline(time.Now().Add(someTimeout))
  386. c.SetWriteDeadline(time.Now().Add(someTimeout))
  387. b := make([]byte, 256)
  388. n, peer, err := c.ReadFrom(b)
  389. if err != nil {
  390. if perr := parseReadError(err); perr != nil {
  391. ch <- perr
  392. }
  393. ch <- err
  394. return
  395. }
  396. if peer == nil { // for connected-mode sockets
  397. switch c.LocalAddr().Network() {
  398. case "udp":
  399. peer, err = ResolveUDPAddr("udp", string(b[:n]))
  400. case "unixgram":
  401. peer, err = ResolveUnixAddr("unixgram", string(b[:n]))
  402. }
  403. if err != nil {
  404. ch <- err
  405. return
  406. }
  407. }
  408. if _, err := c.WriteTo(b[:n], peer); err != nil {
  409. if perr := parseWriteError(err); perr != nil {
  410. ch <- perr
  411. }
  412. ch <- err
  413. return
  414. }
  415. }
  416. func packetTransceiver(c PacketConn, wb []byte, dst Addr, ch chan<- error) {
  417. defer close(ch)
  418. c.SetDeadline(time.Now().Add(someTimeout))
  419. c.SetReadDeadline(time.Now().Add(someTimeout))
  420. c.SetWriteDeadline(time.Now().Add(someTimeout))
  421. n, err := c.WriteTo(wb, dst)
  422. if err != nil {
  423. if perr := parseWriteError(err); perr != nil {
  424. ch <- perr
  425. }
  426. ch <- err
  427. return
  428. }
  429. if n != len(wb) {
  430. ch <- fmt.Errorf("wrote %d; want %d", n, len(wb))
  431. }
  432. rb := make([]byte, len(wb))
  433. n, _, err = c.ReadFrom(rb)
  434. if err != nil {
  435. if perr := parseReadError(err); perr != nil {
  436. ch <- perr
  437. }
  438. ch <- err
  439. return
  440. }
  441. if n != len(wb) {
  442. ch <- fmt.Errorf("read %d; want %d", n, len(wb))
  443. }
  444. }