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