MCPcopy
hub / github.com/grpc/grpc-go / TestUnaryClient_ServerStreamingMismatch

Method TestUnaryClient_ServerStreamingMismatch

stream_test.go:81–147  ·  view source on GitHub ↗

TestUnaryClient_ServerStreamingMismatch ensures that the client's non-streaming RecvMsg() logic correctly handles various error scenarios from the server. The Client initiates a Unary RPC (Invoke), forcing it to use the non-server-streaming `recvMsg` code path (where the bug was). The Server handle

(t *testing.T)

Source from the content-addressed store, hash-verified

79// The Server handles it as a Streaming RPC (FullDuplexCall), allowing us to
80// send arbitrary sequences of messages and errors.
81func (s) TestUnaryClient_ServerStreamingMismatch(t *testing.T) {
82 tests := []struct {
83 name string
84 fullDuplexCallF func(testgrpc.TestService_FullDuplexCallServer) error
85 wantErrorContains string
86 wantCode codes.Code
87 clientCallOptions []grpc.CallOption
88 }{
89 {
90 name: "server_sends_error_after_message",
91 fullDuplexCallF: func(stream testgrpc.TestService_FullDuplexCallServer) error {
92 if err := stream.Send(&testpb.StreamingOutputCallResponse{}); err != nil {
93 return err
94 }
95 return status.Error(codes.Internal, "server error after message")
96 },
97 wantErrorContains: "server error after message",
98 wantCode: codes.Internal,
99 },
100 {
101 name: "server_sends_second_message_exceeding_limit",
102 fullDuplexCallF: func(stream testgrpc.TestService_FullDuplexCallServer) error {
103 if err := stream.Send(&testpb.StreamingOutputCallResponse{
104 Payload: &testpb.Payload{Body: make([]byte, 1)},
105 }); err != nil {
106 return err
107 }
108 return stream.Send(&testpb.StreamingOutputCallResponse{
109 Payload: &testpb.Payload{Body: make([]byte, 10)},
110 })
111 },
112 clientCallOptions: []grpc.CallOption{grpc.MaxCallRecvMsgSize(5)},
113 wantErrorContains: "received message larger than max",
114 wantCode: codes.ResourceExhausted,
115 },
116 }
117
118 for _, test := range tests {
119 t.Run(test.name, func(t *testing.T) {
120 ss := &stubserver.StubServer{
121 FullDuplexCallF: test.fullDuplexCallF,
122 }
123 if err := ss.Start(nil); err != nil {
124 t.Fatal("Error starting server:", err)
125 }
126 defer ss.Stop()
127
128 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
129 defer cancel()
130
131 // Invoke the streaming RPC method as a Unary RPC. This forces the client
132 // to use the non-streaming RecvMsg path, while the server handles it as
133 // a stream (allowing it to send messages and errors in ways a standard
134 // Unary server cannot).
135 err := ss.CC.Invoke(ctx, "/grpc.testing.TestService/FullDuplexCall", &testpb.StreamingOutputCallRequest{}, &testpb.StreamingOutputCallResponse{}, test.clientCallOptions...)
136 if err == nil {
137 t.Fatal("Client.Invoke returned nil, want error")
138 }

Callers

nothing calls this directly

Calls 10

StartMethod · 0.95
StopMethod · 0.95
ErrorFunction · 0.92
MaxCallRecvMsgSizeFunction · 0.92
CodeFunction · 0.92
SendMethod · 0.65
FatalMethod · 0.65
InvokeMethod · 0.65
ErrorfMethod · 0.65
ErrorMethod · 0.65

Tested by

no test coverage detected