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