github.com/shijuvar/go@v0.0.0-20141209052335-e8f13700b70c/src/net/net_windows_test.go (about) 1 // Copyright 2014 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 package net 6 7 import ( 8 "bufio" 9 "fmt" 10 "io" 11 "os" 12 "os/exec" 13 "syscall" 14 "testing" 15 "time" 16 ) 17 18 func TestAcceptIgnoreSomeErrors(t *testing.T) { 19 t.Skip("skipping temporarily, see issue 8662") 20 21 recv := func(ln Listener) (string, error) { 22 c, err := ln.Accept() 23 if err != nil { 24 // Display windows errno in error message. 25 operr, ok := err.(*OpError) 26 if !ok { 27 return "", err 28 } 29 errno, ok := operr.Err.(syscall.Errno) 30 if !ok { 31 return "", err 32 } 33 return "", fmt.Errorf("%v (windows errno=%d)", err, errno) 34 } 35 defer c.Close() 36 37 b := make([]byte, 100) 38 n, err := c.Read(b) 39 if err != nil && err != io.EOF { 40 return "", err 41 } 42 return string(b[:n]), nil 43 } 44 45 send := func(addr string, data string) error { 46 c, err := Dial("tcp", addr) 47 if err != nil { 48 return err 49 } 50 defer c.Close() 51 52 b := []byte(data) 53 n, err := c.Write(b) 54 if err != nil { 55 return err 56 } 57 if n != len(b) { 58 return fmt.Errorf(`Only %d chars of string "%s" sent`, n, data) 59 } 60 return nil 61 } 62 63 if envaddr := os.Getenv("GOTEST_DIAL_ADDR"); envaddr != "" { 64 // In child process. 65 c, err := Dial("tcp", envaddr) 66 if err != nil { 67 t.Fatalf("Dial failed: %v", err) 68 } 69 fmt.Printf("sleeping\n") 70 time.Sleep(time.Minute) // process will be killed here 71 c.Close() 72 } 73 74 ln, err := Listen("tcp", "127.0.0.1:0") 75 if err != nil { 76 t.Fatalf("Listen failed: %v", err) 77 } 78 defer ln.Close() 79 80 // Start child process that connects to our listener. 81 cmd := exec.Command(os.Args[0], "-test.run=TestAcceptIgnoreSomeErrors") 82 cmd.Env = append(os.Environ(), "GOTEST_DIAL_ADDR="+ln.Addr().String()) 83 stdout, err := cmd.StdoutPipe() 84 if err != nil { 85 t.Fatalf("cmd.StdoutPipe failed: %v", err) 86 } 87 err = cmd.Start() 88 if err != nil { 89 t.Fatalf("cmd.Start failed: %v\n", err) 90 } 91 outReader := bufio.NewReader(stdout) 92 for { 93 s, err := outReader.ReadString('\n') 94 if err != nil { 95 t.Fatalf("reading stdout failed: %v", err) 96 } 97 if s == "sleeping\n" { 98 break 99 } 100 } 101 defer cmd.Wait() // ignore error - we know it is getting killed 102 103 const alittle = 100 * time.Millisecond 104 time.Sleep(alittle) 105 cmd.Process.Kill() // the only way to trigger the errors 106 time.Sleep(alittle) 107 108 // Send second connection data (with delay in a separate goroutine). 109 result := make(chan error) 110 go func() { 111 time.Sleep(alittle) 112 err := send(ln.Addr().String(), "abc") 113 if err != nil { 114 result <- err 115 } 116 result <- nil 117 }() 118 defer func() { 119 err := <-result 120 if err != nil { 121 t.Fatalf("send failed: %v", err) 122 } 123 }() 124 125 // Receive first or second connection. 126 s, err := recv(ln) 127 if err != nil { 128 t.Fatalf("recv failed: %v", err) 129 } 130 switch s { 131 case "": 132 // First connection data is received, lets get second connection data. 133 case "abc": 134 // First connection is lost forever, but that is ok. 135 return 136 default: 137 t.Fatalf(`"%s" received from recv, but "" or "abc" expected`, s) 138 } 139 140 // Get second connection data. 141 s, err = recv(ln) 142 if err != nil { 143 t.Fatalf("recv failed: %v", err) 144 } 145 if s != "abc" { 146 t.Fatalf(`"%s" received from recv, but "abc" expected`, s) 147 } 148 }