@@ -45,6 +45,7 @@ import (
45
45
"google.golang.org/grpc/internal/grpctest"
46
46
"google.golang.org/grpc/internal/leakcheck"
47
47
"google.golang.org/grpc/internal/testutils"
48
+ "google.golang.org/grpc/metadata"
48
49
"google.golang.org/grpc/resolver"
49
50
"google.golang.org/grpc/status"
50
51
)
@@ -2136,6 +2137,70 @@ func (s) TestHeadersHTTPStatusGRPCStatus(t *testing.T) {
2136
2137
}
2137
2138
}
2138
2139
2140
+ func (s ) TestWriteHeaderConnectionError (t * testing.T ) {
2141
+ server , client , cancel := setUp (t , 0 , notifyCall )
2142
+ defer cancel ()
2143
+ defer server .stop ()
2144
+
2145
+ waitWhileTrue (t , func () (bool , error ) {
2146
+ server .mu .Lock ()
2147
+ defer server .mu .Unlock ()
2148
+
2149
+ if len (server .conns ) == 0 {
2150
+ return true , fmt .Errorf ("timed-out while waiting for connection to be created on the server" )
2151
+ }
2152
+ return false , nil
2153
+ })
2154
+
2155
+ server .mu .Lock ()
2156
+
2157
+ if len (server .conns ) != 1 {
2158
+ t .Fatalf ("Server has %d connections from the client, want 1" , len (server .conns ))
2159
+ }
2160
+
2161
+ // Get the server transport for the connecton to the client.
2162
+ var serverTransport * http2Server
2163
+ for k := range server .conns {
2164
+ serverTransport = k .(* http2Server )
2165
+ }
2166
+ notifyChan := make (chan struct {})
2167
+ server .h .notify = notifyChan
2168
+ server .mu .Unlock ()
2169
+
2170
+ ctx , cancel := context .WithTimeout (context .Background (), defaultTestTimeout )
2171
+ defer cancel ()
2172
+ cstream , err := client .NewStream (ctx , & CallHdr {})
2173
+ if err != nil {
2174
+ t .Fatalf ("Client failed to create first stream. Err: %v" , err )
2175
+ }
2176
+
2177
+ <- notifyChan // Wait for server stream to be established.
2178
+ var sstream * Stream
2179
+ // Access stream on the server.
2180
+ serverTransport .mu .Lock ()
2181
+ for _ , v := range serverTransport .activeStreams {
2182
+ if v .id == cstream .id {
2183
+ sstream = v
2184
+ }
2185
+ }
2186
+ serverTransport .mu .Unlock ()
2187
+ if sstream == nil {
2188
+ t .Fatalf ("Didn't find stream corresponding to client cstream.id: %v on the server" , cstream .id )
2189
+ }
2190
+
2191
+ client .Close (fmt .Errorf ("closed manually by test" ))
2192
+
2193
+ // Wait for server transport to be closed.
2194
+ <- serverTransport .done
2195
+
2196
+ // Write header on a closed server transport.
2197
+ err = serverTransport .WriteHeader (sstream , metadata.MD {})
2198
+ st := status .Convert (err )
2199
+ if st .Code () != codes .Unavailable {
2200
+ t .Fatalf ("WriteHeader() failed with status code %s, want %s" , st .Code (), codes .Unavailable )
2201
+ }
2202
+ }
2203
+
2139
2204
func (s ) TestPingPong1B (t * testing.T ) {
2140
2205
runPingPongTest (t , 1 )
2141
2206
}
0 commit comments