xref: /aosp_15_r20/external/grpc-grpc/test/core/transport/chttp2/ping_configuration_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 <memory>
16 
17 #include "gtest/gtest.h"
18 
19 #include <grpc/grpc.h>
20 #include <grpc/impl/channel_arg_names.h>
21 #include <grpc/slice.h>
22 
23 #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
24 #include "src/core/ext/transport/chttp2/transport/internal.h"
25 #include "src/core/ext/transport/chttp2/transport/legacy_frame.h"
26 #include "src/core/ext/transport/chttp2/transport/ping_abuse_policy.h"
27 #include "src/core/ext/transport/chttp2/transport/ping_rate_policy.h"
28 #include "src/core/lib/channel/channel_args.h"
29 #include "src/core/lib/event_engine/default_event_engine.h"
30 #include "src/core/lib/experiments/config.h"
31 #include "src/core/lib/gprpp/time.h"
32 #include "src/core/lib/iomgr/endpoint.h"
33 #include "src/core/lib/iomgr/exec_ctx.h"
34 #include "src/core/lib/resource_quota/resource_quota.h"
35 #include "test/core/util/mock_endpoint.h"
36 #include "test/core/util/test_config.h"
37 
38 namespace grpc_core {
39 namespace {
40 
41 class ConfigurationTest : public ::testing::Test {
42  protected:
ConfigurationTest()43   ConfigurationTest() {
44     mock_endpoint_ = grpc_mock_endpoint_create(DiscardWrite);
45     grpc_mock_endpoint_finish_put_reads(mock_endpoint_);
46     args_ = args_.SetObject(ResourceQuota::Default());
47     args_ = args_.SetObject(
48         grpc_event_engine::experimental::GetDefaultEventEngine());
49   }
50 
51   grpc_endpoint* mock_endpoint_ = nullptr;
52   ChannelArgs args_;
53 
54  private:
DiscardWrite(grpc_slice)55   static void DiscardWrite(grpc_slice /*slice*/) {}
56 };
57 
TEST_F(ConfigurationTest,ClientKeepaliveDefaults)58 TEST_F(ConfigurationTest, ClientKeepaliveDefaults) {
59   ExecCtx exec_ctx;
60   grpc_chttp2_transport* t = reinterpret_cast<grpc_chttp2_transport*>(
61       grpc_create_chttp2_transport(args_, mock_endpoint_, /*is_client=*/true));
62   EXPECT_EQ(t->keepalive_time, Duration::Infinity());
63   EXPECT_EQ(t->keepalive_timeout, Duration::Infinity());
64   EXPECT_EQ(t->keepalive_permit_without_calls, false);
65   EXPECT_EQ(t->ping_rate_policy.TestOnlyMaxPingsWithoutData(), 2);
66   t->Orphan();
67 }
68 
TEST_F(ConfigurationTest,ClientKeepaliveExplicitArgs)69 TEST_F(ConfigurationTest, ClientKeepaliveExplicitArgs) {
70   ExecCtx exec_ctx;
71   args_ = args_.Set(GRPC_ARG_KEEPALIVE_TIME_MS, 20000);
72   args_ = args_.Set(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, 10000);
73   args_ = args_.Set(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, true);
74   args_ = args_.Set(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 3);
75   grpc_chttp2_transport* t = reinterpret_cast<grpc_chttp2_transport*>(
76       grpc_create_chttp2_transport(args_, mock_endpoint_, /*is_client=*/true));
77   EXPECT_EQ(t->keepalive_time, Duration::Seconds(20));
78   EXPECT_EQ(t->keepalive_timeout, Duration::Seconds(10));
79   EXPECT_EQ(t->keepalive_permit_without_calls, true);
80   EXPECT_EQ(t->ping_rate_policy.TestOnlyMaxPingsWithoutData(), 3);
81   t->Orphan();
82 }
83 
TEST_F(ConfigurationTest,ServerKeepaliveDefaults)84 TEST_F(ConfigurationTest, ServerKeepaliveDefaults) {
85   ExecCtx exec_ctx;
86   grpc_chttp2_transport* t = reinterpret_cast<grpc_chttp2_transport*>(
87       grpc_create_chttp2_transport(args_, mock_endpoint_, /*is_client=*/false));
88   EXPECT_EQ(t->keepalive_time, Duration::Hours(2));
89   EXPECT_EQ(t->keepalive_timeout, Duration::Seconds(20));
90   EXPECT_EQ(t->keepalive_permit_without_calls, false);
91   // Server never limits based on number of pings without data.
92   EXPECT_EQ(t->ping_rate_policy.TestOnlyMaxPingsWithoutData(), 0);
93   EXPECT_EQ(t->ping_abuse_policy.TestOnlyMinPingIntervalWithoutData(),
94             Duration::Minutes(5));
95   EXPECT_EQ(t->ping_abuse_policy.TestOnlyMaxPingStrikes(), 2);
96   t->Orphan();
97 }
98 
TEST_F(ConfigurationTest,ServerKeepaliveExplicitArgs)99 TEST_F(ConfigurationTest, ServerKeepaliveExplicitArgs) {
100   ExecCtx exec_ctx;
101   args_ = args_.Set(GRPC_ARG_KEEPALIVE_TIME_MS, 20000);
102   args_ = args_.Set(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, 10000);
103   args_ = args_.Set(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, true);
104   args_ = args_.Set(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 3);
105   args_ =
106       args_.Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS, 20000);
107   args_ = args_.Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, 0);
108   grpc_chttp2_transport* t = reinterpret_cast<grpc_chttp2_transport*>(
109       grpc_create_chttp2_transport(args_, mock_endpoint_, /*is_client=*/false));
110   EXPECT_EQ(t->keepalive_time, Duration::Seconds(20));
111   EXPECT_EQ(t->keepalive_timeout, Duration::Seconds(10));
112   EXPECT_EQ(t->keepalive_permit_without_calls, true);
113   // Server never limits based on number of pings without data.
114   EXPECT_EQ(t->ping_rate_policy.TestOnlyMaxPingsWithoutData(), 0);
115   EXPECT_EQ(t->ping_abuse_policy.TestOnlyMinPingIntervalWithoutData(),
116             Duration::Seconds(20));
117   EXPECT_EQ(t->ping_abuse_policy.TestOnlyMaxPingStrikes(), 0);
118   t->Orphan();
119 }
120 
121 // This test modifies the defaults of the client side settings, so it would
122 // affect any test that is run after this.
123 // TODO(yashykt): If adding more client side tests after this, add a reset to
124 // defaults function.
TEST_F(ConfigurationTest,ModifyClientDefaults)125 TEST_F(ConfigurationTest, ModifyClientDefaults) {
126   ExecCtx exec_ctx;
127   // Note that we are creating a new args object to override the defaults.
128   ChannelArgs args = args_.Set(GRPC_ARG_KEEPALIVE_TIME_MS, 20000);
129   args = args.Set(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, 10000);
130   args = args.Set(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, true);
131   args = args.Set(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 3);
132   grpc_chttp2_config_default_keepalive_args(args, /*is_client=*/true);
133   // Note that we are using the original args_ object for creating the transport
134   // which does not override the defaults.
135   grpc_chttp2_transport* t = reinterpret_cast<grpc_chttp2_transport*>(
136       grpc_create_chttp2_transport(args_, mock_endpoint_, /*is_client=*/true));
137   EXPECT_EQ(t->keepalive_time, Duration::Seconds(20));
138   EXPECT_EQ(t->keepalive_timeout, Duration::Seconds(10));
139   EXPECT_EQ(t->keepalive_permit_without_calls, true);
140   EXPECT_EQ(t->ping_rate_policy.TestOnlyMaxPingsWithoutData(), 3);
141   t->Orphan();
142 }
143 
144 // This test modifies the defaults of the client side settings, so it would
145 // affect any test that is run after this.
146 // TODO(yashykt): If adding more server side tests after this, add a reset to
147 // defaults function.
TEST_F(ConfigurationTest,ModifyServerDefaults)148 TEST_F(ConfigurationTest, ModifyServerDefaults) {
149   ExecCtx exec_ctx;
150   // Note that we are creating a new args object to override the defaults.
151   ChannelArgs args = args_.Set(GRPC_ARG_KEEPALIVE_TIME_MS, 20000);
152   args = args.Set(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, 10000);
153   args = args.Set(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, true);
154   args = args.Set(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 3);
155   args = args.Set(GRPC_ARG_HTTP2_MIN_RECV_PING_INTERVAL_WITHOUT_DATA_MS, 20000);
156   args = args.Set(GRPC_ARG_HTTP2_MAX_PING_STRIKES, 0);
157   grpc_chttp2_config_default_keepalive_args(args, /*is_client=*/false);
158   // Note that we are using the original args_ object for creating the transport
159   // which does not override the defaults.
160   grpc_chttp2_transport* t = reinterpret_cast<grpc_chttp2_transport*>(
161       grpc_create_chttp2_transport(args_, mock_endpoint_, /*is_client=*/false));
162   EXPECT_EQ(t->keepalive_time, Duration::Seconds(20));
163   EXPECT_EQ(t->keepalive_timeout, Duration::Seconds(10));
164   EXPECT_EQ(t->keepalive_permit_without_calls, true);
165   // Server never limits based on number of pings without data.
166   EXPECT_EQ(t->ping_rate_policy.TestOnlyMaxPingsWithoutData(), 0);
167   EXPECT_EQ(t->ping_abuse_policy.TestOnlyMinPingIntervalWithoutData(),
168             Duration::Seconds(20));
169   EXPECT_EQ(t->ping_abuse_policy.TestOnlyMaxPingStrikes(), 0);
170   t->Orphan();
171 }
172 
173 }  // namespace
174 }  // namespace grpc_core
175 
main(int argc,char ** argv)176 int main(int argc, char** argv) {
177   ::testing::InitGoogleTest(&argc, argv);
178   grpc::testing::TestEnvironment env(&argc, argv);
179   grpc_core::ForceEnableExperiment("keepalive_fix", true);
180   grpc_core::ForceEnableExperiment("keepalive_server_fix", true);
181   grpc_init();
182   auto ret = RUN_ALL_TESTS();
183   grpc_shutdown();
184   return ret;
185 }
186