xref: /aosp_15_r20/external/grpc-grpc/test/core/end2end/tests/streaming_error_response.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2016 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 /// \file Verify that status ordering rules are obeyed.
20 /// \ref doc/status_ordering.md
21 
22 #include <memory>
23 
24 #include "gtest/gtest.h"
25 
26 #include <grpc/status.h>
27 
28 #include "src/core/lib/gprpp/time.h"
29 #include "test/core/end2end/end2end_tests.h"
30 
31 namespace grpc_core {
32 namespace {
33 
34 // Client sends a request with payload, potentially requesting status early. The
35 // server reads and streams responses. The client cancels the RPC to get an
36 // error status. (Server sending a non-OK status is not considered an error
37 // status.)
CORE_END2END_TEST(CoreEnd2endTest,StreamingErrorResponse)38 CORE_END2END_TEST(CoreEnd2endTest, StreamingErrorResponse) {
39   SKIP_IF_CHAOTIC_GOOD();
40   auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
41   CoreEnd2endTest::IncomingMetadata server_initial_metadata;
42   CoreEnd2endTest::IncomingMessage response_payload1_recv;
43   c.NewBatch(1)
44       .SendInitialMetadata({})
45       .SendCloseFromClient()
46       .RecvInitialMetadata(server_initial_metadata)
47       .RecvMessage(response_payload1_recv);
48   auto s = RequestCall(101);
49   Expect(101, true);
50   Step();
51   s.NewBatch(102).SendInitialMetadata({}).SendMessage("hello");
52   Expect(102, true);
53   Expect(1, true);
54   Step();
55   s.NewBatch(103).SendMessage("world");
56   // The success of the op depends on whether the payload is written before the
57   // transport sees the end of stream. If the stream has been write closed
58   // before the write completes, it would fail, otherwise it would succeed.
59   // Since this behavior is dependent on the transport implementation, we allow
60   // any success status with this op.
61   Expect(103, AnyStatus());
62   CoreEnd2endTest::IncomingMessage response_payload2_recv;
63   c.NewBatch(2).RecvMessage(response_payload2_recv);
64   Expect(2, true);
65   Step();
66   EXPECT_FALSE(response_payload2_recv.is_end_of_stream());
67   // Cancel the call so that the client sets up an error status.
68   c.Cancel();
69   CoreEnd2endTest::IncomingCloseOnServer client_close;
70   s.NewBatch(104).RecvCloseOnServer(client_close);
71   Expect(104, true);
72   Step();
73   CoreEnd2endTest::IncomingStatusOnClient server_status;
74   c.NewBatch(3).RecvStatusOnClient(server_status);
75   Expect(3, true);
76   Step();
77   EXPECT_FALSE(response_payload1_recv.is_end_of_stream());
78   EXPECT_FALSE(response_payload2_recv.is_end_of_stream());
79   EXPECT_EQ(server_status.status(), GRPC_STATUS_CANCELLED);
80   EXPECT_TRUE(client_close.was_cancelled());
81 }
82 
CORE_END2END_TEST(CoreEnd2endTest,StreamingErrorResponseRequestStatusEarly)83 CORE_END2END_TEST(CoreEnd2endTest, StreamingErrorResponseRequestStatusEarly) {
84   SKIP_IF_CHAOTIC_GOOD();
85   auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
86   CoreEnd2endTest::IncomingMetadata server_initial_metadata;
87   CoreEnd2endTest::IncomingMessage response_payload1_recv;
88   CoreEnd2endTest::IncomingStatusOnClient server_status;
89   c.NewBatch(1)
90       .SendInitialMetadata({})
91       .SendCloseFromClient()
92       .RecvInitialMetadata(server_initial_metadata)
93       .RecvMessage(response_payload1_recv)
94       .RecvStatusOnClient(server_status);
95   auto s = RequestCall(101);
96   Expect(101, true);
97   Step();
98   s.NewBatch(102).SendInitialMetadata({}).SendMessage("hello");
99   Expect(102, true);
100   Step();
101   s.NewBatch(103).SendMessage("world");
102   // The success of the op depends on whether the payload is written before the
103   // transport sees the end of stream. If the stream has been write closed
104   // before the write completes, it would fail, otherwise it would succeed.
105   // Since this behavior is dependent on the transport implementation, we allow
106   // any success status with this op.
107   Expect(103, AnyStatus());
108   // Cancel the call so that the client sets up an error status.
109   c.Cancel();
110   CoreEnd2endTest::IncomingCloseOnServer client_close;
111   s.NewBatch(104).RecvCloseOnServer(client_close);
112   Expect(104, true);
113   Expect(1, true);
114   Step();
115   EXPECT_EQ(server_status.status(), GRPC_STATUS_CANCELLED);
116   EXPECT_TRUE(client_close.was_cancelled());
117 }
118 
CORE_END2END_TEST(CoreEnd2endTest,StreamingErrorResponseRequestStatusEarlyAndRecvMessageSeparately)119 CORE_END2END_TEST(
120     CoreEnd2endTest,
121     StreamingErrorResponseRequestStatusEarlyAndRecvMessageSeparately) {
122   SKIP_IF_CHAOTIC_GOOD();
123   auto c = NewClientCall("/foo").Timeout(Duration::Seconds(5)).Create();
124   CoreEnd2endTest::IncomingMetadata server_initial_metadata;
125   CoreEnd2endTest::IncomingStatusOnClient server_status;
126   c.NewBatch(1)
127       .SendInitialMetadata({})
128       .SendCloseFromClient()
129       .RecvInitialMetadata(server_initial_metadata)
130       .RecvStatusOnClient(server_status);
131   auto s = RequestCall(101);
132   Expect(101, true);
133   Step();
134   s.NewBatch(102).SendInitialMetadata({}).SendMessage("hello");
135   CoreEnd2endTest::IncomingMessage response_payload1_recv;
136   c.NewBatch(4).RecvMessage(response_payload1_recv);
137   Expect(102, true);
138   Expect(4, true);
139   Step();
140   s.NewBatch(103).SendMessage("world");
141   // The success of the op depends on whether the payload is written before the
142   // transport sees the end of stream. If the stream has been write closed
143   // before the write completes, it would fail, otherwise it would succeed.
144   // Since this behavior is dependent on the transport implementation, we allow
145   // any success status with this op.
146   Expect(103, AnyStatus());
147   // Cancel the call so that the client sets up an error status.
148   c.Cancel();
149   CoreEnd2endTest::IncomingCloseOnServer client_close;
150   s.NewBatch(104).RecvCloseOnServer(client_close);
151   Expect(104, true);
152   Expect(1, true);
153   Step();
154   EXPECT_EQ(server_status.status(), GRPC_STATUS_CANCELLED);
155   EXPECT_TRUE(client_close.was_cancelled());
156 }
157 
158 }  // namespace
159 }  // namespace grpc_core
160