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