@@ -10,10 +10,13 @@ package http2
10
10
import (
11
11
"bytes"
12
12
"context"
13
+ "crypto/tls"
13
14
"fmt"
14
15
"io"
16
+ "net"
15
17
"net/http"
16
18
"reflect"
19
+ "sync"
17
20
"sync/atomic"
18
21
"testing"
19
22
"time"
@@ -79,6 +82,56 @@ func TestTestClientConn(t *testing.T) {
79
82
rt .wantBody (nil )
80
83
}
81
84
85
+ // TestConnectTimeout tests that a request does not exceed request timeout + dial timeout
86
+ func TestConnectTimeout (t * testing.T ) {
87
+ tr := & Transport {
88
+ DialTLSContext : func (ctx context.Context , network , addr string , cfg * tls.Config ) (net.Conn , error ) {
89
+ // mock a net dialler with 1s timeout, encountering network issue
90
+ // keeping dialing until timeout
91
+ var dialer = net.Dialer {Timeout : time .Duration (- 1 )}
92
+ select {
93
+ case <- time .After (time .Second ):
94
+ case <- ctx .Done ():
95
+ }
96
+ return dialer .DialContext (ctx , network , addr )
97
+ },
98
+ AllowHTTP : true ,
99
+ }
100
+
101
+ var sg sync.WaitGroup
102
+ parentCtx , cancel := context .WithCancel (context .Background ())
103
+ defer cancel ()
104
+
105
+ for j := 0 ; j < 2 ; j ++ {
106
+ sg .Add (1 )
107
+ go func () {
108
+ for i := 0 ; i < 10000 ; i ++ {
109
+ sg .Add (1 )
110
+ go func () {
111
+ ctx , _ := context .WithTimeout (parentCtx , time .Second )
112
+ req , err := http .NewRequestWithContext (ctx , "GET" , "http://127.0.0.1:80" , nil )
113
+ if err != nil {
114
+ t .Errorf ("NewRequest: %v" , err )
115
+ }
116
+
117
+ start := time .Now ()
118
+ tr .RoundTrip (req )
119
+ duration := time .Since (start )
120
+ // duration should not exceed request timeout + dial timeout
121
+ if duration > 2 * time .Second {
122
+ t .Errorf ("RoundTrip took %s; want <2s" , duration .String ())
123
+ }
124
+ sg .Done ()
125
+ }()
126
+ time .Sleep (1 * time .Millisecond )
127
+ }
128
+ sg .Done ()
129
+ }()
130
+ }
131
+
132
+ sg .Wait ()
133
+ }
134
+
82
135
// A testClientConn allows testing ClientConn.RoundTrip against a fake server.
83
136
//
84
137
// A test using testClientConn consists of:
0 commit comments