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