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  }