file_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // Copyright 2011 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. package net
  5. import (
  6. "os"
  7. "reflect"
  8. "runtime"
  9. "testing"
  10. )
  11. type listenerFile interface {
  12. Listener
  13. File() (f *os.File, err error)
  14. }
  15. type packetConnFile interface {
  16. PacketConn
  17. File() (f *os.File, err error)
  18. }
  19. type connFile interface {
  20. Conn
  21. File() (f *os.File, err error)
  22. }
  23. func testFileListener(t *testing.T, net, laddr string) {
  24. switch net {
  25. case "tcp", "tcp4", "tcp6":
  26. laddr += ":0" // any available port
  27. }
  28. l, err := Listen(net, laddr)
  29. if err != nil {
  30. t.Fatalf("Listen failed: %v", err)
  31. }
  32. defer l.Close()
  33. lf := l.(listenerFile)
  34. f, err := lf.File()
  35. if err != nil {
  36. t.Fatalf("File failed: %v", err)
  37. }
  38. c, err := FileListener(f)
  39. if err != nil {
  40. t.Fatalf("FileListener failed: %v", err)
  41. }
  42. if !reflect.DeepEqual(l.Addr(), c.Addr()) {
  43. t.Fatalf("Addrs not equal: %#v != %#v", l.Addr(), c.Addr())
  44. }
  45. if err := c.Close(); err != nil {
  46. t.Fatalf("Close failed: %v", err)
  47. }
  48. if err := f.Close(); err != nil {
  49. t.Fatalf("Close failed: %v", err)
  50. }
  51. }
  52. var fileListenerTests = []struct {
  53. net string
  54. laddr string
  55. ipv6 bool // test with underlying AF_INET6 socket
  56. linux bool // test with abstract unix domain socket, a Linux-ism
  57. }{
  58. {net: "tcp", laddr: ""},
  59. {net: "tcp", laddr: "0.0.0.0"},
  60. {net: "tcp", laddr: "[::ffff:0.0.0.0]"},
  61. {net: "tcp", laddr: "[::]", ipv6: true},
  62. {net: "tcp", laddr: "127.0.0.1"},
  63. {net: "tcp", laddr: "[::ffff:127.0.0.1]"},
  64. {net: "tcp", laddr: "[::1]", ipv6: true},
  65. {net: "tcp4", laddr: ""},
  66. {net: "tcp4", laddr: "0.0.0.0"},
  67. {net: "tcp4", laddr: "[::ffff:0.0.0.0]"},
  68. {net: "tcp4", laddr: "127.0.0.1"},
  69. {net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
  70. {net: "tcp6", laddr: "", ipv6: true},
  71. {net: "tcp6", laddr: "[::]", ipv6: true},
  72. {net: "tcp6", laddr: "[::1]", ipv6: true},
  73. {net: "unix", laddr: "@gotest/net", linux: true},
  74. {net: "unixpacket", laddr: "@gotest/net", linux: true},
  75. }
  76. func TestFileListener(t *testing.T) {
  77. switch runtime.GOOS {
  78. case "nacl", "windows":
  79. t.Skipf("skipping test on %q", runtime.GOOS)
  80. }
  81. for _, tt := range fileListenerTests {
  82. if skipServerTest(tt.net, "unix", tt.laddr, tt.ipv6, false, tt.linux) {
  83. continue
  84. }
  85. if skipServerTest(tt.net, "unixpacket", tt.laddr, tt.ipv6, false, tt.linux) {
  86. continue
  87. }
  88. testFileListener(t, tt.net, tt.laddr)
  89. }
  90. }
  91. func testFilePacketConn(t *testing.T, pcf packetConnFile, listen bool) {
  92. f, err := pcf.File()
  93. if err != nil {
  94. t.Fatalf("File failed: %v", err)
  95. }
  96. c, err := FilePacketConn(f)
  97. if err != nil {
  98. t.Fatalf("FilePacketConn failed: %v", err)
  99. }
  100. if !reflect.DeepEqual(pcf.LocalAddr(), c.LocalAddr()) {
  101. t.Fatalf("LocalAddrs not equal: %#v != %#v", pcf.LocalAddr(), c.LocalAddr())
  102. }
  103. if listen {
  104. if _, err := c.WriteTo([]byte{}, c.LocalAddr()); err != nil {
  105. t.Fatalf("WriteTo failed: %v", err)
  106. }
  107. }
  108. if err := c.Close(); err != nil {
  109. t.Fatalf("Close failed: %v", err)
  110. }
  111. if err := f.Close(); err != nil {
  112. t.Fatalf("Close failed: %v", err)
  113. }
  114. }
  115. func testFilePacketConnListen(t *testing.T, net, laddr string) {
  116. switch net {
  117. case "udp", "udp4", "udp6":
  118. laddr += ":0" // any available port
  119. }
  120. l, err := ListenPacket(net, laddr)
  121. if err != nil {
  122. t.Fatalf("ListenPacket failed: %v", err)
  123. }
  124. testFilePacketConn(t, l.(packetConnFile), true)
  125. if err := l.Close(); err != nil {
  126. t.Fatalf("Close failed: %v", err)
  127. }
  128. }
  129. func testFilePacketConnDial(t *testing.T, net, raddr string) {
  130. switch net {
  131. case "udp", "udp4", "udp6":
  132. raddr += ":12345"
  133. }
  134. c, err := Dial(net, raddr)
  135. if err != nil {
  136. t.Fatalf("Dial failed: %v", err)
  137. }
  138. testFilePacketConn(t, c.(packetConnFile), false)
  139. if err := c.Close(); err != nil {
  140. t.Fatalf("Close failed: %v", err)
  141. }
  142. }
  143. var filePacketConnTests = []struct {
  144. net string
  145. addr string
  146. ipv6 bool // test with underlying AF_INET6 socket
  147. linux bool // test with abstract unix domain socket, a Linux-ism
  148. }{
  149. {net: "udp", addr: "127.0.0.1"},
  150. {net: "udp", addr: "[::ffff:127.0.0.1]"},
  151. {net: "udp", addr: "[::1]", ipv6: true},
  152. {net: "udp4", addr: "127.0.0.1"},
  153. {net: "udp4", addr: "[::ffff:127.0.0.1]"},
  154. {net: "udp6", addr: "[::1]", ipv6: true},
  155. {net: "ip4:icmp", addr: "127.0.0.1"},
  156. {net: "unixgram", addr: "@gotest3/net", linux: true},
  157. }
  158. func TestFilePacketConn(t *testing.T) {
  159. switch runtime.GOOS {
  160. case "nacl", "plan9", "windows":
  161. t.Skipf("skipping test on %q", runtime.GOOS)
  162. }
  163. for _, tt := range filePacketConnTests {
  164. if skipServerTest(tt.net, "unixgram", tt.addr, tt.ipv6, false, tt.linux) {
  165. continue
  166. }
  167. if os.Getuid() != 0 && tt.net == "ip4:icmp" {
  168. t.Log("skipping test; must be root")
  169. continue
  170. }
  171. testFilePacketConnListen(t, tt.net, tt.addr)
  172. switch tt.addr {
  173. case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]":
  174. default:
  175. if tt.net != "unixgram" {
  176. testFilePacketConnDial(t, tt.net, tt.addr)
  177. }
  178. }
  179. }
  180. }