Fix "PR c++/92804 ICE trying to use concept as a nested-name-specifier"
[official-gcc.git] / libgo / go / net / dial_unix_test.go
blob1891d8c44301c84cbf54f0d28b342b47768d1075
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.
5 // +build aix darwin dragonfly freebsd hurd linux netbsd openbsd solaris
7 package net
9 import (
10 "context"
11 "syscall"
12 "testing"
13 "time"
16 // Issue 16523
17 func TestDialContextCancelRace(t *testing.T) {
18 oldConnectFunc := connectFunc
19 oldGetsockoptIntFunc := getsockoptIntFunc
20 oldTestHookCanceledDial := testHookCanceledDial
21 defer func() {
22 connectFunc = oldConnectFunc
23 getsockoptIntFunc = oldGetsockoptIntFunc
24 testHookCanceledDial = oldTestHookCanceledDial
25 }()
27 ln, err := newLocalListener("tcp")
28 if err != nil {
29 t.Fatal(err)
31 listenerDone := make(chan struct{})
32 go func() {
33 defer close(listenerDone)
34 c, err := ln.Accept()
35 if err == nil {
36 c.Close()
38 }()
39 defer func() { <-listenerDone }()
40 defer ln.Close()
42 sawCancel := make(chan bool, 1)
43 testHookCanceledDial = func() {
44 sawCancel <- true
47 ctx, cancelCtx := context.WithCancel(context.Background())
49 connectFunc = func(fd int, addr syscall.Sockaddr) error {
50 err := oldConnectFunc(fd, addr)
51 t.Logf("connect(%d, addr) = %v", fd, err)
52 if err == nil {
53 // On some operating systems, localhost
54 // connects _sometimes_ succeed immediately.
55 // Prevent that, so we exercise the code path
56 // we're interested in testing. This seems
57 // harmless. It makes FreeBSD 10.10 work when
58 // run with many iterations. It failed about
59 // half the time previously.
60 return syscall.EINPROGRESS
62 return err
65 getsockoptIntFunc = func(fd, level, opt int) (val int, err error) {
66 val, err = oldGetsockoptIntFunc(fd, level, opt)
67 t.Logf("getsockoptIntFunc(%d, %d, %d) = (%v, %v)", fd, level, opt, val, err)
68 if level == syscall.SOL_SOCKET && opt == syscall.SO_ERROR && err == nil && val == 0 {
69 t.Logf("canceling context")
71 // Cancel the context at just the moment which
72 // caused the race in issue 16523.
73 cancelCtx()
75 // And wait for the "interrupter" goroutine to
76 // cancel the dial by messing with its write
77 // timeout before returning.
78 select {
79 case <-sawCancel:
80 t.Logf("saw cancel")
81 case <-time.After(5 * time.Second):
82 t.Errorf("didn't see cancel after 5 seconds")
85 return
88 var d Dialer
89 c, err := d.DialContext(ctx, "tcp", ln.Addr().String())
90 if err == nil {
91 c.Close()
92 t.Fatal("unexpected successful dial; want context canceled error")
95 select {
96 case <-ctx.Done():
97 case <-time.After(5 * time.Second):
98 t.Fatal("expected context to be canceled")
101 oe, ok := err.(*OpError)
102 if !ok || oe.Op != "dial" {
103 t.Fatalf("Dial error = %#v; want dial *OpError", err)
106 if oe.Err != errCanceled {
107 t.Errorf("DialContext = (%v, %v); want OpError with error %v", c, err, errCanceled)