1 // Copyright 2024 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/http2_settings.h"
16
17 #include "gmock/gmock.h"
18 #include "gtest/gtest.h"
19
20 namespace grpc_core {
21
TEST(Http2SettingsTest,CanSetAndRetrieveSettings)22 TEST(Http2SettingsTest, CanSetAndRetrieveSettings) {
23 Http2Settings settings;
24 settings.SetHeaderTableSize(1);
25 settings.SetEnablePush(true);
26 settings.SetMaxConcurrentStreams(3);
27 settings.SetInitialWindowSize(4);
28 settings.SetMaxFrameSize(50000);
29 settings.SetMaxHeaderListSize(6);
30 settings.SetAllowTrueBinaryMetadata(true);
31 settings.SetPreferredReceiveCryptoMessageSize(77777);
32 settings.SetAllowSecurityFrame(true);
33 EXPECT_EQ(settings.header_table_size(), 1u);
34 EXPECT_EQ(settings.enable_push(), true);
35 EXPECT_EQ(settings.max_concurrent_streams(), 3u);
36 EXPECT_EQ(settings.initial_window_size(), 4u);
37 EXPECT_EQ(settings.max_frame_size(), 50000u);
38 EXPECT_EQ(settings.max_header_list_size(), 6u);
39 EXPECT_EQ(settings.allow_true_binary_metadata(), true);
40 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 77777u);
41 EXPECT_EQ(settings.allow_security_frame(), true);
42 settings.SetHeaderTableSize(10);
43 settings.SetEnablePush(false);
44 settings.SetMaxConcurrentStreams(30);
45 settings.SetInitialWindowSize(40);
46 settings.SetMaxFrameSize(5000000);
47 settings.SetMaxHeaderListSize(60);
48 settings.SetAllowTrueBinaryMetadata(false);
49 settings.SetPreferredReceiveCryptoMessageSize(70000);
50 settings.SetAllowSecurityFrame(false);
51 EXPECT_EQ(settings.header_table_size(), 10u);
52 EXPECT_EQ(settings.enable_push(), false);
53 EXPECT_EQ(settings.max_concurrent_streams(), 30u);
54 EXPECT_EQ(settings.initial_window_size(), 40u);
55 EXPECT_EQ(settings.max_frame_size(), 5000000u);
56 EXPECT_EQ(settings.max_header_list_size(), 60u);
57 EXPECT_EQ(settings.allow_true_binary_metadata(), false);
58 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 70000u);
59 EXPECT_EQ(settings.allow_security_frame(), false);
60 }
61
TEST(Http2SettingsTest,InitialWindowSizeLimits)62 TEST(Http2SettingsTest, InitialWindowSizeLimits) {
63 Http2Settings settings;
64 settings.SetInitialWindowSize(0);
65 EXPECT_EQ(settings.initial_window_size(), 0u);
66 settings.SetInitialWindowSize(0x7fffffff);
67 EXPECT_EQ(settings.initial_window_size(), 0x7fffffffu);
68 settings.SetInitialWindowSize(0x80000000);
69 EXPECT_EQ(settings.initial_window_size(), 0x7fffffffu);
70 settings.SetInitialWindowSize(0xffffffff);
71 EXPECT_EQ(settings.initial_window_size(), 0x7fffffffu);
72 }
73
TEST(Http2SettingsTest,MaxFrameSizeLimits)74 TEST(Http2SettingsTest, MaxFrameSizeLimits) {
75 Http2Settings settings;
76 settings.SetMaxFrameSize(0);
77 EXPECT_EQ(settings.max_frame_size(), 16384u);
78 settings.SetMaxFrameSize(16384);
79 EXPECT_EQ(settings.max_frame_size(), 16384u);
80 settings.SetMaxFrameSize(16385);
81 EXPECT_EQ(settings.max_frame_size(), 16385u);
82 settings.SetMaxFrameSize(16777215);
83 EXPECT_EQ(settings.max_frame_size(), 16777215u);
84 settings.SetMaxFrameSize(16777216);
85 EXPECT_EQ(settings.max_frame_size(), 16777215u);
86 settings.SetMaxFrameSize(16777217);
87 EXPECT_EQ(settings.max_frame_size(), 16777215u);
88 settings.SetMaxFrameSize(0xffffffff);
89 EXPECT_EQ(settings.max_frame_size(), 16777215u);
90 }
91
TEST(Http2SettingsTest,PreferredReceiveCryptoMessageSize)92 TEST(Http2SettingsTest, PreferredReceiveCryptoMessageSize) {
93 Http2Settings settings;
94 settings.SetPreferredReceiveCryptoMessageSize(0);
95 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 16384u);
96 settings.SetPreferredReceiveCryptoMessageSize(16384);
97 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 16384u);
98 settings.SetPreferredReceiveCryptoMessageSize(16385);
99 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 16385u);
100 settings.SetPreferredReceiveCryptoMessageSize(16777215);
101 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 16777215u);
102 settings.SetPreferredReceiveCryptoMessageSize(16777216);
103 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 16777216u);
104 settings.SetPreferredReceiveCryptoMessageSize(16777217);
105 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 16777217u);
106 settings.SetPreferredReceiveCryptoMessageSize(0x7fffffff);
107 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 0x7fffffffu);
108 settings.SetPreferredReceiveCryptoMessageSize(0x80000000);
109 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 0x7fffffffu);
110 settings.SetPreferredReceiveCryptoMessageSize(0xffffffff);
111 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 0x7fffffffu);
112 }
113
114 namespace {
115 using KeyValue = std::pair<uint16_t, uint32_t>;
116 using KeyValueVec = std::vector<KeyValue>;
117
Diff(const Http2Settings & a,const Http2Settings & b,bool is_first_send)118 KeyValueVec Diff(const Http2Settings& a, const Http2Settings& b,
119 bool is_first_send) {
120 KeyValueVec diffs;
121 a.Diff(is_first_send, b, [&diffs](uint16_t key, uint32_t value) {
122 diffs.emplace_back(key, value);
123 });
124 return diffs;
125 }
126
operator ==(const KeyValue & a,const Http2SettingsFrame::Setting & b)127 bool operator==(const KeyValue& a, const Http2SettingsFrame::Setting& b) {
128 return a.first == b.id && a.second == b.value;
129 }
130
131 } // namespace
132
TEST(Http2SettingsTest,DiffOnFreshlyInitializedSettings)133 TEST(Http2SettingsTest, DiffOnFreshlyInitializedSettings) {
134 const Http2Settings settings1;
135 const Http2Settings settings2;
136 EXPECT_THAT(Diff(settings1, settings2, false), ::testing::IsEmpty());
137 EXPECT_THAT(Diff(settings1, settings2, true),
138 ::testing::UnorderedElementsAre(KeyValue{4, 65535}));
139 }
140
TEST(Http2SettingsTest,DiffOnSettingsWithOneValueSet)141 TEST(Http2SettingsTest, DiffOnSettingsWithOneValueSet) {
142 Http2Settings settings1;
143 Http2Settings settings2;
144 settings1.SetHeaderTableSize(1);
145 EXPECT_THAT(Diff(settings1, settings2, false),
146 ::testing::UnorderedElementsAre(KeyValue{1, 1}));
147 EXPECT_THAT(
148 Diff(settings1, settings2, true),
149 ::testing::UnorderedElementsAre(KeyValue{1, 1}, KeyValue{4, 65535}));
150 }
151
TEST(Http2SettingsTest,DiffOnSettingsWithTwoValuesSet)152 TEST(Http2SettingsTest, DiffOnSettingsWithTwoValuesSet) {
153 Http2Settings settings1;
154 Http2Settings settings2;
155 settings1.SetHeaderTableSize(1);
156 settings1.SetEnablePush(false);
157 EXPECT_THAT(Diff(settings1, settings2, false),
158 ::testing::UnorderedElementsAre(KeyValue{1, 1}, KeyValue{2, 0}));
159 EXPECT_THAT(Diff(settings1, settings2, true),
160 ::testing::UnorderedElementsAre(KeyValue{1, 1}, KeyValue{2, 0},
161 KeyValue{4, 65535}));
162 }
163
TEST(Http2SettingsTest,DiffOnSettingsWithThreeValuesSet)164 TEST(Http2SettingsTest, DiffOnSettingsWithThreeValuesSet) {
165 Http2Settings settings1;
166 Http2Settings settings2;
167 settings1.SetHeaderTableSize(1);
168 settings1.SetEnablePush(false);
169 settings1.SetMaxConcurrentStreams(3);
170 EXPECT_THAT(Diff(settings1, settings2, false),
171 ::testing::UnorderedElementsAre(KeyValue{1, 1}, KeyValue{2, 0},
172 KeyValue{3, 3}));
173 EXPECT_THAT(
174 Diff(settings1, settings2, true),
175 ::testing::UnorderedElementsAre(KeyValue{1, 1}, KeyValue{2, 0},
176 KeyValue{3, 3}, KeyValue{4, 65535}));
177 }
178
TEST(Http2SettingsTest,DiffOnSettingsWithFourValuesSet)179 TEST(Http2SettingsTest, DiffOnSettingsWithFourValuesSet) {
180 Http2Settings settings1;
181 Http2Settings settings2;
182 settings1.SetHeaderTableSize(1);
183 settings1.SetEnablePush(false);
184 settings1.SetMaxConcurrentStreams(3);
185 settings1.SetInitialWindowSize(4);
186 EXPECT_THAT(Diff(settings1, settings2, false),
187 ::testing::UnorderedElementsAre(KeyValue{1, 1}, KeyValue{2, 0},
188 KeyValue{3, 3}, KeyValue{4, 4}));
189 EXPECT_THAT(Diff(settings1, settings2, true),
190 ::testing::UnorderedElementsAre(KeyValue{1, 1}, KeyValue{2, 0},
191 KeyValue{3, 3}, KeyValue{4, 4}));
192 }
193
TEST(Http2SettingsTest,DiffOnSettingsWithFiveValuesSet)194 TEST(Http2SettingsTest, DiffOnSettingsWithFiveValuesSet) {
195 Http2Settings settings1;
196 Http2Settings settings2;
197 settings1.SetHeaderTableSize(1);
198 settings1.SetEnablePush(false);
199 settings1.SetMaxConcurrentStreams(3);
200 settings1.SetInitialWindowSize(4);
201 settings1.SetMaxFrameSize(50000);
202 EXPECT_THAT(Diff(settings1, settings2, false),
203 ::testing::UnorderedElementsAre(KeyValue{1, 1}, KeyValue{2, 0},
204 KeyValue{3, 3}, KeyValue{4, 4},
205 KeyValue{5, 50000}));
206 EXPECT_THAT(Diff(settings1, settings2, true),
207 ::testing::UnorderedElementsAre(KeyValue{1, 1}, KeyValue{2, 0},
208 KeyValue{3, 3}, KeyValue{4, 4},
209 KeyValue{5, 50000}));
210 }
211
TEST(Http2SettingsTest,DiffOnSettingsWithSixValuesSet)212 TEST(Http2SettingsTest, DiffOnSettingsWithSixValuesSet) {
213 Http2Settings settings1;
214 Http2Settings settings2;
215 settings1.SetHeaderTableSize(1);
216 settings1.SetEnablePush(false);
217 settings1.SetMaxConcurrentStreams(3);
218 settings1.SetInitialWindowSize(4);
219 settings1.SetMaxFrameSize(50000);
220 settings1.SetMaxHeaderListSize(6);
221 EXPECT_THAT(Diff(settings1, settings2, false),
222 ::testing::UnorderedElementsAre(
223 KeyValue{1, 1}, KeyValue{2, 0}, KeyValue{3, 3},
224 KeyValue{4, 4}, KeyValue{5, 50000}, KeyValue{6, 6}));
225 EXPECT_THAT(Diff(settings1, settings2, true),
226 ::testing::UnorderedElementsAre(
227 KeyValue{1, 1}, KeyValue{2, 0}, KeyValue{3, 3},
228 KeyValue{4, 4}, KeyValue{5, 50000}, KeyValue{6, 6}));
229 }
230
TEST(Http2SettingsTest,DiffOnSettingsWithSevenValuesSet)231 TEST(Http2SettingsTest, DiffOnSettingsWithSevenValuesSet) {
232 Http2Settings settings1;
233 Http2Settings settings2;
234 settings1.SetHeaderTableSize(1);
235 settings1.SetEnablePush(false);
236 settings1.SetMaxConcurrentStreams(3);
237 settings1.SetInitialWindowSize(4);
238 settings1.SetMaxFrameSize(50000);
239 settings1.SetMaxHeaderListSize(6);
240 settings1.SetAllowTrueBinaryMetadata(true);
241 EXPECT_THAT(
242 Diff(settings1, settings2, false),
243 ::testing::UnorderedElementsAre(
244 KeyValue{1, 1}, KeyValue{2, 0}, KeyValue{3, 3}, KeyValue{4, 4},
245 KeyValue{5, 50000}, KeyValue{6, 6}, KeyValue{65027, 1}));
246 EXPECT_THAT(
247 Diff(settings1, settings2, true),
248 ::testing::UnorderedElementsAre(
249 KeyValue{1, 1}, KeyValue{2, 0}, KeyValue{3, 3}, KeyValue{4, 4},
250 KeyValue{5, 50000}, KeyValue{6, 6}, KeyValue{65027, 1}));
251 }
252
TEST(Http2SettingsTest,DiffOnSettingsWithEightValuesSet)253 TEST(Http2SettingsTest, DiffOnSettingsWithEightValuesSet) {
254 Http2Settings settings1;
255 Http2Settings settings2;
256 settings1.SetHeaderTableSize(1);
257 settings1.SetEnablePush(false);
258 settings1.SetMaxConcurrentStreams(3);
259 settings1.SetInitialWindowSize(4);
260 settings1.SetMaxFrameSize(50000);
261 settings1.SetMaxHeaderListSize(6);
262 settings1.SetAllowTrueBinaryMetadata(true);
263 settings1.SetPreferredReceiveCryptoMessageSize(77777);
264 EXPECT_THAT(Diff(settings1, settings2, false),
265 ::testing::UnorderedElementsAre(
266 KeyValue{1, 1}, KeyValue{2, 0}, KeyValue{3, 3},
267 KeyValue{4, 4}, KeyValue{5, 50000}, KeyValue{6, 6},
268 KeyValue{65027, 1}, KeyValue{65028, 77777}));
269 EXPECT_THAT(Diff(settings1, settings2, true),
270 ::testing::UnorderedElementsAre(
271 KeyValue{1, 1}, KeyValue{2, 0}, KeyValue{3, 3},
272 KeyValue{4, 4}, KeyValue{5, 50000}, KeyValue{6, 6},
273 KeyValue{65027, 1}, KeyValue{65028, 77777}));
274 }
275
TEST(Http2SettingsTest,DiffOnSettingsWithNineValuesSet)276 TEST(Http2SettingsTest, DiffOnSettingsWithNineValuesSet) {
277 Http2Settings settings1;
278 Http2Settings settings2;
279 settings1.SetHeaderTableSize(1);
280 settings1.SetEnablePush(false);
281 settings1.SetMaxConcurrentStreams(3);
282 settings1.SetInitialWindowSize(4);
283 settings1.SetMaxFrameSize(50000);
284 settings1.SetMaxHeaderListSize(6);
285 settings1.SetAllowTrueBinaryMetadata(true);
286 settings1.SetPreferredReceiveCryptoMessageSize(77777);
287 settings1.SetAllowSecurityFrame(true);
288 EXPECT_THAT(
289 Diff(settings1, settings2, false),
290 ::testing::UnorderedElementsAre(
291 KeyValue{1, 1}, KeyValue{2, 0}, KeyValue{3, 3}, KeyValue{4, 4},
292 KeyValue{5, 50000}, KeyValue{6, 6}, KeyValue{65027, 1},
293 KeyValue{65028, 77777}, KeyValue{65029, 1}));
294 EXPECT_THAT(
295 Diff(settings1, settings2, true),
296 ::testing::UnorderedElementsAre(
297 KeyValue{1, 1}, KeyValue{2, 0}, KeyValue{3, 3}, KeyValue{4, 4},
298 KeyValue{5, 50000}, KeyValue{6, 6}, KeyValue{65027, 1},
299 KeyValue{65028, 77777}, KeyValue{65029, 1}));
300 }
301
TEST(Http2SettingsTest,ChangingHeaderTableSizeChangesEquality)302 TEST(Http2SettingsTest, ChangingHeaderTableSizeChangesEquality) {
303 Http2Settings settings1;
304 Http2Settings settings2;
305 settings1.SetHeaderTableSize(1);
306 EXPECT_NE(settings1, settings2);
307 settings2.SetHeaderTableSize(1);
308 EXPECT_EQ(settings1, settings2);
309 settings2.SetHeaderTableSize(2);
310 EXPECT_NE(settings1, settings2);
311 }
312
TEST(Http2SettingsTest,ChangingEnablePushChangesEquality)313 TEST(Http2SettingsTest, ChangingEnablePushChangesEquality) {
314 Http2Settings settings1;
315 Http2Settings settings2;
316 settings1.SetEnablePush(false);
317 EXPECT_NE(settings1, settings2);
318 settings2.SetEnablePush(false);
319 EXPECT_EQ(settings1, settings2);
320 settings2.SetEnablePush(true);
321 EXPECT_NE(settings1, settings2);
322 }
323
TEST(Http2SettingsTest,ChangingMaxConcurrentStreamsChangesEquality)324 TEST(Http2SettingsTest, ChangingMaxConcurrentStreamsChangesEquality) {
325 Http2Settings settings1;
326 Http2Settings settings2;
327 settings1.SetMaxConcurrentStreams(1);
328 EXPECT_NE(settings1, settings2);
329 settings2.SetMaxConcurrentStreams(1);
330 EXPECT_EQ(settings1, settings2);
331 settings2.SetMaxConcurrentStreams(2);
332 EXPECT_NE(settings1, settings2);
333 }
334
TEST(Http2SettingsTest,ChangingInitialWindowSizeChangesEquality)335 TEST(Http2SettingsTest, ChangingInitialWindowSizeChangesEquality) {
336 Http2Settings settings1;
337 Http2Settings settings2;
338 settings1.SetInitialWindowSize(1);
339 EXPECT_NE(settings1, settings2);
340 settings2.SetInitialWindowSize(1);
341 EXPECT_EQ(settings1, settings2);
342 settings2.SetInitialWindowSize(2);
343 EXPECT_NE(settings1, settings2);
344 }
345
TEST(Http2SettingsTest,ChangingMaxFrameSizeChangesEquality)346 TEST(Http2SettingsTest, ChangingMaxFrameSizeChangesEquality) {
347 Http2Settings settings1;
348 Http2Settings settings2;
349 settings1.SetMaxFrameSize(100000);
350 EXPECT_NE(settings1, settings2);
351 settings2.SetMaxFrameSize(100000);
352 EXPECT_EQ(settings1, settings2);
353 settings2.SetMaxFrameSize(200000);
354 EXPECT_NE(settings1, settings2);
355 }
356
TEST(Http2SettingsTest,ChangingMaxHeaderListSizeChangesEquality)357 TEST(Http2SettingsTest, ChangingMaxHeaderListSizeChangesEquality) {
358 Http2Settings settings1;
359 Http2Settings settings2;
360 settings1.SetMaxHeaderListSize(1);
361 EXPECT_NE(settings1, settings2);
362 settings2.SetMaxHeaderListSize(1);
363 EXPECT_EQ(settings1, settings2);
364 settings2.SetMaxHeaderListSize(2);
365 EXPECT_NE(settings1, settings2);
366 }
367
TEST(Http2SettingsTest,ChangingAllowTrueBinaryMetadataChangesEquality)368 TEST(Http2SettingsTest, ChangingAllowTrueBinaryMetadataChangesEquality) {
369 Http2Settings settings1;
370 Http2Settings settings2;
371 settings1.SetAllowTrueBinaryMetadata(true);
372 EXPECT_NE(settings1, settings2);
373 settings2.SetAllowTrueBinaryMetadata(true);
374 EXPECT_EQ(settings1, settings2);
375 settings2.SetAllowTrueBinaryMetadata(false);
376 EXPECT_NE(settings1, settings2);
377 }
378
TEST(Http2SettingsTest,ChangingPreferredReceiveCryptoMessageSizeChangesEquality)379 TEST(Http2SettingsTest,
380 ChangingPreferredReceiveCryptoMessageSizeChangesEquality) {
381 Http2Settings settings1;
382 Http2Settings settings2;
383 settings1.SetPreferredReceiveCryptoMessageSize(100000);
384 EXPECT_NE(settings1, settings2);
385 settings2.SetPreferredReceiveCryptoMessageSize(100000);
386 EXPECT_EQ(settings1, settings2);
387 settings2.SetPreferredReceiveCryptoMessageSize(200000);
388 EXPECT_NE(settings1, settings2);
389 }
390
TEST(Http2SettingsTest,ChangingAllowSecurityFrameChangesEquality)391 TEST(Http2SettingsTest, ChangingAllowSecurityFrameChangesEquality) {
392 Http2Settings settings1;
393 Http2Settings settings2;
394 settings1.SetAllowSecurityFrame(true);
395 EXPECT_NE(settings1, settings2);
396 settings2.SetAllowSecurityFrame(true);
397 EXPECT_EQ(settings1, settings2);
398 settings2.SetAllowSecurityFrame(false);
399 EXPECT_NE(settings1, settings2);
400 }
401
TEST(Http2SettingsTest,WireIdToNameWorks)402 TEST(Http2SettingsTest, WireIdToNameWorks) {
403 EXPECT_EQ(Http2Settings::WireIdToName(1), "HEADER_TABLE_SIZE");
404 EXPECT_EQ(Http2Settings::WireIdToName(2), "ENABLE_PUSH");
405 EXPECT_EQ(Http2Settings::WireIdToName(3), "MAX_CONCURRENT_STREAMS");
406 EXPECT_EQ(Http2Settings::WireIdToName(4), "INITIAL_WINDOW_SIZE");
407 EXPECT_EQ(Http2Settings::WireIdToName(5), "MAX_FRAME_SIZE");
408 EXPECT_EQ(Http2Settings::WireIdToName(6), "MAX_HEADER_LIST_SIZE");
409 EXPECT_EQ(Http2Settings::WireIdToName(65027),
410 "GRPC_ALLOW_TRUE_BINARY_METADATA");
411 EXPECT_EQ(Http2Settings::WireIdToName(65028),
412 "GRPC_PREFERRED_RECEIVE_MESSAGE_SIZE");
413 EXPECT_EQ(Http2Settings::WireIdToName(65029), "GRPC_ALLOW_SECURITY_FRAME");
414 EXPECT_EQ(Http2Settings::WireIdToName(65030), "UNKNOWN (65030)");
415 }
416
TEST(Http2SettingsTest,ApplyHeaderTableSizeWorks)417 TEST(Http2SettingsTest, ApplyHeaderTableSizeWorks) {
418 Http2Settings settings;
419 EXPECT_EQ(settings.Apply(1, 1), GRPC_HTTP2_NO_ERROR);
420 EXPECT_EQ(settings.header_table_size(), 1u);
421 EXPECT_EQ(settings.Apply(1, 0x7fffffff), GRPC_HTTP2_NO_ERROR);
422 EXPECT_EQ(settings.header_table_size(), 0x7fffffffu);
423 }
424
TEST(Http2SettingsTest,ApplyEnablePushWorks)425 TEST(Http2SettingsTest, ApplyEnablePushWorks) {
426 Http2Settings settings;
427 EXPECT_EQ(settings.Apply(2, 0), GRPC_HTTP2_NO_ERROR);
428 EXPECT_EQ(settings.enable_push(), false);
429 EXPECT_EQ(settings.Apply(2, 1), GRPC_HTTP2_NO_ERROR);
430 EXPECT_EQ(settings.enable_push(), true);
431 EXPECT_EQ(settings.Apply(2, 2), GRPC_HTTP2_PROTOCOL_ERROR);
432 }
433
TEST(Http2SettingsTest,ApplyMaxConcurrentStreamsWorks)434 TEST(Http2SettingsTest, ApplyMaxConcurrentStreamsWorks) {
435 Http2Settings settings;
436 EXPECT_EQ(settings.Apply(3, 1), GRPC_HTTP2_NO_ERROR);
437 EXPECT_EQ(settings.max_concurrent_streams(), 1u);
438 EXPECT_EQ(settings.Apply(3, 0x7fffffff), GRPC_HTTP2_NO_ERROR);
439 EXPECT_EQ(settings.max_concurrent_streams(), 0x7fffffffu);
440 }
441
TEST(Http2SettingsTest,ApplyInitialWindowSizeWorks)442 TEST(Http2SettingsTest, ApplyInitialWindowSizeWorks) {
443 Http2Settings settings;
444 EXPECT_EQ(settings.Apply(4, 1), GRPC_HTTP2_NO_ERROR);
445 EXPECT_EQ(settings.initial_window_size(), 1u);
446 EXPECT_EQ(settings.Apply(4, 0x7fffffff), GRPC_HTTP2_NO_ERROR);
447 EXPECT_EQ(settings.initial_window_size(), 0x7fffffffu);
448 }
449
TEST(Http2SettingsTest,ApplyMaxFrameSizeWorks)450 TEST(Http2SettingsTest, ApplyMaxFrameSizeWorks) {
451 Http2Settings settings;
452 EXPECT_EQ(settings.Apply(5, 16384), GRPC_HTTP2_NO_ERROR);
453 EXPECT_EQ(settings.max_frame_size(), 16384u);
454 EXPECT_EQ(settings.Apply(5, 16777215), GRPC_HTTP2_NO_ERROR);
455 EXPECT_EQ(settings.max_frame_size(), 16777215);
456 EXPECT_EQ(settings.Apply(5, 16383), GRPC_HTTP2_PROTOCOL_ERROR);
457 EXPECT_EQ(settings.Apply(5, 16777216), GRPC_HTTP2_PROTOCOL_ERROR);
458 }
459
TEST(Http2SettingsTest,ApplyMaxHeaderListSizeWorks)460 TEST(Http2SettingsTest, ApplyMaxHeaderListSizeWorks) {
461 Http2Settings settings;
462 EXPECT_EQ(settings.Apply(6, 1), GRPC_HTTP2_NO_ERROR);
463 EXPECT_EQ(settings.max_header_list_size(), 1u);
464 EXPECT_EQ(settings.Apply(6, 0x7fffffff), GRPC_HTTP2_NO_ERROR);
465 EXPECT_EQ(settings.max_header_list_size(), 16777216);
466 }
467
TEST(Http2SettingsTest,ApplyAllowTrueBinaryMetadataWorks)468 TEST(Http2SettingsTest, ApplyAllowTrueBinaryMetadataWorks) {
469 Http2Settings settings;
470 EXPECT_EQ(settings.Apply(65027, 0), GRPC_HTTP2_NO_ERROR);
471 EXPECT_EQ(settings.allow_true_binary_metadata(), false);
472 EXPECT_EQ(settings.Apply(65027, 1), GRPC_HTTP2_NO_ERROR);
473 EXPECT_EQ(settings.allow_true_binary_metadata(), true);
474 EXPECT_EQ(settings.Apply(65027, 2), GRPC_HTTP2_PROTOCOL_ERROR);
475 }
476
TEST(Http2SettingsTest,ApplyPreferredReceiveCryptoMessageSizeWorks)477 TEST(Http2SettingsTest, ApplyPreferredReceiveCryptoMessageSizeWorks) {
478 Http2Settings settings;
479 EXPECT_EQ(settings.Apply(65028, 1), GRPC_HTTP2_NO_ERROR);
480 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 16384u);
481 EXPECT_EQ(settings.Apply(65028, 0x7fffffff), GRPC_HTTP2_NO_ERROR);
482 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 0x7fffffffu);
483 EXPECT_EQ(settings.Apply(65028, 0x80000000), GRPC_HTTP2_NO_ERROR);
484 EXPECT_EQ(settings.preferred_receive_crypto_message_size(), 0x7fffffffu);
485 }
486
TEST(Http2SettingsTest,ApplyAllowSecurityFrameWorks)487 TEST(Http2SettingsTest, ApplyAllowSecurityFrameWorks) {
488 Http2Settings settings;
489 EXPECT_EQ(settings.Apply(65029, 0), GRPC_HTTP2_NO_ERROR);
490 EXPECT_EQ(settings.allow_security_frame(), false);
491 EXPECT_EQ(settings.Apply(65029, 1), GRPC_HTTP2_NO_ERROR);
492 EXPECT_EQ(settings.allow_security_frame(), true);
493 EXPECT_EQ(settings.Apply(65029, 2), GRPC_HTTP2_PROTOCOL_ERROR);
494 }
495
496 namespace {
497 MATCHER_P(SettingsFrame, settings, "") {
498 if (!arg.has_value()) {
499 *result_listener << "Expected a settings frame, got nothing";
500 return false;
501 }
502 if (arg->ack) {
503 *result_listener << "Expected a settings frame, got an ack";
504 return false;
505 }
506 if (arg->settings.size() != settings.size()) {
507 *result_listener << "Expected settings frame with " << settings.size()
508 << " settings, got " << arg->settings.size();
509 return false;
510 }
511 for (size_t i = 0; i < settings.size(); i++) {
512 bool found = false;
513 for (size_t j = 0; j < arg->settings.size(); j++) {
514 if (settings[i] == arg->settings[j]) {
515 found = true;
516 break;
517 }
518 }
519 if (!found) {
520 *result_listener << "Expected settings frame with setting "
521 << settings[i].first << " = " << settings[i].second
522 << ", but it was not found";
523 return false;
524 }
525 }
526 return true;
527 }
528 } // namespace
529
TEST(Http2SettingsManagerTest,ImmediatelyNeedsToSend)530 TEST(Http2SettingsManagerTest, ImmediatelyNeedsToSend) {
531 Http2SettingsManager settings_manager;
532 EXPECT_THAT(settings_manager.MaybeSendUpdate(),
533 SettingsFrame(KeyValueVec{{4, 65535}}));
534 }
535
TEST(Http2SettingsManagerTest,SendAckWorks)536 TEST(Http2SettingsManagerTest, SendAckWorks) {
537 Http2SettingsManager settings_manager;
538 settings_manager.mutable_local().SetInitialWindowSize(100000);
539 EXPECT_EQ(settings_manager.acked().initial_window_size(), 65535u);
540 EXPECT_THAT(settings_manager.MaybeSendUpdate(),
541 SettingsFrame(KeyValueVec{{4, 100000}}));
542 EXPECT_TRUE(settings_manager.AckLastSend());
543 EXPECT_EQ(settings_manager.acked().initial_window_size(), 100000u);
544 }
545
TEST(Http2SettingsManagerTest,AckWithoutSendFails)546 TEST(Http2SettingsManagerTest, AckWithoutSendFails) {
547 Http2SettingsManager settings_manager;
548 EXPECT_FALSE(settings_manager.AckLastSend());
549 }
550
TEST(Http2SettingsManagerTest,AckAfterAckFails)551 TEST(Http2SettingsManagerTest, AckAfterAckFails) {
552 Http2SettingsManager settings_manager;
553 settings_manager.mutable_local().SetInitialWindowSize(100000);
554 EXPECT_THAT(settings_manager.MaybeSendUpdate(),
555 SettingsFrame(KeyValueVec{{4, 100000}}));
556 EXPECT_TRUE(settings_manager.AckLastSend());
557 EXPECT_FALSE(settings_manager.AckLastSend());
558 }
559
560 } // namespace grpc_core
561
main(int argc,char ** argv)562 int main(int argc, char** argv) {
563 ::testing::InitGoogleTest(&argc, argv);
564 return RUN_ALL_TESTS();
565 }
566