...

Source file src/net/tcpsock_unix_test.go

Documentation: net

		 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  // +build !js,!plan9,!windows
		 7  
		 8  package net
		 9  
		10  import (
		11  	"context"
		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  	mustHaveExternalNetwork(t)
		88  
		89  	defer dnsWaitGroup.Wait()
		90  	t.Parallel()
		91  	const tries = 10000
		92  	var wg sync.WaitGroup
		93  	wg.Add(tries * 2)
		94  	sem := make(chan bool, 5)
		95  	for i := 0; i < tries; i++ {
		96  		sem <- true
		97  		ctx, cancel := context.WithCancel(context.Background())
		98  		go func() {
		99  			defer wg.Done()
	 100  			time.Sleep(time.Duration(rand.Int63n(int64(5 * time.Millisecond))))
	 101  			cancel()
	 102  		}()
	 103  		go func(i int) {
	 104  			defer wg.Done()
	 105  			var dialer Dialer
	 106  			// Try to connect to a real host on a port
	 107  			// that it is not listening on.
	 108  			_, err := dialer.DialContext(ctx, "tcp", "golang.org:3")
	 109  			if err == nil {
	 110  				t.Errorf("Dial to unbound port succeeded on attempt %d", i)
	 111  			}
	 112  			<-sem
	 113  		}(i)
	 114  	}
	 115  	wg.Wait()
	 116  }
	 117  

View as plain text