xref: /aosp_15_r20/external/grpc-grpc/test/core/end2end/tests/bad_ping.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2017 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/lib/channel/channel_args.h"
27 #include "src/core/lib/gprpp/time.h"
28 #include "test/core/end2end/end2end_tests.h"
29 
30 #define MAX_PING_STRIKES 2
31 
32 namespace grpc_core {
33 namespace {
34 
35 // Send more pings than server allows to trigger server's GOAWAY.
CORE_END2END_TEST(RetryHttp2Test,BadPing)36 CORE_END2END_TEST(RetryHttp2Test, BadPing) {
37   InitClient(ChannelArgs()
38                  .Set(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0)
39                  .Set(GRPC_ARG_HTTP2_BDP_PROBE, 0));
40   InitServer(ChannelArgs()
41                  .Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS,
42                       Duration::Minutes(5).millis())
43                  .Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, MAX_PING_STRIKES)
44                  .Set(GRPC_ARG_HTTP2_BDP_PROBE, 0));
45   auto c = NewClientCall("/foo").Timeout(Duration::Seconds(10)).Create();
46   CoreEnd2endTest::IncomingStatusOnClient server_status;
47   CoreEnd2endTest::IncomingMetadata server_initial_metadata;
48   c.NewBatch(1)
49       .SendInitialMetadata({})
50       .SendCloseFromClient()
51       .RecvInitialMetadata(server_initial_metadata)
52       .RecvStatusOnClient(server_status);
53   auto s = RequestCall(101);
54   Expect(101, true);
55   Step();
56   // Send too many pings to the server to trigger the punishment:
57   // The first ping will let server mark its last_recv time. Afterwards, each
58   // ping will trigger a ping strike, and we need at least MAX_PING_STRIKES
59   // strikes to trigger the punishment. So (MAX_PING_STRIKES + 2) pings are
60   // needed here.
61   int i;
62   for (i = 1; i <= MAX_PING_STRIKES + 2; i++) {
63     PingServerFromClient(200 + i);
64     Expect(200 + i, true);
65     if (i == MAX_PING_STRIKES + 2) {
66       Expect(1, true);
67     }
68     Step();
69   }
70   CoreEnd2endTest::IncomingCloseOnServer client_close;
71   s.NewBatch(102)
72       .SendInitialMetadata({})
73       .SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
74       .RecvCloseOnServer(client_close);
75   Expect(102, true);
76   Step();
77   ShutdownServerAndNotify(103);
78   Expect(103, true);
79   Step();
80   // The connection should be closed immediately after the misbehaved pings,
81   // the in-progress RPC should fail.
82   EXPECT_EQ(server_status.status(), GRPC_STATUS_UNAVAILABLE);
83   EXPECT_EQ(s.method(), "/foo");
84   EXPECT_TRUE(client_close.was_cancelled());
85 }
86 
87 // Try sending more pings than server allows, but server should be fine because
88 // max_pings_without_data should limit pings sent out on wire.
CORE_END2END_TEST(RetryHttp2Test,PingsWithoutData)89 CORE_END2END_TEST(RetryHttp2Test, PingsWithoutData) {
90   // Only allow MAX_PING_STRIKES pings without data (DATA/HEADERS/WINDOW_UPDATE)
91   // so that the transport will throttle the excess pings.
92   InitClient(ChannelArgs()
93                  .Set(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, MAX_PING_STRIKES)
94                  .Set(GRPC_ARG_HTTP2_BDP_PROBE, 0));
95   InitServer(ChannelArgs()
96                  .Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS,
97                       Duration::Minutes(5).millis())
98                  .Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, MAX_PING_STRIKES)
99                  .Set(GRPC_ARG_HTTP2_BDP_PROBE, 0));
100   auto c = NewClientCall("/foo").Timeout(Duration::Seconds(10)).Create();
101   CoreEnd2endTest::IncomingStatusOnClient server_status;
102   CoreEnd2endTest::IncomingMetadata server_initial_metadata;
103   c.NewBatch(1)
104       .SendInitialMetadata({})
105       .SendCloseFromClient()
106       .RecvInitialMetadata(server_initial_metadata)
107       .RecvStatusOnClient(server_status);
108   auto s = RequestCall(101);
109   Expect(101, true);
110   Step();
111   // Send too many pings to the server similar to the previous test case.
112   // However, since we set the MAX_PINGS_WITHOUT_DATA at the client side, only
113   // MAX_PING_STRIKES will actually be sent and the rpc will still succeed.
114   int i;
115   for (i = 1; i <= MAX_PING_STRIKES + 2; i++) {
116     PingServerFromClient(200 + i);
117     if (i <= MAX_PING_STRIKES) {
118       Expect(200 + i, true);
119     }
120     Step();
121   }
122   CoreEnd2endTest::IncomingCloseOnServer client_close;
123   s.NewBatch(102)
124       .SendInitialMetadata({})
125       .SendStatusFromServer(GRPC_STATUS_UNIMPLEMENTED, "xyz", {})
126       .RecvCloseOnServer(client_close);
127   Expect(102, true);
128   // Client call should return.
129   Expect(1, true);
130   Step();
131   ShutdownServerAndNotify(103);
132   Expect(103, true);
133   // Also expect the previously blocked pings to complete with an error
134   Expect(200 + MAX_PING_STRIKES + 1, false);
135   Expect(200 + MAX_PING_STRIKES + 2, false);
136   Step();
137   // The rpc should be successful.
138   EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
139   EXPECT_EQ(s.method(), "/foo");
140 }
141 
142 }  // namespace
143 }  // namespace grpc_core
144