Home | History | Annotate | Download | only in 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 // +build darwin
      6 
      7 package net
      8 
      9 import (
     10 	"runtime"
     11 	"sync"
     12 	"syscall"
     13 	"testing"
     14 	"time"
     15 )
     16 
     17 // See golang.org/issue/14548.
     18 func TestTCPSpuriousConnSetupCompletion(t *testing.T) {
     19 	if testing.Short() {
     20 		t.Skip("skipping in short mode")
     21 	}
     22 
     23 	ln, err := newLocalListener("tcp")
     24 	if err != nil {
     25 		t.Fatal(err)
     26 	}
     27 	var wg sync.WaitGroup
     28 	wg.Add(1)
     29 	go func(ln Listener) {
     30 		defer wg.Done()
     31 		for {
     32 			c, err := ln.Accept()
     33 			if err != nil {
     34 				return
     35 			}
     36 			wg.Add(1)
     37 			go func(c Conn) {
     38 				var b [1]byte
     39 				c.Read(b[:])
     40 				c.Close()
     41 				wg.Done()
     42 			}(c)
     43 		}
     44 	}(ln)
     45 
     46 	attempts := int(1e4) // larger is better
     47 	wg.Add(attempts)
     48 	throttle := make(chan struct{}, runtime.GOMAXPROCS(-1)*2)
     49 	for i := 0; i < attempts; i++ {
     50 		throttle <- struct{}{}
     51 		go func(i int) {
     52 			defer func() {
     53 				<-throttle
     54 				wg.Done()
     55 			}()
     56 			d := Dialer{Timeout: 50 * time.Millisecond}
     57 			c, err := d.Dial(ln.Addr().Network(), ln.Addr().String())
     58 			if err != nil {
     59 				if perr := parseDialError(err); perr != nil {
     60 					t.Errorf("#%d: %v (original error: %v)", i, perr, err)
     61 				}
     62 				return
     63 			}
     64 			var b [1]byte
     65 			if _, err := c.Write(b[:]); err != nil {
     66 				if perr := parseWriteError(err); perr != nil {
     67 					t.Errorf("#%d: %v", i, err)
     68 				}
     69 				if samePlatformError(err, syscall.ENOTCONN) {
     70 					t.Errorf("#%d: %v", i, err)
     71 				}
     72 			}
     73 			c.Close()
     74 		}(i)
     75 	}
     76 
     77 	ln.Close()
     78 	wg.Wait()
     79 }
     80