1 // Copyright 2023 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <string.h>
16
17 #include <memory>
18
19 #include "gtest/gtest.h"
20
21 #include <grpc/grpc.h>
22 #include <grpc/impl/channel_arg_names.h>
23 #include <grpc/status.h>
24
25 #include "src/core/lib/channel/channel_args.h"
26 #include "src/core/lib/gprpp/time.h"
27 #include "src/core/lib/slice/slice.h"
28 #include "test/core/end2end/end2end_tests.h"
29
30 namespace grpc_core {
31 namespace {
32
CORE_END2END_TEST(CoreDeadlineTest,TimeoutBeforeRequestCall)33 CORE_END2END_TEST(CoreDeadlineTest, TimeoutBeforeRequestCall) {
34 SKIP_IF_CHAOTIC_GOOD();
35 auto c = NewClientCall("/foo").Timeout(Duration::Seconds(1)).Create();
36 CoreEnd2endTest::IncomingStatusOnClient server_status;
37 CoreEnd2endTest::IncomingMetadata server_initial_metadata;
38 c.NewBatch(1)
39 .SendInitialMetadata({})
40 .SendCloseFromClient()
41 .RecvInitialMetadata(server_initial_metadata)
42 .RecvStatusOnClient(server_status);
43 Expect(1, true);
44 Step();
45 EXPECT_EQ(server_status.status(), GRPC_STATUS_DEADLINE_EXCEEDED);
46 auto s = RequestCall(2);
47 bool got_call = false;
48 std::unique_ptr<IncomingCloseOnServer> client_close;
49 Expect(2, MaybePerformAction{[this, &s, &got_call, &client_close](bool ok) {
50 got_call = true;
51 if (ok) {
52 // If we successfully get a call, then we should additionally get a
53 // close tag.
54 client_close = std::make_unique<IncomingCloseOnServer>();
55 s.NewBatch(3).RecvCloseOnServer(*client_close);
56 Expect(3, true);
57 }
58 }});
59 Step();
60 if (client_close != nullptr) {
61 // If we got a close op then it should indicate cancelled.
62 EXPECT_TRUE(got_call);
63 EXPECT_TRUE(client_close->was_cancelled());
64 }
65 if (!got_call) {
66 // Maybe we didn't get a call (didn't reach the server pre-deadline).
67 // In that case we should get a failed call back on shutdown.
68 ShutdownServerAndNotify(4);
69 Expect(2, false);
70 Expect(4, true);
71 Step();
72 }
73 }
74
CORE_END2END_TEST(CoreDeadlineTest,TimeoutBeforeRequestCallWithRegisteredMethod)75 CORE_END2END_TEST(CoreDeadlineTest,
76 TimeoutBeforeRequestCallWithRegisteredMethod) {
77 SKIP_IF_CHAOTIC_GOOD();
78 auto method = RegisterServerMethod("/foo", GRPC_SRM_PAYLOAD_NONE);
79
80 auto c = NewClientCall("/foo").Timeout(Duration::Seconds(1)).Create();
81 CoreEnd2endTest::IncomingStatusOnClient server_status;
82 CoreEnd2endTest::IncomingMetadata server_initial_metadata;
83 c.NewBatch(1)
84 .SendInitialMetadata({})
85 .SendCloseFromClient()
86 .RecvInitialMetadata(server_initial_metadata)
87 .RecvStatusOnClient(server_status);
88 Expect(1, true);
89 Step();
90 EXPECT_EQ(server_status.status(), GRPC_STATUS_DEADLINE_EXCEEDED);
91 auto s = RequestRegisteredCall(method, 2);
92 bool got_call = false;
93 std::unique_ptr<IncomingCloseOnServer> client_close;
94 Expect(2, MaybePerformAction{[this, &s, &got_call, &client_close](bool ok) {
95 got_call = true;
96 if (ok) {
97 // If we successfully get a call, then we should additionally get a
98 // close tag.
99 client_close = std::make_unique<IncomingCloseOnServer>();
100 s.NewBatch(3).RecvCloseOnServer(*client_close);
101 Expect(3, true);
102 }
103 }});
104 Step();
105 if (client_close != nullptr) {
106 // If we got a close op then it should indicate cancelled.
107 EXPECT_TRUE(got_call);
108 EXPECT_TRUE(client_close->was_cancelled());
109 }
110 if (!got_call) {
111 // Maybe we didn't get a call (didn't reach the server pre-deadline).
112 // In that case we should get a failed call back on shutdown.
113 ShutdownServerAndNotify(4);
114 Expect(2, false);
115 Expect(4, true);
116 Step();
117 }
118 }
119
CORE_END2END_TEST(CoreDeadlineSingleHopTest,TimeoutBeforeRequestCallWithRegisteredMethodWithPayload)120 CORE_END2END_TEST(CoreDeadlineSingleHopTest,
121 TimeoutBeforeRequestCallWithRegisteredMethodWithPayload) {
122 SKIP_IF_CHAOTIC_GOOD();
123 auto method =
124 RegisterServerMethod("/foo", GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER);
125
126 const size_t kMessageSize = 10 * 1024 * 1024;
127 auto send_from_client = RandomSlice(kMessageSize);
128 InitServer(
129 ChannelArgs().Set(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, kMessageSize));
130 InitClient(
131 ChannelArgs().Set(GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH, kMessageSize));
132
133 auto c = NewClientCall("/foo").Timeout(Duration::Seconds(1)).Create();
134 CoreEnd2endTest::IncomingStatusOnClient server_status;
135 CoreEnd2endTest::IncomingMetadata server_initial_metadata;
136 c.NewBatch(1)
137 .SendInitialMetadata({})
138 .SendCloseFromClient()
139 .SendMessage(send_from_client.Ref())
140 .RecvInitialMetadata(server_initial_metadata)
141 .RecvStatusOnClient(server_status);
142 Expect(1, true);
143 Step();
144 EXPECT_EQ(server_status.status(), GRPC_STATUS_DEADLINE_EXCEEDED);
145 IncomingMessage client_message;
146 auto s = RequestRegisteredCall(method, &client_message, 2);
147 bool got_call = false;
148 std::unique_ptr<IncomingCloseOnServer> client_close;
149 Expect(2, MaybePerformAction{[this, &s, &got_call, &client_close](bool ok) {
150 gpr_log(GPR_INFO, "\n***\n*** got call: %d\n***", ok);
151 got_call = true;
152 if (ok) {
153 // If we successfully get a call, then we should additionally get a
154 // close tag.
155 client_close = std::make_unique<IncomingCloseOnServer>();
156 s.NewBatch(3).RecvCloseOnServer(*client_close);
157 Expect(3, true);
158 }
159 }});
160 Step();
161 if (client_close != nullptr) {
162 // If we got a close op then it should indicate cancelled.
163 EXPECT_TRUE(got_call);
164 EXPECT_TRUE(client_close->was_cancelled());
165 }
166 if (!got_call) {
167 // Maybe we didn't get a call (didn't reach the server pre-deadline).
168 // In that case we should get a failed call back on shutdown.
169 ShutdownServerAndNotify(4);
170 Expect(2, false);
171 Expect(4, true);
172 Step();
173 }
174 }
175
176 } // namespace
177 } // namespace grpc_core
178