blob: 8257363edb0f785cd401e7643e95bf772a344282 [file] [log] [blame]
bncbdf981f2019-07-30 17:21:14 -07001// Copyright (c) 2019 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/third_party/quiche/src/quic/core/qpack/qpack_blocking_manager.h"
6
7#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
8
9namespace quic {
10namespace test {
bncf97492c2019-09-20 17:47:13 -070011
12class QpackBlockingManagerPeer {
13 public:
14 static bool stream_is_blocked(const QpackBlockingManager* manager,
15 QuicStreamId stream_id) {
16 for (const auto& header_blocks_for_stream : manager->header_blocks_) {
17 if (header_blocks_for_stream.first != stream_id) {
18 continue;
19 }
20 for (const auto& indices : header_blocks_for_stream.second) {
21 if (QpackBlockingManager::RequiredInsertCount(indices) >
22 manager->known_received_count_) {
23 return true;
24 }
25 }
26 }
27
28 return false;
29 }
30};
31
bncbdf981f2019-07-30 17:21:14 -070032namespace {
33
34class QpackBlockingManagerTest : public QuicTest {
35 protected:
36 QpackBlockingManagerTest() = default;
37 ~QpackBlockingManagerTest() override = default;
38
bncf97492c2019-09-20 17:47:13 -070039 bool stream_is_blocked(QuicStreamId stream_id) const {
40 return QpackBlockingManagerPeer::stream_is_blocked(&manager_, stream_id);
41 }
42
bncbdf981f2019-07-30 17:21:14 -070043 QpackBlockingManager manager_;
44};
45
46TEST_F(QpackBlockingManagerTest, Empty) {
bncbdf981f2019-07-30 17:21:14 -070047 EXPECT_EQ(0u, manager_.known_received_count());
48 EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
49 manager_.smallest_blocking_index());
50
51 EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
52 EXPECT_FALSE(manager_.OnHeaderAcknowledgement(1));
53}
54
55TEST_F(QpackBlockingManagerTest, NotBlockedByInsertCountIncrement) {
56 manager_.OnInsertCountIncrement(2);
57
58 // Stream 0 is not blocked, because it only references entries that are
59 // already acknowledged by an Insert Count Increment instruction.
60 manager_.OnHeaderBlockSent(0, {1, 0});
bncf97492c2019-09-20 17:47:13 -070061 EXPECT_FALSE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -070062}
63
64TEST_F(QpackBlockingManagerTest, UnblockedByInsertCountIncrement) {
65 manager_.OnHeaderBlockSent(0, {1, 0});
bncf97492c2019-09-20 17:47:13 -070066 EXPECT_TRUE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -070067
68 manager_.OnInsertCountIncrement(2);
bncf97492c2019-09-20 17:47:13 -070069 EXPECT_FALSE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -070070}
71
72TEST_F(QpackBlockingManagerTest, NotBlockedByHeaderAcknowledgement) {
73 manager_.OnHeaderBlockSent(0, {2, 1, 1});
bncf97492c2019-09-20 17:47:13 -070074 EXPECT_TRUE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -070075
76 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
bncf97492c2019-09-20 17:47:13 -070077 EXPECT_FALSE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -070078
79 // Stream 1 is not blocked, because it only references entries that are
80 // already acknowledged by a Header Acknowledgement instruction.
81 manager_.OnHeaderBlockSent(1, {2, 2});
bncf97492c2019-09-20 17:47:13 -070082 EXPECT_FALSE(stream_is_blocked(1));
bncbdf981f2019-07-30 17:21:14 -070083}
84
85TEST_F(QpackBlockingManagerTest, UnblockedByHeaderAcknowledgement) {
86 manager_.OnHeaderBlockSent(0, {2, 1, 1});
87 manager_.OnHeaderBlockSent(1, {2, 2});
bncf97492c2019-09-20 17:47:13 -070088 EXPECT_TRUE(stream_is_blocked(0));
89 EXPECT_TRUE(stream_is_blocked(1));
bncbdf981f2019-07-30 17:21:14 -070090
91 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
bncf97492c2019-09-20 17:47:13 -070092 EXPECT_FALSE(stream_is_blocked(0));
93 EXPECT_FALSE(stream_is_blocked(1));
bncbdf981f2019-07-30 17:21:14 -070094}
95
96TEST_F(QpackBlockingManagerTest, KnownReceivedCount) {
97 EXPECT_EQ(0u, manager_.known_received_count());
98
99 // Sending a header block does not change Known Received Count.
100 manager_.OnHeaderBlockSent(0, {0});
101 EXPECT_EQ(0u, manager_.known_received_count());
102
103 manager_.OnHeaderBlockSent(1, {1});
104 EXPECT_EQ(0u, manager_.known_received_count());
105
106 // Header Acknowledgement might increase Known Received Count.
107 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
108 EXPECT_EQ(1u, manager_.known_received_count());
109
110 manager_.OnHeaderBlockSent(2, {5});
111 EXPECT_EQ(1u, manager_.known_received_count());
112
113 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
114 EXPECT_EQ(2u, manager_.known_received_count());
115
116 // Insert Count Increment increases Known Received Count.
117 manager_.OnInsertCountIncrement(2);
118 EXPECT_EQ(4u, manager_.known_received_count());
119
120 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(2));
121 EXPECT_EQ(6u, manager_.known_received_count());
122
123 // Stream Cancellation does not change Known Received Count.
124 manager_.OnStreamCancellation(0);
125 EXPECT_EQ(6u, manager_.known_received_count());
126
127 // Header Acknowledgement of a block with smaller Required Insert Count does
128 // not increase Known Received Count.
129 manager_.OnHeaderBlockSent(0, {3});
130 EXPECT_EQ(6u, manager_.known_received_count());
131
132 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
133 EXPECT_EQ(6u, manager_.known_received_count());
134
135 // Header Acknowledgement of a block with equal Required Insert Count does not
136 // increase Known Received Count.
137 manager_.OnHeaderBlockSent(1, {5});
138 EXPECT_EQ(6u, manager_.known_received_count());
139
140 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
141 EXPECT_EQ(6u, manager_.known_received_count());
142}
143
144TEST_F(QpackBlockingManagerTest, SmallestBlockingIndex) {
145 EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
146 manager_.smallest_blocking_index());
147
148 manager_.OnHeaderBlockSent(0, {0});
149 EXPECT_EQ(0u, manager_.smallest_blocking_index());
150
151 manager_.OnHeaderBlockSent(1, {2});
152 EXPECT_EQ(0u, manager_.smallest_blocking_index());
153
154 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
155 EXPECT_EQ(2u, manager_.smallest_blocking_index());
156
157 manager_.OnHeaderBlockSent(1, {1});
158 EXPECT_EQ(1u, manager_.smallest_blocking_index());
159
160 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(1));
161 EXPECT_EQ(1u, manager_.smallest_blocking_index());
162
163 // Insert Count Increment does not change smallest blocking index.
164 manager_.OnInsertCountIncrement(2);
165 EXPECT_EQ(1u, manager_.smallest_blocking_index());
166
167 manager_.OnStreamCancellation(1);
168 EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
169 manager_.smallest_blocking_index());
170}
171
172TEST_F(QpackBlockingManagerTest, HeaderAcknowledgementsOnSingleStream) {
173 EXPECT_EQ(0u, manager_.known_received_count());
bncbdf981f2019-07-30 17:21:14 -0700174 EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
175 manager_.smallest_blocking_index());
176
177 manager_.OnHeaderBlockSent(0, {2, 1, 1});
178 EXPECT_EQ(0u, manager_.known_received_count());
bncf97492c2019-09-20 17:47:13 -0700179 EXPECT_TRUE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -0700180 EXPECT_EQ(1u, manager_.smallest_blocking_index());
181
182 manager_.OnHeaderBlockSent(0, {1, 0});
183 EXPECT_EQ(0u, manager_.known_received_count());
bncf97492c2019-09-20 17:47:13 -0700184 EXPECT_TRUE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -0700185 EXPECT_EQ(0u, manager_.smallest_blocking_index());
186
187 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
188 EXPECT_EQ(3u, manager_.known_received_count());
bncf97492c2019-09-20 17:47:13 -0700189 EXPECT_FALSE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -0700190 EXPECT_EQ(0u, manager_.smallest_blocking_index());
191
192 manager_.OnHeaderBlockSent(0, {3});
193 EXPECT_EQ(3u, manager_.known_received_count());
bncf97492c2019-09-20 17:47:13 -0700194 EXPECT_TRUE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -0700195 EXPECT_EQ(0u, manager_.smallest_blocking_index());
196
197 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
198 EXPECT_EQ(3u, manager_.known_received_count());
bncf97492c2019-09-20 17:47:13 -0700199 EXPECT_TRUE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -0700200 EXPECT_EQ(3u, manager_.smallest_blocking_index());
201
202 EXPECT_TRUE(manager_.OnHeaderAcknowledgement(0));
203 EXPECT_EQ(4u, manager_.known_received_count());
bncf97492c2019-09-20 17:47:13 -0700204 EXPECT_FALSE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -0700205 EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
206 manager_.smallest_blocking_index());
207
208 EXPECT_FALSE(manager_.OnHeaderAcknowledgement(0));
209}
210
211TEST_F(QpackBlockingManagerTest, CancelStream) {
212 manager_.OnHeaderBlockSent(0, {3});
bncf97492c2019-09-20 17:47:13 -0700213 EXPECT_TRUE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -0700214 EXPECT_EQ(3u, manager_.smallest_blocking_index());
215
216 manager_.OnHeaderBlockSent(0, {2});
bncf97492c2019-09-20 17:47:13 -0700217 EXPECT_TRUE(stream_is_blocked(0));
bncbdf981f2019-07-30 17:21:14 -0700218 EXPECT_EQ(2u, manager_.smallest_blocking_index());
219
220 manager_.OnHeaderBlockSent(1, {4});
bncf97492c2019-09-20 17:47:13 -0700221 EXPECT_TRUE(stream_is_blocked(0));
222 EXPECT_TRUE(stream_is_blocked(1));
bncbdf981f2019-07-30 17:21:14 -0700223 EXPECT_EQ(2u, manager_.smallest_blocking_index());
224
225 manager_.OnStreamCancellation(0);
bncf97492c2019-09-20 17:47:13 -0700226 EXPECT_FALSE(stream_is_blocked(0));
227 EXPECT_TRUE(stream_is_blocked(1));
bncbdf981f2019-07-30 17:21:14 -0700228 EXPECT_EQ(4u, manager_.smallest_blocking_index());
229
230 manager_.OnStreamCancellation(1);
bncf97492c2019-09-20 17:47:13 -0700231 EXPECT_FALSE(stream_is_blocked(0));
232 EXPECT_FALSE(stream_is_blocked(1));
bncbdf981f2019-07-30 17:21:14 -0700233 EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
234 manager_.smallest_blocking_index());
235}
236
bnc6b2cf772019-08-13 05:19:21 -0700237TEST_F(QpackBlockingManagerTest,
238 ReferenceOnEncoderStreamUnblockedByInsertCountIncrement) {
239 EXPECT_EQ(0u, manager_.known_received_count());
240 EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
241 manager_.smallest_blocking_index());
242
243 // Entry 1 refers to entry 0.
244 manager_.OnReferenceSentOnEncoderStream(1, 0);
245 // Entry 2 also refers to entry 0.
246 manager_.OnReferenceSentOnEncoderStream(2, 0);
247
248 EXPECT_EQ(0u, manager_.known_received_count());
249 EXPECT_EQ(0u, manager_.smallest_blocking_index());
250
251 // Acknowledging entry 1 still leaves one unacknowledged reference to entry 0.
252 manager_.OnInsertCountIncrement(2);
253
254 EXPECT_EQ(2u, manager_.known_received_count());
255 EXPECT_EQ(0u, manager_.smallest_blocking_index());
256
257 // Entry 3 also refers to entry 2.
258 manager_.OnReferenceSentOnEncoderStream(3, 2);
259
260 EXPECT_EQ(2u, manager_.known_received_count());
261 EXPECT_EQ(0u, manager_.smallest_blocking_index());
262
263 // Acknowledging entry 2 removes last reference to entry 0.
264 manager_.OnInsertCountIncrement(1);
265
266 EXPECT_EQ(3u, manager_.known_received_count());
267 EXPECT_EQ(2u, manager_.smallest_blocking_index());
268
269 // Acknowledging entry 4 (and implicitly 3) removes reference to entry 2.
270 manager_.OnInsertCountIncrement(2);
271
272 EXPECT_EQ(5u, manager_.known_received_count());
273 EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
274 manager_.smallest_blocking_index());
275}
276
277TEST_F(QpackBlockingManagerTest,
278 ReferenceOnEncoderStreamUnblockedByHeaderAcknowledgement) {
279 EXPECT_EQ(0u, manager_.known_received_count());
280 EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
281 manager_.smallest_blocking_index());
282
283 // Entry 1 refers to entry 0.
284 manager_.OnReferenceSentOnEncoderStream(1, 0);
285 // Entry 2 also refers to entry 0.
286 manager_.OnReferenceSentOnEncoderStream(2, 0);
287
288 EXPECT_EQ(0u, manager_.known_received_count());
289 EXPECT_EQ(0u, manager_.smallest_blocking_index());
290
291 // Acknowledging a header block with entries up to 1 still leave one
292 // unacknowledged reference to entry 0.
293 manager_.OnHeaderBlockSent(/* stream_id = */ 0, {0, 1});
294 manager_.OnHeaderAcknowledgement(/* stream_id = */ 0);
295
296 EXPECT_EQ(2u, manager_.known_received_count());
297 EXPECT_EQ(0u, manager_.smallest_blocking_index());
298
299 // Entry 3 also refers to entry 2.
300 manager_.OnReferenceSentOnEncoderStream(3, 2);
301
302 // Acknowledging a header block with entries up to 2 removes last reference to
303 // entry 0.
304 manager_.OnHeaderBlockSent(/* stream_id = */ 0, {2, 0, 2});
305 manager_.OnHeaderAcknowledgement(/* stream_id = */ 0);
306
307 EXPECT_EQ(3u, manager_.known_received_count());
308 EXPECT_EQ(2u, manager_.smallest_blocking_index());
309
310 // Acknowledging entry 4 (and implicitly 3) removes reference to entry 2.
311 manager_.OnHeaderBlockSent(/* stream_id = */ 0, {1, 4, 2, 0});
312 manager_.OnHeaderAcknowledgement(/* stream_id = */ 0);
313
314 EXPECT_EQ(5u, manager_.known_received_count());
315 EXPECT_EQ(std::numeric_limits<uint64_t>::max(),
316 manager_.smallest_blocking_index());
317}
318
bncf97492c2019-09-20 17:47:13 -0700319TEST_F(QpackBlockingManagerTest, BlockingAllowedOnStream) {
320 const QuicStreamId kStreamId1 = 1;
321 const QuicStreamId kStreamId2 = 2;
322 const QuicStreamId kStreamId3 = 3;
323
324 // No stream can block if limit is 0.
325 EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 0));
326 EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 0));
327
328 // Either stream can block if limit is larger.
329 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
330 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
331
332 // Doubly block first stream.
333 manager_.OnHeaderBlockSent(kStreamId1, {0});
334 manager_.OnHeaderBlockSent(kStreamId1, {1});
335
336 // First stream is already blocked so it can carry more blocking references.
337 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
338 // Second stream is not allowed to block if limit is already reached.
339 EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
340
341 // Either stream can block if limit is larger than number of blocked streams.
342 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
343 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
344
345 // Block second stream.
346 manager_.OnHeaderBlockSent(kStreamId2, {2});
347
348 // Streams are already blocked so either can carry more blocking references.
349 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
350 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
351
352 // Third, unblocked stream is not allowed to block unless limit is strictly
353 // larger than number of blocked streams.
354 EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId3, 2));
355 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId3, 3));
356
357 // Acknowledge decoding of first header block on first stream.
358 // Stream is still blocked on its second header block.
359 manager_.OnHeaderAcknowledgement(kStreamId1);
360
bncf50ccf62019-09-27 09:51:45 -0700361 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
362 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
bncf97492c2019-09-20 17:47:13 -0700363
364 // Acknowledge decoding of second header block on first stream.
365 // This unblocks the stream.
366 manager_.OnHeaderAcknowledgement(kStreamId1);
367
368 // First stream is not allowed to block if limit is already reached.
369 EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
370 // Second stream is already blocked so it can carry more blocking references.
371 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
372
373 // Either stream can block if limit is larger than number of blocked streams.
374 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 2));
375 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 2));
376
377 // Unblock second stream.
378 manager_.OnHeaderAcknowledgement(kStreamId2);
379
380 // No stream can block if limit is 0.
381 EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId1, 0));
382 EXPECT_FALSE(manager_.blocking_allowed_on_stream(kStreamId2, 0));
383
384 // Either stream can block if limit is larger.
385 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId1, 1));
386 EXPECT_TRUE(manager_.blocking_allowed_on_stream(kStreamId2, 1));
387}
388
bncbdf981f2019-07-30 17:21:14 -0700389} // namespace
390} // namespace test
391} // namespace quic