PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/gofrontend/libgo/go/net/tcp_test.go

http://github.com/axw/llgo
Go | 587 lines | 514 code | 48 blank | 25 comment | 187 complexity | 6db41a4e2e8c3adaaafb46240337966f MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. // Copyright 2012 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. "io"
  7. "reflect"
  8. "runtime"
  9. "sync"
  10. "testing"
  11. "time"
  12. )
  13. func BenchmarkTCP4OneShot(b *testing.B) {
  14. benchmarkTCP(b, false, false, "127.0.0.1:0")
  15. }
  16. func BenchmarkTCP4OneShotTimeout(b *testing.B) {
  17. benchmarkTCP(b, false, true, "127.0.0.1:0")
  18. }
  19. func BenchmarkTCP4Persistent(b *testing.B) {
  20. benchmarkTCP(b, true, false, "127.0.0.1:0")
  21. }
  22. func BenchmarkTCP4PersistentTimeout(b *testing.B) {
  23. benchmarkTCP(b, true, true, "127.0.0.1:0")
  24. }
  25. func BenchmarkTCP6OneShot(b *testing.B) {
  26. if !supportsIPv6 {
  27. b.Skip("ipv6 is not supported")
  28. }
  29. benchmarkTCP(b, false, false, "[::1]:0")
  30. }
  31. func BenchmarkTCP6OneShotTimeout(b *testing.B) {
  32. if !supportsIPv6 {
  33. b.Skip("ipv6 is not supported")
  34. }
  35. benchmarkTCP(b, false, true, "[::1]:0")
  36. }
  37. func BenchmarkTCP6Persistent(b *testing.B) {
  38. if !supportsIPv6 {
  39. b.Skip("ipv6 is not supported")
  40. }
  41. benchmarkTCP(b, true, false, "[::1]:0")
  42. }
  43. func BenchmarkTCP6PersistentTimeout(b *testing.B) {
  44. if !supportsIPv6 {
  45. b.Skip("ipv6 is not supported")
  46. }
  47. benchmarkTCP(b, true, true, "[::1]:0")
  48. }
  49. func benchmarkTCP(b *testing.B, persistent, timeout bool, laddr string) {
  50. testHookUninstaller.Do(uninstallTestHooks)
  51. const msgLen = 512
  52. conns := b.N
  53. numConcurrent := runtime.GOMAXPROCS(-1) * 2
  54. msgs := 1
  55. if persistent {
  56. conns = numConcurrent
  57. msgs = b.N / conns
  58. if msgs == 0 {
  59. msgs = 1
  60. }
  61. if conns > b.N {
  62. conns = b.N
  63. }
  64. }
  65. sendMsg := func(c Conn, buf []byte) bool {
  66. n, err := c.Write(buf)
  67. if n != len(buf) || err != nil {
  68. b.Log(err)
  69. return false
  70. }
  71. return true
  72. }
  73. recvMsg := func(c Conn, buf []byte) bool {
  74. for read := 0; read != len(buf); {
  75. n, err := c.Read(buf)
  76. read += n
  77. if err != nil {
  78. b.Log(err)
  79. return false
  80. }
  81. }
  82. return true
  83. }
  84. ln, err := Listen("tcp", laddr)
  85. if err != nil {
  86. b.Fatal(err)
  87. }
  88. defer ln.Close()
  89. serverSem := make(chan bool, numConcurrent)
  90. // Acceptor.
  91. go func() {
  92. for {
  93. c, err := ln.Accept()
  94. if err != nil {
  95. break
  96. }
  97. serverSem <- true
  98. // Server connection.
  99. go func(c Conn) {
  100. defer func() {
  101. c.Close()
  102. <-serverSem
  103. }()
  104. if timeout {
  105. c.SetDeadline(time.Now().Add(time.Hour)) // Not intended to fire.
  106. }
  107. var buf [msgLen]byte
  108. for m := 0; m < msgs; m++ {
  109. if !recvMsg(c, buf[:]) || !sendMsg(c, buf[:]) {
  110. break
  111. }
  112. }
  113. }(c)
  114. }
  115. }()
  116. clientSem := make(chan bool, numConcurrent)
  117. for i := 0; i < conns; i++ {
  118. clientSem <- true
  119. // Client connection.
  120. go func() {
  121. defer func() {
  122. <-clientSem
  123. }()
  124. c, err := Dial("tcp", ln.Addr().String())
  125. if err != nil {
  126. b.Log(err)
  127. return
  128. }
  129. defer c.Close()
  130. if timeout {
  131. c.SetDeadline(time.Now().Add(time.Hour)) // Not intended to fire.
  132. }
  133. var buf [msgLen]byte
  134. for m := 0; m < msgs; m++ {
  135. if !sendMsg(c, buf[:]) || !recvMsg(c, buf[:]) {
  136. break
  137. }
  138. }
  139. }()
  140. }
  141. for i := 0; i < numConcurrent; i++ {
  142. clientSem <- true
  143. serverSem <- true
  144. }
  145. }
  146. func BenchmarkTCP4ConcurrentReadWrite(b *testing.B) {
  147. benchmarkTCPConcurrentReadWrite(b, "127.0.0.1:0")
  148. }
  149. func BenchmarkTCP6ConcurrentReadWrite(b *testing.B) {
  150. if !supportsIPv6 {
  151. b.Skip("ipv6 is not supported")
  152. }
  153. benchmarkTCPConcurrentReadWrite(b, "[::1]:0")
  154. }
  155. func benchmarkTCPConcurrentReadWrite(b *testing.B, laddr string) {
  156. testHookUninstaller.Do(uninstallTestHooks)
  157. // The benchmark creates GOMAXPROCS client/server pairs.
  158. // Each pair creates 4 goroutines: client reader/writer and server reader/writer.
  159. // The benchmark stresses concurrent reading and writing to the same connection.
  160. // Such pattern is used in net/http and net/rpc.
  161. b.StopTimer()
  162. P := runtime.GOMAXPROCS(0)
  163. N := b.N / P
  164. W := 1000
  165. // Setup P client/server connections.
  166. clients := make([]Conn, P)
  167. servers := make([]Conn, P)
  168. ln, err := Listen("tcp", laddr)
  169. if err != nil {
  170. b.Fatal(err)
  171. }
  172. defer ln.Close()
  173. done := make(chan bool)
  174. go func() {
  175. for p := 0; p < P; p++ {
  176. s, err := ln.Accept()
  177. if err != nil {
  178. b.Error(err)
  179. return
  180. }
  181. servers[p] = s
  182. }
  183. done <- true
  184. }()
  185. for p := 0; p < P; p++ {
  186. c, err := Dial("tcp", ln.Addr().String())
  187. if err != nil {
  188. b.Fatal(err)
  189. }
  190. clients[p] = c
  191. }
  192. <-done
  193. b.StartTimer()
  194. var wg sync.WaitGroup
  195. wg.Add(4 * P)
  196. for p := 0; p < P; p++ {
  197. // Client writer.
  198. go func(c Conn) {
  199. defer wg.Done()
  200. var buf [1]byte
  201. for i := 0; i < N; i++ {
  202. v := byte(i)
  203. for w := 0; w < W; w++ {
  204. v *= v
  205. }
  206. buf[0] = v
  207. _, err := c.Write(buf[:])
  208. if err != nil {
  209. b.Error(err)
  210. return
  211. }
  212. }
  213. }(clients[p])
  214. // Pipe between server reader and server writer.
  215. pipe := make(chan byte, 128)
  216. // Server reader.
  217. go func(s Conn) {
  218. defer wg.Done()
  219. var buf [1]byte
  220. for i := 0; i < N; i++ {
  221. _, err := s.Read(buf[:])
  222. if err != nil {
  223. b.Error(err)
  224. return
  225. }
  226. pipe <- buf[0]
  227. }
  228. }(servers[p])
  229. // Server writer.
  230. go func(s Conn) {
  231. defer wg.Done()
  232. var buf [1]byte
  233. for i := 0; i < N; i++ {
  234. v := <-pipe
  235. for w := 0; w < W; w++ {
  236. v *= v
  237. }
  238. buf[0] = v
  239. _, err := s.Write(buf[:])
  240. if err != nil {
  241. b.Error(err)
  242. return
  243. }
  244. }
  245. s.Close()
  246. }(servers[p])
  247. // Client reader.
  248. go func(c Conn) {
  249. defer wg.Done()
  250. var buf [1]byte
  251. for i := 0; i < N; i++ {
  252. _, err := c.Read(buf[:])
  253. if err != nil {
  254. b.Error(err)
  255. return
  256. }
  257. }
  258. c.Close()
  259. }(clients[p])
  260. }
  261. wg.Wait()
  262. }
  263. type resolveTCPAddrTest struct {
  264. network string
  265. litAddrOrName string
  266. addr *TCPAddr
  267. err error
  268. }
  269. var resolveTCPAddrTests = []resolveTCPAddrTest{
  270. {"tcp", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil},
  271. {"tcp4", "127.0.0.1:65535", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 65535}, nil},
  272. {"tcp", "[::1]:0", &TCPAddr{IP: ParseIP("::1"), Port: 0}, nil},
  273. {"tcp6", "[::1]:65535", &TCPAddr{IP: ParseIP("::1"), Port: 65535}, nil},
  274. {"tcp", "[::1%en0]:1", &TCPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil},
  275. {"tcp6", "[::1%911]:2", &TCPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil},
  276. {"", "127.0.0.1:0", &TCPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior
  277. {"", "[::1]:0", &TCPAddr{IP: ParseIP("::1"), Port: 0}, nil}, // Go 1.0 behavior
  278. {"tcp", ":12345", &TCPAddr{Port: 12345}, nil},
  279. {"http", "127.0.0.1:0", nil, UnknownNetworkError("http")},
  280. }
  281. func TestResolveTCPAddr(t *testing.T) {
  282. origTestHookLookupIP := testHookLookupIP
  283. defer func() { testHookLookupIP = origTestHookLookupIP }()
  284. testHookLookupIP = lookupLocalhost
  285. for i, tt := range resolveTCPAddrTests {
  286. addr, err := ResolveTCPAddr(tt.network, tt.litAddrOrName)
  287. if err != tt.err {
  288. t.Errorf("#%d: %v", i, err)
  289. } else if !reflect.DeepEqual(addr, tt.addr) {
  290. t.Errorf("#%d: got %#v; want %#v", i, addr, tt.addr)
  291. }
  292. if err != nil {
  293. continue
  294. }
  295. rtaddr, err := ResolveTCPAddr(addr.Network(), addr.String())
  296. if err != nil {
  297. t.Errorf("#%d: %v", i, err)
  298. } else if !reflect.DeepEqual(rtaddr, addr) {
  299. t.Errorf("#%d: got %#v; want %#v", i, rtaddr, addr)
  300. }
  301. }
  302. }
  303. var tcpListenerNameTests = []struct {
  304. net string
  305. laddr *TCPAddr
  306. }{
  307. {"tcp4", &TCPAddr{IP: IPv4(127, 0, 0, 1)}},
  308. {"tcp4", &TCPAddr{}},
  309. {"tcp4", nil},
  310. }
  311. func TestTCPListenerName(t *testing.T) {
  312. if testing.Short() || !*testExternal {
  313. t.Skip("avoid external network")
  314. }
  315. for _, tt := range tcpListenerNameTests {
  316. ln, err := ListenTCP(tt.net, tt.laddr)
  317. if err != nil {
  318. t.Fatal(err)
  319. }
  320. defer ln.Close()
  321. la := ln.Addr()
  322. if a, ok := la.(*TCPAddr); !ok || a.Port == 0 {
  323. t.Fatalf("got %v; expected a proper address with non-zero port number", la)
  324. }
  325. }
  326. }
  327. func TestIPv6LinkLocalUnicastTCP(t *testing.T) {
  328. if testing.Short() || !*testExternal {
  329. t.Skip("avoid external network")
  330. }
  331. if !supportsIPv6 {
  332. t.Skip("IPv6 is not supported")
  333. }
  334. for i, tt := range ipv6LinkLocalUnicastTCPTests {
  335. ln, err := Listen(tt.network, tt.address)
  336. if err != nil {
  337. // It might return "LookupHost returned no
  338. // suitable address" error on some platforms.
  339. t.Log(err)
  340. continue
  341. }
  342. ls, err := (&streamListener{Listener: ln}).newLocalServer()
  343. if err != nil {
  344. t.Fatal(err)
  345. }
  346. defer ls.teardown()
  347. ch := make(chan error, 1)
  348. handler := func(ls *localServer, ln Listener) { transponder(ln, ch) }
  349. if err := ls.buildup(handler); err != nil {
  350. t.Fatal(err)
  351. }
  352. if la, ok := ln.Addr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
  353. t.Fatalf("got %v; expected a proper address with zone identifier", la)
  354. }
  355. c, err := Dial(tt.network, ls.Listener.Addr().String())
  356. if err != nil {
  357. t.Fatal(err)
  358. }
  359. defer c.Close()
  360. if la, ok := c.LocalAddr().(*TCPAddr); !ok || !tt.nameLookup && la.Zone == "" {
  361. t.Fatalf("got %v; expected a proper address with zone identifier", la)
  362. }
  363. if ra, ok := c.RemoteAddr().(*TCPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
  364. t.Fatalf("got %v; expected a proper address with zone identifier", ra)
  365. }
  366. if _, err := c.Write([]byte("TCP OVER IPV6 LINKLOCAL TEST")); err != nil {
  367. t.Fatal(err)
  368. }
  369. b := make([]byte, 32)
  370. if _, err := c.Read(b); err != nil {
  371. t.Fatal(err)
  372. }
  373. for err := range ch {
  374. t.Errorf("#%d: %v", i, err)
  375. }
  376. }
  377. }
  378. func TestTCPConcurrentAccept(t *testing.T) {
  379. defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
  380. ln, err := Listen("tcp", "127.0.0.1:0")
  381. if err != nil {
  382. t.Fatal(err)
  383. }
  384. const N = 10
  385. var wg sync.WaitGroup
  386. wg.Add(N)
  387. for i := 0; i < N; i++ {
  388. go func() {
  389. for {
  390. c, err := ln.Accept()
  391. if err != nil {
  392. break
  393. }
  394. c.Close()
  395. }
  396. wg.Done()
  397. }()
  398. }
  399. attempts := 10 * N
  400. fails := 0
  401. d := &Dialer{Timeout: 200 * time.Millisecond}
  402. for i := 0; i < attempts; i++ {
  403. c, err := d.Dial("tcp", ln.Addr().String())
  404. if err != nil {
  405. fails++
  406. } else {
  407. c.Close()
  408. }
  409. }
  410. ln.Close()
  411. wg.Wait()
  412. if fails > attempts/9 { // see issues 7400 and 7541
  413. t.Fatalf("too many Dial failed: %v", fails)
  414. }
  415. if fails > 0 {
  416. t.Logf("# of failed Dials: %v", fails)
  417. }
  418. }
  419. func TestTCPReadWriteAllocs(t *testing.T) {
  420. t.Skip("skipping test on gccgo until escape analysis is turned on")
  421. switch runtime.GOOS {
  422. case "nacl", "windows":
  423. // NaCl needs to allocate pseudo file descriptor
  424. // stuff. See syscall/fd_nacl.go.
  425. // Windows uses closures and channels for IO
  426. // completion port-based netpoll. See fd_windows.go.
  427. t.Skipf("not supported on %s", runtime.GOOS)
  428. }
  429. ln, err := Listen("tcp", "127.0.0.1:0")
  430. if err != nil {
  431. t.Fatal(err)
  432. }
  433. defer ln.Close()
  434. var server Conn
  435. errc := make(chan error)
  436. go func() {
  437. var err error
  438. server, err = ln.Accept()
  439. errc <- err
  440. }()
  441. client, err := Dial("tcp", ln.Addr().String())
  442. if err != nil {
  443. t.Fatal(err)
  444. }
  445. defer client.Close()
  446. if err := <-errc; err != nil {
  447. t.Fatal(err)
  448. }
  449. defer server.Close()
  450. var buf [128]byte
  451. allocs := testing.AllocsPerRun(1000, func() {
  452. _, err := server.Write(buf[:])
  453. if err != nil {
  454. t.Fatal(err)
  455. }
  456. _, err = io.ReadFull(client, buf[:])
  457. if err != nil {
  458. t.Fatal(err)
  459. }
  460. })
  461. if allocs > 0 {
  462. t.Fatalf("got %v; want 0", allocs)
  463. }
  464. }
  465. func TestTCPStress(t *testing.T) {
  466. const conns = 2
  467. const msgLen = 512
  468. msgs := int(1e4)
  469. if testing.Short() {
  470. msgs = 1e2
  471. }
  472. sendMsg := func(c Conn, buf []byte) bool {
  473. n, err := c.Write(buf)
  474. if n != len(buf) || err != nil {
  475. t.Log(err)
  476. return false
  477. }
  478. return true
  479. }
  480. recvMsg := func(c Conn, buf []byte) bool {
  481. for read := 0; read != len(buf); {
  482. n, err := c.Read(buf)
  483. read += n
  484. if err != nil {
  485. t.Log(err)
  486. return false
  487. }
  488. }
  489. return true
  490. }
  491. ln, err := Listen("tcp", "127.0.0.1:0")
  492. if err != nil {
  493. t.Fatal(err)
  494. }
  495. defer ln.Close()
  496. // Acceptor.
  497. go func() {
  498. for {
  499. c, err := ln.Accept()
  500. if err != nil {
  501. break
  502. }
  503. // Server connection.
  504. go func(c Conn) {
  505. defer c.Close()
  506. var buf [msgLen]byte
  507. for m := 0; m < msgs; m++ {
  508. if !recvMsg(c, buf[:]) || !sendMsg(c, buf[:]) {
  509. break
  510. }
  511. }
  512. }(c)
  513. }
  514. }()
  515. done := make(chan bool)
  516. for i := 0; i < conns; i++ {
  517. // Client connection.
  518. go func() {
  519. defer func() {
  520. done <- true
  521. }()
  522. c, err := Dial("tcp", ln.Addr().String())
  523. if err != nil {
  524. t.Log(err)
  525. return
  526. }
  527. defer c.Close()
  528. var buf [msgLen]byte
  529. for m := 0; m < msgs; m++ {
  530. if !sendMsg(c, buf[:]) || !recvMsg(c, buf[:]) {
  531. break
  532. }
  533. }
  534. }()
  535. }
  536. for i := 0; i < conns; i++ {
  537. <-done
  538. }
  539. }