1 //
2 //
3 // Copyright 2015 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 #include <memory>
20
21 #include "gtest/gtest.h"
22
23 #include <grpc/impl/channel_arg_names.h>
24 #include <grpc/status.h>
25
26 #include "src/core/ext/transport/chttp2/transport/internal.h"
27 #include "src/core/lib/channel/channel_args.h"
28 #include "src/core/lib/gprpp/time.h"
29 #include "test/core/end2end/end2end_tests.h"
30
31 namespace grpc_core {
32 namespace {
33
SimpleRequestBody(CoreEnd2endTest & test)34 void SimpleRequestBody(CoreEnd2endTest& test) {
35 auto c = test.NewClientCall("/foo").Timeout(Duration::Seconds(5)).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 auto s = test.RequestCall(101);
44 test.Expect(101, true);
45 test.Step();
46 CoreEnd2endTest::IncomingCloseOnServer client_close;
47 s.NewBatch(102)
48 .SendInitialMetadata({})
49 .SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
50 .RecvCloseOnServer(client_close);
51 test.Expect(102, true);
52 test.Expect(1, true);
53 test.Step();
54 EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
55 EXPECT_EQ(server_status.message(), "xyz");
56 EXPECT_EQ(s.method(), "/foo");
57 EXPECT_FALSE(client_close.was_cancelled());
58 }
59
CORE_END2END_TEST(Http2SingleHopTest,MaxConcurrentStreams)60 CORE_END2END_TEST(Http2SingleHopTest, MaxConcurrentStreams) {
61 SKIP_IF_MINSTACK();
62 InitServer(
63 ChannelArgs()
64 .Set(GRPC_ARG_MAX_CONCURRENT_STREAMS, 1)
65 .Set(GRPC_ARG_MAX_CONCURRENT_STREAMS_OVERLOAD_PROTECTION, false));
66 InitClient(ChannelArgs());
67 // perform a ping-pong to ensure that settings have had a chance to round
68 // trip
69 SimpleRequestBody(*this);
70 // perform another one to make sure that the one stream case still works
71 SimpleRequestBody(*this);
72 // start two requests - ensuring that the second is not accepted until
73 // the first completes
74 auto c1 = NewClientCall("/alpha").Timeout(Duration::Seconds(1000)).Create();
75 auto c2 = NewClientCall("/beta").Timeout(Duration::Seconds(1000)).Create();
76 auto s1 = RequestCall(101);
77 c1.NewBatch(301).SendInitialMetadata({}).SendCloseFromClient();
78 IncomingMetadata server_initial_metadata1;
79 IncomingStatusOnClient server_status1;
80 c1.NewBatch(302)
81 .RecvStatusOnClient(server_status1)
82 .RecvInitialMetadata(server_initial_metadata1);
83 c2.NewBatch(401).SendInitialMetadata({}).SendCloseFromClient();
84 IncomingMetadata server_initial_metadata2;
85 IncomingStatusOnClient server_status2;
86 c2.NewBatch(402)
87 .RecvStatusOnClient(server_status2)
88 .RecvInitialMetadata(server_initial_metadata2);
89 bool got_client_start = false;
90 bool got_server_start = false;
91 int live_call;
92 Expect(101, MaybePerformAction{[&got_server_start](bool ok) {
93 EXPECT_TRUE(ok);
94 got_server_start = ok;
95 }});
96 Expect(301, MaybePerformAction{[&got_client_start, &live_call](bool ok) {
97 EXPECT_FALSE(got_client_start);
98 EXPECT_TRUE(ok);
99 got_client_start = ok;
100 live_call = 300;
101 }});
102 Expect(401, MaybePerformAction{[&got_client_start, &live_call](bool ok) {
103 EXPECT_FALSE(got_client_start);
104 EXPECT_TRUE(ok);
105 got_client_start = ok;
106 live_call = 400;
107 }});
108 Step();
109 if (got_client_start && !got_server_start) {
110 Expect(101, true);
111 Step();
112 got_server_start = true;
113 } else if (got_server_start && !got_client_start) {
114 Expect(301, MaybePerformAction{[&got_client_start, &live_call](bool ok) {
115 EXPECT_FALSE(got_client_start);
116 EXPECT_TRUE(ok);
117 got_client_start = ok;
118 live_call = 300;
119 }});
120 Expect(401, MaybePerformAction{[&got_client_start, &live_call](bool ok) {
121 EXPECT_FALSE(got_client_start);
122 EXPECT_TRUE(ok);
123 got_client_start = ok;
124 live_call = 400;
125 }});
126 Step();
127 EXPECT_TRUE(got_client_start);
128 }
129 IncomingCloseOnServer client_close;
130 s1.NewBatch(102)
131 .SendInitialMetadata({})
132 .RecvCloseOnServer(client_close)
133 .SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {});
134 Expect(102, true);
135 Expect(live_call + 2, true);
136 // first request is finished, we should be able to start the second
137 live_call = (live_call == 300) ? 400 : 300;
138 Expect(live_call + 1, true);
139 Step();
140 // Spin for a little: we expect to see no events now - and this time allows
141 // any overload protection machinery in the transport to settle (chttp2 tries
142 // to ensure calls are finished deleting before allowing more requests
143 // through).
144 Step();
145 auto s2 = RequestCall(201);
146 Expect(201, true);
147 Step();
148 s2.NewBatch(202)
149 .SendInitialMetadata({})
150 .RecvCloseOnServer(client_close)
151 .SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {});
152 Expect(live_call + 2, true);
153 Expect(202, true);
154 Step();
155 }
156
CORE_END2END_TEST(Http2SingleHopTest,MaxConcurrentStreamsTimeoutOnFirst)157 CORE_END2END_TEST(Http2SingleHopTest, MaxConcurrentStreamsTimeoutOnFirst) {
158 SKIP_IF_MINSTACK();
159 InitServer(
160 ChannelArgs()
161 .Set(GRPC_ARG_MAX_CONCURRENT_STREAMS, 1)
162 .Set(GRPC_ARG_MAX_CONCURRENT_STREAMS_OVERLOAD_PROTECTION, false));
163 InitClient(ChannelArgs());
164 // perform a ping-pong to ensure that settings have had a chance to round
165 // trip
166 SimpleRequestBody(*this);
167 // perform another one to make sure that the one stream case still works
168 SimpleRequestBody(*this);
169 // start two requests - ensuring that the second is not accepted until
170 // the first completes
171 auto c1 = NewClientCall("/alpha").Timeout(Duration::Seconds(3)).Create();
172 auto c2 = NewClientCall("/beta").Timeout(Duration::Seconds(1000)).Create();
173 auto s1 = RequestCall(101);
174 c1.NewBatch(301).SendInitialMetadata({}).SendCloseFromClient();
175 IncomingMetadata server_initial_metadata1;
176 IncomingStatusOnClient server_status1;
177 c1.NewBatch(302)
178 .RecvStatusOnClient(server_status1)
179 .RecvInitialMetadata(server_initial_metadata1);
180 Expect(101, true);
181 Expect(301, true);
182 Step();
183 c2.NewBatch(401).SendInitialMetadata({}).SendCloseFromClient();
184 IncomingMetadata server_initial_metadata2;
185 IncomingStatusOnClient server_status2;
186 c2.NewBatch(402)
187 .RecvStatusOnClient(server_status2)
188 .RecvInitialMetadata(server_initial_metadata2);
189 auto s2 = RequestCall(201);
190 Expect(302, true);
191 // first request is finished, we should be able to start the second
192 Expect(401, true);
193 Expect(201, true);
194 Step();
195 IncomingCloseOnServer client_close2;
196 s2.NewBatch(202)
197 .SendInitialMetadata({})
198 .RecvCloseOnServer(client_close2)
199 .SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {});
200 Expect(402, true);
201 Expect(202, true);
202 Step();
203 }
204
CORE_END2END_TEST(Http2SingleHopTest,MaxConcurrentStreamsTimeoutOnSecond)205 CORE_END2END_TEST(Http2SingleHopTest, MaxConcurrentStreamsTimeoutOnSecond) {
206 SKIP_IF_MINSTACK();
207 InitServer(
208 ChannelArgs()
209 .Set(GRPC_ARG_MAX_CONCURRENT_STREAMS, 1)
210 .Set(GRPC_ARG_MAX_CONCURRENT_STREAMS_OVERLOAD_PROTECTION, false));
211 InitClient(ChannelArgs());
212 // perform a ping-pong to ensure that settings have had a chance to round
213 // trip
214 SimpleRequestBody(*this);
215 // perform another one to make sure that the one stream case still works
216 SimpleRequestBody(*this);
217 // start two requests - ensuring that the second is not accepted until
218 // the first completes , and the second request will timeout in the
219 // concurrent_list
220 auto c1 = NewClientCall("/alpha").Timeout(Duration::Seconds(1000)).Create();
221 auto c2 = NewClientCall("/beta").Timeout(Duration::Seconds(3)).Create();
222 auto s1 = RequestCall(101);
223 c1.NewBatch(301).SendInitialMetadata({}).SendCloseFromClient();
224 IncomingMetadata server_initial_metadata1;
225 IncomingStatusOnClient server_status1;
226 c1.NewBatch(302)
227 .RecvStatusOnClient(server_status1)
228 .RecvInitialMetadata(server_initial_metadata1);
229 Expect(101, true);
230 Expect(301, true);
231 Step();
232 c2.NewBatch(401).SendInitialMetadata({}).SendCloseFromClient();
233 IncomingMetadata server_initial_metadata2;
234 IncomingStatusOnClient server_status2;
235 c2.NewBatch(402)
236 .RecvStatusOnClient(server_status2)
237 .RecvInitialMetadata(server_initial_metadata2);
238 // the second request is time out
239 Expect(401, false);
240 Expect(402, true);
241 Step();
242 // now reply the first call
243 IncomingCloseOnServer client_close1;
244 s1.NewBatch(102)
245 .SendInitialMetadata({})
246 .RecvCloseOnServer(client_close1)
247 .SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {});
248 Expect(302, true);
249 Expect(102, true);
250 Step();
251 }
252
253 } // namespace
254 } // namespace grpc_core
255