tcpsock_unix_test.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright 2016 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 && !plan9 && !windows
  5. package net
  6. import (
  7. "context"
  8. "math/rand"
  9. "runtime"
  10. "sync"
  11. "syscall"
  12. "testing"
  13. "time"
  14. )
  15. // See golang.org/issue/14548.
  16. func TestTCPSpuriousConnSetupCompletion(t *testing.T) {
  17. if testing.Short() {
  18. t.Skip("skipping in short mode")
  19. }
  20. ln := newLocalListener(t, "tcp")
  21. var wg sync.WaitGroup
  22. wg.Add(1)
  23. go func(ln Listener) {
  24. defer wg.Done()
  25. for {
  26. c, err := ln.Accept()
  27. if err != nil {
  28. return
  29. }
  30. wg.Add(1)
  31. go func(c Conn) {
  32. var b [1]byte
  33. c.Read(b[:])
  34. c.Close()
  35. wg.Done()
  36. }(c)
  37. }
  38. }(ln)
  39. attempts := int(1e4) // larger is better
  40. wg.Add(attempts)
  41. throttle := make(chan struct{}, runtime.GOMAXPROCS(-1)*2)
  42. for i := 0; i < attempts; i++ {
  43. throttle <- struct{}{}
  44. go func(i int) {
  45. defer func() {
  46. <-throttle
  47. wg.Done()
  48. }()
  49. d := Dialer{Timeout: 50 * time.Millisecond}
  50. c, err := d.Dial(ln.Addr().Network(), ln.Addr().String())
  51. if err != nil {
  52. if perr := parseDialError(err); perr != nil {
  53. t.Errorf("#%d: %v (original error: %v)", i, perr, err)
  54. }
  55. return
  56. }
  57. var b [1]byte
  58. if _, err := c.Write(b[:]); err != nil {
  59. if perr := parseWriteError(err); perr != nil {
  60. t.Errorf("#%d: %v", i, err)
  61. }
  62. if samePlatformError(err, syscall.ENOTCONN) {
  63. t.Errorf("#%d: %v", i, err)
  64. }
  65. }
  66. c.Close()
  67. }(i)
  68. }
  69. ln.Close()
  70. wg.Wait()
  71. }
  72. // Issue 19289.
  73. // Test that a canceled Dial does not cause a subsequent Dial to succeed.
  74. func TestTCPSpuriousConnSetupCompletionWithCancel(t *testing.T) {
  75. mustHaveExternalNetwork(t)
  76. defer dnsWaitGroup.Wait()
  77. t.Parallel()
  78. const tries = 10000
  79. var wg sync.WaitGroup
  80. wg.Add(tries * 2)
  81. sem := make(chan bool, 5)
  82. for i := 0; i < tries; i++ {
  83. sem <- true
  84. ctx, cancel := context.WithCancel(context.Background())
  85. go func() {
  86. defer wg.Done()
  87. time.Sleep(time.Duration(rand.Int63n(int64(5 * time.Millisecond))))
  88. cancel()
  89. }()
  90. go func(i int) {
  91. defer wg.Done()
  92. var dialer Dialer
  93. // Try to connect to a real host on a port
  94. // that it is not listening on.
  95. _, err := dialer.DialContext(ctx, "tcp", "golang.org:3")
  96. if err == nil {
  97. t.Errorf("Dial to unbound port succeeded on attempt %d", i)
  98. }
  99. <-sem
  100. }(i)
  101. }
  102. wg.Wait()
  103. }