xref: /aosp_15_r20/external/grpc-grpc/test/core/transport/chttp2/ping_abuse_policy_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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 "src/core/ext/transport/chttp2/transport/ping_abuse_policy.h"
16 
17 #include <chrono>
18 #include <thread>
19 
20 #include "gtest/gtest.h"
21 
22 #include <grpc/impl/channel_arg_names.h>
23 
24 namespace grpc_core {
25 namespace {
26 
TEST(PingAbusePolicy,NoOp)27 TEST(PingAbusePolicy, NoOp) {
28   Chttp2PingAbusePolicy policy{ChannelArgs()};
29   EXPECT_EQ(policy.TestOnlyMaxPingStrikes(), 2);
30   EXPECT_EQ(policy.TestOnlyMinPingIntervalWithoutData(), Duration::Minutes(5));
31 }
32 
TEST(PingAbusePolicy,WithChannelArgs)33 TEST(PingAbusePolicy, WithChannelArgs) {
34   Chttp2PingAbusePolicy policy{
35       ChannelArgs()
36           .Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS, 100)
37           .Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, 42)};
38   EXPECT_EQ(policy.TestOnlyMaxPingStrikes(), 42);
39   EXPECT_EQ(policy.TestOnlyMinPingIntervalWithoutData(),
40             Duration::Milliseconds(100));
41 }
42 
TEST(PingAbusePolicy,ChannelArgsRangeCheck)43 TEST(PingAbusePolicy, ChannelArgsRangeCheck) {
44   Chttp2PingAbusePolicy policy{
45       ChannelArgs()
46           .Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS, -1000)
47           .Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, -100)};
48   EXPECT_EQ(policy.TestOnlyMaxPingStrikes(), 0);
49   EXPECT_EQ(policy.TestOnlyMinPingIntervalWithoutData(), Duration::Zero());
50 }
51 
TEST(PingAbusePolicy,BasicOut)52 TEST(PingAbusePolicy, BasicOut) {
53   Chttp2PingAbusePolicy policy{ChannelArgs()};
54   EXPECT_EQ(policy.TestOnlyMaxPingStrikes(), 2);
55   // First ping ok
56   EXPECT_FALSE(policy.ReceivedOnePing(false));
57   // Strike 1... too soon
58   EXPECT_FALSE(policy.ReceivedOnePing(false));
59   // Strike 2... too soon
60   EXPECT_FALSE(policy.ReceivedOnePing(false));
61   // Strike 3... you're out!
62   EXPECT_TRUE(policy.ReceivedOnePing(false));
63 }
64 
TEST(PingAbusePolicy,TimePreventsOut)65 TEST(PingAbusePolicy, TimePreventsOut) {
66   Chttp2PingAbusePolicy policy{ChannelArgs().Set(
67       GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS, 1000)};
68   EXPECT_EQ(policy.TestOnlyMaxPingStrikes(), 2);
69   // First ping ok
70   EXPECT_FALSE(policy.ReceivedOnePing(false));
71   // Strike 1... too soon
72   EXPECT_FALSE(policy.ReceivedOnePing(false));
73   // Strike 2... too soon
74   EXPECT_FALSE(policy.ReceivedOnePing(false));
75   // Sleep a bit, allowed
76   std::this_thread::sleep_for(std::chrono::seconds(2));
77   EXPECT_FALSE(policy.ReceivedOnePing(false));
78 }
79 
TEST(PingAbusePolicy,TimerSustains)80 TEST(PingAbusePolicy, TimerSustains) {
81   Chttp2PingAbusePolicy policy{ChannelArgs().Set(
82       GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS, 10)};
83   EXPECT_EQ(policy.TestOnlyMaxPingStrikes(), 2);
84   for (int i = 0; i < 100; i++) {
85     EXPECT_FALSE(policy.ReceivedOnePing(false));
86     std::this_thread::sleep_for(std::chrono::milliseconds(20));
87   }
88 }
89 
TEST(PingAbusePolicy,IdleIncreasesTimeout)90 TEST(PingAbusePolicy, IdleIncreasesTimeout) {
91   Chttp2PingAbusePolicy policy{ChannelArgs().Set(
92       GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS, 1000)};
93   EXPECT_EQ(policy.TestOnlyMaxPingStrikes(), 2);
94   // First ping ok
95   EXPECT_FALSE(policy.ReceivedOnePing(true));
96   // Strike 1... too soon
97   EXPECT_FALSE(policy.ReceivedOnePing(true));
98   // Strike 2... too soon
99   EXPECT_FALSE(policy.ReceivedOnePing(true));
100   // Sleep a bit, allowed
101   std::this_thread::sleep_for(std::chrono::seconds(2));
102   EXPECT_TRUE(policy.ReceivedOnePing(true));
103 }
104 
105 }  // namespace
106 }  // namespace grpc_core
107 
main(int argc,char ** argv)108 int main(int argc, char** argv) {
109   ::testing::InitGoogleTest(&argc, argv);
110   // hardcode expected defaults so we don't account for external configuration
111   grpc_core::Chttp2PingAbusePolicy::SetDefaults(
112       grpc_core::ChannelArgs()
113           .Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, 2)
114           .Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS,
115                grpc_core::Duration::Minutes(5).millis()));
116   return RUN_ALL_TESTS();
117 }
118