PageRenderTime 69ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/gofrontend/libgo/go/net/dial_test.go

http://github.com/axw/llgo
Go | 715 lines | 595 code | 62 blank | 58 comment | 192 complexity | 59f24626f55a09dcdfbb67cc2fbda5a0 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  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. "io"
  7. "net/internal/socktest"
  8. "runtime"
  9. "sync"
  10. "testing"
  11. "time"
  12. )
  13. var prohibitionaryDialArgTests = []struct {
  14. network string
  15. address string
  16. }{
  17. {"tcp6", "127.0.0.1"},
  18. {"tcp6", "::ffff:127.0.0.1"},
  19. }
  20. func TestProhibitionaryDialArg(t *testing.T) {
  21. switch runtime.GOOS {
  22. case "plan9":
  23. t.Skipf("not supported on %s", runtime.GOOS)
  24. }
  25. if testing.Short() || !*testExternal {
  26. t.Skip("avoid external network")
  27. }
  28. if !supportsIPv4map {
  29. t.Skip("mapping ipv4 address inside ipv6 address not supported")
  30. }
  31. ln, err := Listen("tcp", "[::]:0")
  32. if err != nil {
  33. t.Fatal(err)
  34. }
  35. defer ln.Close()
  36. _, port, err := SplitHostPort(ln.Addr().String())
  37. if err != nil {
  38. t.Fatal(err)
  39. }
  40. for i, tt := range prohibitionaryDialArgTests {
  41. c, err := Dial(tt.network, JoinHostPort(tt.address, port))
  42. if err == nil {
  43. c.Close()
  44. t.Errorf("#%d: %v", i, err)
  45. }
  46. }
  47. }
  48. func TestSelfConnect(t *testing.T) {
  49. if runtime.GOOS == "windows" {
  50. // TODO(brainman): do not know why it hangs.
  51. t.Skip("known-broken test on windows")
  52. }
  53. // Test that Dial does not honor self-connects.
  54. // See the comment in DialTCP.
  55. // Find a port that would be used as a local address.
  56. l, err := Listen("tcp", "127.0.0.1:0")
  57. if err != nil {
  58. t.Fatal(err)
  59. }
  60. c, err := Dial("tcp", l.Addr().String())
  61. if err != nil {
  62. t.Fatal(err)
  63. }
  64. addr := c.LocalAddr().String()
  65. c.Close()
  66. l.Close()
  67. // Try to connect to that address repeatedly.
  68. n := 100000
  69. if testing.Short() {
  70. n = 1000
  71. }
  72. switch runtime.GOOS {
  73. case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "solaris", "windows":
  74. // Non-Linux systems take a long time to figure
  75. // out that there is nothing listening on localhost.
  76. n = 100
  77. }
  78. for i := 0; i < n; i++ {
  79. c, err := DialTimeout("tcp", addr, time.Millisecond)
  80. if err == nil {
  81. if c.LocalAddr().String() == addr {
  82. t.Errorf("#%d: Dial %q self-connect", i, addr)
  83. } else {
  84. t.Logf("#%d: Dial %q succeeded - possibly racing with other listener", i, addr)
  85. }
  86. c.Close()
  87. }
  88. }
  89. }
  90. func TestDialTimeoutFDLeak(t *testing.T) {
  91. switch runtime.GOOS {
  92. case "plan9":
  93. t.Skipf("%s does not have full support of socktest", runtime.GOOS)
  94. }
  95. const T = 100 * time.Millisecond
  96. switch runtime.GOOS {
  97. case "plan9", "windows":
  98. origTestHookDialChannel := testHookDialChannel
  99. testHookDialChannel = func() { time.Sleep(2 * T) }
  100. defer func() { testHookDialChannel = origTestHookDialChannel }()
  101. if runtime.GOOS == "plan9" {
  102. break
  103. }
  104. fallthrough
  105. default:
  106. sw.Set(socktest.FilterConnect, func(so *socktest.Status) (socktest.AfterFilter, error) {
  107. time.Sleep(2 * T)
  108. return nil, errTimeout
  109. })
  110. defer sw.Set(socktest.FilterConnect, nil)
  111. }
  112. // Avoid tracking open-close jitterbugs between netFD and
  113. // socket that leads to confusion of information inside
  114. // socktest.Switch.
  115. // It may happen when the Dial call bumps against TCP
  116. // simultaneous open. See selfConnect in tcpsock_posix.go.
  117. defer func() {
  118. sw.Set(socktest.FilterClose, nil)
  119. forceCloseSockets()
  120. }()
  121. var mu sync.Mutex
  122. var attempts int
  123. sw.Set(socktest.FilterClose, func(so *socktest.Status) (socktest.AfterFilter, error) {
  124. mu.Lock()
  125. attempts++
  126. mu.Unlock()
  127. return nil, errTimedout
  128. })
  129. const N = 100
  130. var wg sync.WaitGroup
  131. wg.Add(N)
  132. for i := 0; i < N; i++ {
  133. go func() {
  134. defer wg.Done()
  135. // This dial never starts to send any SYN
  136. // segment because of above socket filter and
  137. // test hook.
  138. c, err := DialTimeout("tcp", "127.0.0.1:0", T)
  139. if err == nil {
  140. t.Errorf("unexpectedly established: tcp:%s->%s", c.LocalAddr(), c.RemoteAddr())
  141. c.Close()
  142. }
  143. }()
  144. }
  145. wg.Wait()
  146. if attempts < N {
  147. t.Errorf("got %d; want >= %d", attempts, N)
  148. }
  149. }
  150. func TestDialerDualStackFDLeak(t *testing.T) {
  151. switch runtime.GOOS {
  152. case "plan9":
  153. t.Skipf("%s does not have full support of socktest", runtime.GOOS)
  154. case "windows":
  155. t.Skipf("not implemented a way to cancel dial racers in TCP SYN-SENT state on %s", runtime.GOOS)
  156. }
  157. if !supportsIPv4 || !supportsIPv6 {
  158. t.Skip("both IPv4 and IPv6 are required")
  159. }
  160. origTestHookLookupIP := testHookLookupIP
  161. defer func() { testHookLookupIP = origTestHookLookupIP }()
  162. testHookLookupIP = lookupLocalhost
  163. handler := func(dss *dualStackServer, ln Listener) {
  164. for {
  165. c, err := ln.Accept()
  166. if err != nil {
  167. return
  168. }
  169. c.Close()
  170. }
  171. }
  172. dss, err := newDualStackServer([]streamListener{
  173. {network: "tcp4", address: "127.0.0.1"},
  174. {network: "tcp6", address: "::1"},
  175. })
  176. if err != nil {
  177. t.Fatal(err)
  178. }
  179. defer dss.teardown()
  180. if err := dss.buildup(handler); err != nil {
  181. t.Fatal(err)
  182. }
  183. before := sw.Sockets()
  184. const T = 100 * time.Millisecond
  185. const N = 10
  186. var wg sync.WaitGroup
  187. wg.Add(N)
  188. d := &Dialer{DualStack: true, Timeout: T}
  189. for i := 0; i < N; i++ {
  190. go func() {
  191. defer wg.Done()
  192. c, err := d.Dial("tcp", JoinHostPort("localhost", dss.port))
  193. if err != nil {
  194. t.Error(err)
  195. return
  196. }
  197. c.Close()
  198. }()
  199. }
  200. wg.Wait()
  201. time.Sleep(2 * T) // wait for the dial racers to stop
  202. after := sw.Sockets()
  203. if len(after) != len(before) {
  204. t.Errorf("got %d; want %d", len(after), len(before))
  205. }
  206. }
  207. // Define a pair of blackholed (IPv4, IPv6) addresses, for which dialTCP is
  208. // expected to hang until the timeout elapses. These addresses are reserved
  209. // for benchmarking by RFC 6890.
  210. const (
  211. slowDst4 = "192.18.0.254"
  212. slowDst6 = "2001:2::254"
  213. slowTimeout = 1 * time.Second
  214. )
  215. // In some environments, the slow IPs may be explicitly unreachable, and fail
  216. // more quickly than expected. This test hook prevents dialTCP from returning
  217. // before the deadline.
  218. func slowDialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, error) {
  219. c, err := dialTCP(net, laddr, raddr, deadline)
  220. if ParseIP(slowDst4).Equal(raddr.IP) || ParseIP(slowDst6).Equal(raddr.IP) {
  221. time.Sleep(deadline.Sub(time.Now()))
  222. }
  223. return c, err
  224. }
  225. func dialClosedPort() (actual, expected time.Duration) {
  226. // Estimate the expected time for this platform.
  227. // On Windows, dialing a closed port takes roughly 1 second,
  228. // but other platforms should be instantaneous.
  229. if runtime.GOOS == "windows" {
  230. expected = 1500 * time.Millisecond
  231. } else {
  232. expected = 95 * time.Millisecond
  233. }
  234. l, err := Listen("tcp", "127.0.0.1:0")
  235. if err != nil {
  236. return 999 * time.Hour, expected
  237. }
  238. addr := l.Addr().String()
  239. l.Close()
  240. // On OpenBSD, interference from TestSelfConnect is mysteriously
  241. // causing the first attempt to hang for a few seconds, so we throw
  242. // away the first result and keep the second.
  243. for i := 1; ; i++ {
  244. startTime := time.Now()
  245. c, err := Dial("tcp", addr)
  246. if err == nil {
  247. c.Close()
  248. }
  249. elapsed := time.Now().Sub(startTime)
  250. if i == 2 {
  251. return elapsed, expected
  252. }
  253. }
  254. }
  255. func TestDialParallel(t *testing.T) {
  256. if testing.Short() || !*testExternal {
  257. t.Skip("avoid external network")
  258. }
  259. if !supportsIPv4 || !supportsIPv6 {
  260. t.Skip("both IPv4 and IPv6 are required")
  261. }
  262. closedPortDelay, expectClosedPortDelay := dialClosedPort()
  263. if closedPortDelay > expectClosedPortDelay {
  264. t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
  265. }
  266. const instant time.Duration = 0
  267. const fallbackDelay = 200 * time.Millisecond
  268. // Some cases will run quickly when "connection refused" is fast,
  269. // or trigger the fallbackDelay on Windows. This value holds the
  270. // lesser of the two delays.
  271. var closedPortOrFallbackDelay time.Duration
  272. if closedPortDelay < fallbackDelay {
  273. closedPortOrFallbackDelay = closedPortDelay
  274. } else {
  275. closedPortOrFallbackDelay = fallbackDelay
  276. }
  277. origTestHookDialTCP := testHookDialTCP
  278. defer func() { testHookDialTCP = origTestHookDialTCP }()
  279. testHookDialTCP = slowDialTCP
  280. nCopies := func(s string, n int) []string {
  281. out := make([]string, n)
  282. for i := 0; i < n; i++ {
  283. out[i] = s
  284. }
  285. return out
  286. }
  287. var testCases = []struct {
  288. primaries []string
  289. fallbacks []string
  290. teardownNetwork string
  291. expectOk bool
  292. expectElapsed time.Duration
  293. }{
  294. // These should just work on the first try.
  295. {[]string{"127.0.0.1"}, []string{}, "", true, instant},
  296. {[]string{"::1"}, []string{}, "", true, instant},
  297. {[]string{"127.0.0.1", "::1"}, []string{slowDst6}, "tcp6", true, instant},
  298. {[]string{"::1", "127.0.0.1"}, []string{slowDst4}, "tcp4", true, instant},
  299. // Primary is slow; fallback should kick in.
  300. {[]string{slowDst4}, []string{"::1"}, "", true, fallbackDelay},
  301. // Skip a "connection refused" in the primary thread.
  302. {[]string{"127.0.0.1", "::1"}, []string{}, "tcp4", true, closedPortDelay},
  303. {[]string{"::1", "127.0.0.1"}, []string{}, "tcp6", true, closedPortDelay},
  304. // Skip a "connection refused" in the fallback thread.
  305. {[]string{slowDst4, slowDst6}, []string{"::1", "127.0.0.1"}, "tcp6", true, fallbackDelay + closedPortDelay},
  306. // Primary refused, fallback without delay.
  307. {[]string{"127.0.0.1"}, []string{"::1"}, "tcp4", true, closedPortOrFallbackDelay},
  308. {[]string{"::1"}, []string{"127.0.0.1"}, "tcp6", true, closedPortOrFallbackDelay},
  309. // Everything is refused.
  310. {[]string{"127.0.0.1"}, []string{}, "tcp4", false, closedPortDelay},
  311. // Nothing to do; fail instantly.
  312. {[]string{}, []string{}, "", false, instant},
  313. // Connecting to tons of addresses should not trip the deadline.
  314. {nCopies("::1", 1000), []string{}, "", true, instant},
  315. }
  316. handler := func(dss *dualStackServer, ln Listener) {
  317. for {
  318. c, err := ln.Accept()
  319. if err != nil {
  320. return
  321. }
  322. c.Close()
  323. }
  324. }
  325. // Convert a list of IP strings into TCPAddrs.
  326. makeAddrs := func(ips []string, port string) addrList {
  327. var out addrList
  328. for _, ip := range ips {
  329. addr, err := ResolveTCPAddr("tcp", JoinHostPort(ip, port))
  330. if err != nil {
  331. t.Fatal(err)
  332. }
  333. out = append(out, addr)
  334. }
  335. return out
  336. }
  337. for i, tt := range testCases {
  338. dss, err := newDualStackServer([]streamListener{
  339. {network: "tcp4", address: "127.0.0.1"},
  340. {network: "tcp6", address: "::1"},
  341. })
  342. if err != nil {
  343. t.Fatal(err)
  344. }
  345. defer dss.teardown()
  346. if err := dss.buildup(handler); err != nil {
  347. t.Fatal(err)
  348. }
  349. if tt.teardownNetwork != "" {
  350. // Destroy one of the listening sockets, creating an unreachable port.
  351. dss.teardownNetwork(tt.teardownNetwork)
  352. }
  353. primaries := makeAddrs(tt.primaries, dss.port)
  354. fallbacks := makeAddrs(tt.fallbacks, dss.port)
  355. d := Dialer{
  356. FallbackDelay: fallbackDelay,
  357. Timeout: slowTimeout,
  358. }
  359. ctx := &dialContext{
  360. Dialer: d,
  361. network: "tcp",
  362. address: "?",
  363. finalDeadline: d.deadline(time.Now()),
  364. }
  365. startTime := time.Now()
  366. c, err := dialParallel(ctx, primaries, fallbacks)
  367. elapsed := time.Now().Sub(startTime)
  368. if c != nil {
  369. c.Close()
  370. }
  371. if tt.expectOk && err != nil {
  372. t.Errorf("#%d: got %v; want nil", i, err)
  373. } else if !tt.expectOk && err == nil {
  374. t.Errorf("#%d: got nil; want non-nil", i)
  375. }
  376. expectElapsedMin := tt.expectElapsed - 95*time.Millisecond
  377. expectElapsedMax := tt.expectElapsed + 95*time.Millisecond
  378. if !(elapsed >= expectElapsedMin) {
  379. t.Errorf("#%d: got %v; want >= %v", i, elapsed, expectElapsedMin)
  380. } else if !(elapsed <= expectElapsedMax) {
  381. t.Errorf("#%d: got %v; want <= %v", i, elapsed, expectElapsedMax)
  382. }
  383. }
  384. // Wait for any slowDst4/slowDst6 connections to timeout.
  385. time.Sleep(slowTimeout * 3 / 2)
  386. }
  387. func lookupSlowFast(fn func(string) ([]IPAddr, error), host string) ([]IPAddr, error) {
  388. switch host {
  389. case "slow6loopback4":
  390. // Returns a slow IPv6 address, and a local IPv4 address.
  391. return []IPAddr{
  392. {IP: ParseIP(slowDst6)},
  393. {IP: ParseIP("127.0.0.1")},
  394. }, nil
  395. default:
  396. return fn(host)
  397. }
  398. }
  399. func TestDialerFallbackDelay(t *testing.T) {
  400. if testing.Short() || !*testExternal {
  401. t.Skip("avoid external network")
  402. }
  403. if !supportsIPv4 || !supportsIPv6 {
  404. t.Skip("both IPv4 and IPv6 are required")
  405. }
  406. origTestHookLookupIP := testHookLookupIP
  407. defer func() { testHookLookupIP = origTestHookLookupIP }()
  408. testHookLookupIP = lookupSlowFast
  409. origTestHookDialTCP := testHookDialTCP
  410. defer func() { testHookDialTCP = origTestHookDialTCP }()
  411. testHookDialTCP = slowDialTCP
  412. var testCases = []struct {
  413. dualstack bool
  414. delay time.Duration
  415. expectElapsed time.Duration
  416. }{
  417. // Use a very brief delay, which should fallback immediately.
  418. {true, 1 * time.Nanosecond, 0},
  419. // Use a 200ms explicit timeout.
  420. {true, 200 * time.Millisecond, 200 * time.Millisecond},
  421. // The default is 300ms.
  422. {true, 0, 300 * time.Millisecond},
  423. // This case is last, in order to wait for hanging slowDst6 connections.
  424. {false, 0, slowTimeout},
  425. }
  426. handler := func(dss *dualStackServer, ln Listener) {
  427. for {
  428. c, err := ln.Accept()
  429. if err != nil {
  430. return
  431. }
  432. c.Close()
  433. }
  434. }
  435. dss, err := newDualStackServer([]streamListener{
  436. {network: "tcp", address: "127.0.0.1"},
  437. })
  438. if err != nil {
  439. t.Fatal(err)
  440. }
  441. defer dss.teardown()
  442. if err := dss.buildup(handler); err != nil {
  443. t.Fatal(err)
  444. }
  445. for i, tt := range testCases {
  446. d := &Dialer{DualStack: tt.dualstack, FallbackDelay: tt.delay, Timeout: slowTimeout}
  447. startTime := time.Now()
  448. c, err := d.Dial("tcp", JoinHostPort("slow6loopback4", dss.port))
  449. elapsed := time.Now().Sub(startTime)
  450. if err == nil {
  451. c.Close()
  452. } else if tt.dualstack {
  453. t.Error(err)
  454. }
  455. expectMin := tt.expectElapsed - 1*time.Millisecond
  456. expectMax := tt.expectElapsed + 95*time.Millisecond
  457. if !(elapsed >= expectMin) {
  458. t.Errorf("#%d: got %v; want >= %v", i, elapsed, expectMin)
  459. }
  460. if !(elapsed <= expectMax) {
  461. t.Errorf("#%d: got %v; want <= %v", i, elapsed, expectMax)
  462. }
  463. }
  464. }
  465. func TestDialSerialAsyncSpuriousConnection(t *testing.T) {
  466. ln, err := newLocalListener("tcp")
  467. if err != nil {
  468. t.Fatal(err)
  469. }
  470. defer ln.Close()
  471. d := Dialer{}
  472. ctx := &dialContext{
  473. Dialer: d,
  474. network: "tcp",
  475. address: "?",
  476. finalDeadline: d.deadline(time.Now()),
  477. }
  478. results := make(chan dialResult)
  479. cancel := make(chan struct{})
  480. // Spawn a connection in the background.
  481. go dialSerialAsync(ctx, addrList{ln.Addr()}, nil, cancel, results)
  482. // Receive it at the server.
  483. c, err := ln.Accept()
  484. if err != nil {
  485. t.Fatal(err)
  486. }
  487. defer c.Close()
  488. // Tell dialSerialAsync that someone else won the race.
  489. close(cancel)
  490. // The connection should close itself, without sending data.
  491. c.SetReadDeadline(time.Now().Add(1 * time.Second))
  492. var b [1]byte
  493. if _, err := c.Read(b[:]); err != io.EOF {
  494. t.Errorf("got %v; want %v", err, io.EOF)
  495. }
  496. }
  497. func TestDialerPartialDeadline(t *testing.T) {
  498. now := time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
  499. var testCases = []struct {
  500. now time.Time
  501. deadline time.Time
  502. addrs int
  503. expectDeadline time.Time
  504. expectErr error
  505. }{
  506. // Regular division.
  507. {now, now.Add(12 * time.Second), 1, now.Add(12 * time.Second), nil},
  508. {now, now.Add(12 * time.Second), 2, now.Add(6 * time.Second), nil},
  509. {now, now.Add(12 * time.Second), 3, now.Add(4 * time.Second), nil},
  510. // Bump against the 2-second sane minimum.
  511. {now, now.Add(12 * time.Second), 999, now.Add(2 * time.Second), nil},
  512. // Total available is now below the sane minimum.
  513. {now, now.Add(1900 * time.Millisecond), 999, now.Add(1900 * time.Millisecond), nil},
  514. // Null deadline.
  515. {now, noDeadline, 1, noDeadline, nil},
  516. // Step the clock forward and cross the deadline.
  517. {now.Add(-1 * time.Millisecond), now, 1, now, nil},
  518. {now.Add(0 * time.Millisecond), now, 1, noDeadline, errTimeout},
  519. {now.Add(1 * time.Millisecond), now, 1, noDeadline, errTimeout},
  520. }
  521. for i, tt := range testCases {
  522. deadline, err := partialDeadline(tt.now, tt.deadline, tt.addrs)
  523. if err != tt.expectErr {
  524. t.Errorf("#%d: got %v; want %v", i, err, tt.expectErr)
  525. }
  526. if deadline != tt.expectDeadline {
  527. t.Errorf("#%d: got %v; want %v", i, deadline, tt.expectDeadline)
  528. }
  529. }
  530. }
  531. func TestDialerLocalAddr(t *testing.T) {
  532. ch := make(chan error, 1)
  533. handler := func(ls *localServer, ln Listener) {
  534. c, err := ln.Accept()
  535. if err != nil {
  536. ch <- err
  537. return
  538. }
  539. defer c.Close()
  540. ch <- nil
  541. }
  542. ls, err := newLocalServer("tcp")
  543. if err != nil {
  544. t.Fatal(err)
  545. }
  546. defer ls.teardown()
  547. if err := ls.buildup(handler); err != nil {
  548. t.Fatal(err)
  549. }
  550. laddr, err := ResolveTCPAddr(ls.Listener.Addr().Network(), ls.Listener.Addr().String())
  551. if err != nil {
  552. t.Fatal(err)
  553. }
  554. laddr.Port = 0
  555. d := &Dialer{LocalAddr: laddr}
  556. c, err := d.Dial(ls.Listener.Addr().Network(), ls.Addr().String())
  557. if err != nil {
  558. t.Fatal(err)
  559. }
  560. defer c.Close()
  561. c.Read(make([]byte, 1))
  562. err = <-ch
  563. if err != nil {
  564. t.Error(err)
  565. }
  566. }
  567. func TestDialerDualStack(t *testing.T) {
  568. if !supportsIPv4 || !supportsIPv6 {
  569. t.Skip("both IPv4 and IPv6 are required")
  570. }
  571. closedPortDelay, expectClosedPortDelay := dialClosedPort()
  572. if closedPortDelay > expectClosedPortDelay {
  573. t.Errorf("got %v; want <= %v", closedPortDelay, expectClosedPortDelay)
  574. }
  575. origTestHookLookupIP := testHookLookupIP
  576. defer func() { testHookLookupIP = origTestHookLookupIP }()
  577. testHookLookupIP = lookupLocalhost
  578. handler := func(dss *dualStackServer, ln Listener) {
  579. for {
  580. c, err := ln.Accept()
  581. if err != nil {
  582. return
  583. }
  584. c.Close()
  585. }
  586. }
  587. var timeout = 100*time.Millisecond + closedPortDelay
  588. for _, dualstack := range []bool{false, true} {
  589. dss, err := newDualStackServer([]streamListener{
  590. {network: "tcp4", address: "127.0.0.1"},
  591. {network: "tcp6", address: "::1"},
  592. })
  593. if err != nil {
  594. t.Fatal(err)
  595. }
  596. defer dss.teardown()
  597. if err := dss.buildup(handler); err != nil {
  598. t.Fatal(err)
  599. }
  600. d := &Dialer{DualStack: dualstack, Timeout: timeout}
  601. for range dss.lns {
  602. c, err := d.Dial("tcp", JoinHostPort("localhost", dss.port))
  603. if err != nil {
  604. t.Error(err)
  605. continue
  606. }
  607. switch addr := c.LocalAddr().(*TCPAddr); {
  608. case addr.IP.To4() != nil:
  609. dss.teardownNetwork("tcp4")
  610. case addr.IP.To16() != nil && addr.IP.To4() == nil:
  611. dss.teardownNetwork("tcp6")
  612. }
  613. c.Close()
  614. }
  615. }
  616. time.Sleep(timeout * 3 / 2) // wait for the dial racers to stop
  617. }
  618. func TestDialerKeepAlive(t *testing.T) {
  619. handler := func(ls *localServer, ln Listener) {
  620. for {
  621. c, err := ln.Accept()
  622. if err != nil {
  623. return
  624. }
  625. c.Close()
  626. }
  627. }
  628. ls, err := newLocalServer("tcp")
  629. if err != nil {
  630. t.Fatal(err)
  631. }
  632. defer ls.teardown()
  633. if err := ls.buildup(handler); err != nil {
  634. t.Fatal(err)
  635. }
  636. defer func() { testHookSetKeepAlive = func() {} }()
  637. for _, keepAlive := range []bool{false, true} {
  638. got := false
  639. testHookSetKeepAlive = func() { got = true }
  640. var d Dialer
  641. if keepAlive {
  642. d.KeepAlive = 30 * time.Second
  643. }
  644. c, err := d.Dial("tcp", ls.Listener.Addr().String())
  645. if err != nil {
  646. t.Fatal(err)
  647. }
  648. c.Close()
  649. if got != keepAlive {
  650. t.Errorf("Dialer.KeepAlive = %v: SetKeepAlive called = %v, want %v", d.KeepAlive, got, !got)
  651. }
  652. }
  653. }