@@ -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,69 @@ 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
+ if len (server .conns ) != 1 {
2156
+ t .Fatal ("Server must have an active connection for the client." )
2157
+ }
2158
+
2159
+ // Get the server transfort for the connecton to the client
2160
+ var serverTransport * http2Server
2161
+ server .mu .Lock ()
2162
+ for k := range server .conns {
2163
+ serverTransport = k .(* http2Server )
2164
+ }
2165
+ notifyChan := make (chan struct {})
2166
+ server .h .notify = notifyChan
2167
+ server .mu .Unlock ()
2168
+
2169
+ ctx , cancel := context .WithTimeout (context .Background (), defaultTestTimeout )
2170
+ defer cancel ()
2171
+ cstream1 , err := client .NewStream (ctx , & CallHdr {})
2172
+ if err != nil {
2173
+ t .Fatalf ("Client failed to create first stream. Err: %v" , err )
2174
+ }
2175
+
2176
+ <- notifyChan // Wait server stream to be established
2177
+ var sstream1 * Stream
2178
+ // Access stream on the server
2179
+ serverTransport .mu .Lock ()
2180
+ for _ , v := range serverTransport .activeStreams {
2181
+ if v .id == cstream1 .id {
2182
+ sstream1 = v
2183
+ }
2184
+ }
2185
+ serverTransport .mu .Unlock ()
2186
+ if sstream1 == nil {
2187
+ t .Fatalf ("Didn't find stream corresponding to client cstream.id: %v on the server" , cstream1 .id )
2188
+ }
2189
+
2190
+ client .Close (fmt .Errorf ("closed manually by test" ))
2191
+
2192
+ // Wait server transport to be closed
2193
+ <- serverTransport .done
2194
+
2195
+ // Write header on a closed server transport
2196
+ err = serverTransport .WriteHeader (sstream1 , metadata.MD {})
2197
+ st := status .Convert (err )
2198
+ if st .Code () != codes .Unavailable {
2199
+ t .Fatalf ("Unailable status expected but got: %v" , st .Code ().String ())
2200
+ }
2201
+ }
2202
+
2139
2203
func (s ) TestPingPong1B (t * testing.T ) {
2140
2204
runPingPongTest (t , 1 )
2141
2205
}
0 commit comments