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