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