1 // Copyright 2013 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.
5 #include "net/quic/quic_received_packet_manager.h"
10 #include "net/quic/quic_connection_stats.h"
11 #include "net/quic/test_tools/quic_received_packet_manager_peer.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
21 class EntropyTrackerPeer
{
23 static QuicPacketNumber
first_gap(
24 const QuicReceivedPacketManager::EntropyTracker
& tracker
) {
25 return tracker
.first_gap_
;
27 static QuicPacketNumber
largest_observed(
28 const QuicReceivedPacketManager::EntropyTracker
& tracker
) {
29 return tracker
.largest_observed_
;
31 static int packets_entropy_size(
32 const QuicReceivedPacketManager::EntropyTracker
& tracker
) {
33 return tracker
.packets_entropy_
.size();
35 static bool IsTrackingPacket(
36 const QuicReceivedPacketManager::EntropyTracker
& tracker
,
37 QuicPacketNumber packet_number
) {
38 return packet_number
>= tracker
.first_gap_
&&
40 (tracker
.first_gap_
+ tracker
.packets_entropy_
.size()) &&
41 tracker
.packets_entropy_
[packet_number
- tracker
.first_gap_
].second
;
47 // Entropy of individual packets is not tracked if there are no gaps.
48 TEST(EntropyTrackerTest
, NoGaps
) {
49 QuicReceivedPacketManager::EntropyTracker tracker
;
51 tracker
.RecordPacketEntropyHash(1, 23);
52 tracker
.RecordPacketEntropyHash(2, 42);
54 EXPECT_EQ(23 ^ 42, tracker
.EntropyHash(2));
55 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker
));
57 EXPECT_EQ(2u, EntropyTrackerPeer::largest_observed(tracker
));
58 EXPECT_EQ(0, EntropyTrackerPeer::packets_entropy_size(tracker
));
59 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 1));
60 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 2));
63 // Entropy of individual packets is tracked as long as there are gaps.
64 // Filling the first gap results in entropy getting garbage collected.
65 TEST(EntropyTrackerTest
, FillGaps
) {
66 QuicReceivedPacketManager::EntropyTracker tracker
;
68 tracker
.RecordPacketEntropyHash(2, 5);
69 tracker
.RecordPacketEntropyHash(5, 17);
70 tracker
.RecordPacketEntropyHash(6, 23);
71 tracker
.RecordPacketEntropyHash(9, 42);
73 EXPECT_EQ(1u, EntropyTrackerPeer::first_gap(tracker
));
74 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
75 EXPECT_EQ(9, EntropyTrackerPeer::packets_entropy_size(tracker
));
77 EXPECT_EQ(5, tracker
.EntropyHash(2));
78 EXPECT_EQ(5 ^ 17, tracker
.EntropyHash(5));
79 EXPECT_EQ(5 ^ 17 ^ 23, tracker
.EntropyHash(6));
80 EXPECT_EQ(5 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
82 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 1));
83 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 2));
84 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 5));
85 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 6));
86 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 9));
89 tracker
.RecordPacketEntropyHash(1, 2);
91 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker
));
92 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
93 EXPECT_EQ(7, EntropyTrackerPeer::packets_entropy_size(tracker
));
95 EXPECT_EQ(2 ^ 5 ^ 17, tracker
.EntropyHash(5));
96 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23, tracker
.EntropyHash(6));
97 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
99 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 1));
100 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 2));
101 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 5));
102 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 6));
103 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 9));
105 // Fill the gap at 4.
106 tracker
.RecordPacketEntropyHash(4, 2);
108 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker
));
109 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
110 EXPECT_EQ(7, EntropyTrackerPeer::packets_entropy_size(tracker
));
112 EXPECT_EQ(5, tracker
.EntropyHash(4));
113 EXPECT_EQ(5 ^ 17, tracker
.EntropyHash(5));
114 EXPECT_EQ(5 ^ 17 ^ 23, tracker
.EntropyHash(6));
115 EXPECT_EQ(5 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
117 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 3));
118 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 4));
119 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 5));
120 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 6));
121 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 9));
123 // Fill the gap at 3. Entropy for packets 3 to 6 are forgotten.
124 tracker
.RecordPacketEntropyHash(3, 2);
126 EXPECT_EQ(7u, EntropyTrackerPeer::first_gap(tracker
));
127 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
128 EXPECT_EQ(3, EntropyTrackerPeer::packets_entropy_size(tracker
));
130 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
132 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 3));
133 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 4));
134 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 5));
135 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 6));
136 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 9));
139 tracker
.RecordPacketEntropyHash(7, 2);
140 tracker
.RecordPacketEntropyHash(8, 2);
142 EXPECT_EQ(10u, EntropyTrackerPeer::first_gap(tracker
));
143 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
144 EXPECT_EQ(0, EntropyTrackerPeer::packets_entropy_size(tracker
));
146 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
149 TEST(EntropyTrackerTest
, SetCumulativeEntropyUpTo
) {
150 QuicReceivedPacketManager::EntropyTracker tracker
;
152 tracker
.RecordPacketEntropyHash(2, 5);
153 tracker
.RecordPacketEntropyHash(5, 17);
154 tracker
.RecordPacketEntropyHash(6, 23);
155 tracker
.RecordPacketEntropyHash(9, 42);
157 EXPECT_EQ(1u, EntropyTrackerPeer::first_gap(tracker
));
158 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
159 EXPECT_EQ(9, EntropyTrackerPeer::packets_entropy_size(tracker
));
161 // Inform the tracker about value of the hash at a gap.
162 tracker
.SetCumulativeEntropyUpTo(3, 7);
163 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker
));
164 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
165 EXPECT_EQ(7, EntropyTrackerPeer::packets_entropy_size(tracker
));
167 EXPECT_EQ(7 ^ 17, tracker
.EntropyHash(5));
168 EXPECT_EQ(7 ^ 17 ^ 23, tracker
.EntropyHash(6));
169 EXPECT_EQ(7 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
171 // Inform the tracker about value of the hash at a known location.
172 tracker
.SetCumulativeEntropyUpTo(6, 1);
173 EXPECT_EQ(7u, EntropyTrackerPeer::first_gap(tracker
));
174 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
175 EXPECT_EQ(3, EntropyTrackerPeer::packets_entropy_size(tracker
));
177 EXPECT_EQ(1 ^ 23 ^ 42, tracker
.EntropyHash(9));
179 // Inform the tracker about value of the hash at the last location.
180 tracker
.SetCumulativeEntropyUpTo(9, 21);
181 EXPECT_EQ(10u, EntropyTrackerPeer::first_gap(tracker
));
182 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
183 EXPECT_EQ(0, EntropyTrackerPeer::packets_entropy_size(tracker
));
185 EXPECT_EQ(42 ^ 21, tracker
.EntropyHash(9));
188 class QuicReceivedPacketManagerTest
: public ::testing::Test
{
190 QuicReceivedPacketManagerTest() : received_manager_(&stats_
) {}
192 void RecordPacketReceipt(QuicPacketNumber packet_number
,
193 QuicPacketEntropyHash entropy_hash
) {
194 RecordPacketReceipt(packet_number
, entropy_hash
, QuicTime::Zero());
197 void RecordPacketReceipt(QuicPacketNumber packet_number
,
198 QuicPacketEntropyHash entropy_hash
,
199 QuicTime receipt_time
) {
200 QuicPacketHeader header
;
201 header
.packet_packet_number
= packet_number
;
202 header
.entropy_hash
= entropy_hash
;
203 received_manager_
.RecordPacketReceived(0u, header
, receipt_time
);
206 void RecordPacketRevived(QuicPacketNumber packet_number
) {
207 received_manager_
.RecordPacketRevived(packet_number
);
210 QuicConnectionStats stats_
;
211 QuicReceivedPacketManager received_manager_
;
214 TEST_F(QuicReceivedPacketManagerTest
, ReceivedPacketEntropyHash
) {
215 vector
<pair
<QuicPacketNumber
, QuicPacketEntropyHash
>> entropies
;
216 entropies
.push_back(std::make_pair(1, 12));
217 entropies
.push_back(std::make_pair(7, 1));
218 entropies
.push_back(std::make_pair(2, 33));
219 entropies
.push_back(std::make_pair(5, 3));
220 entropies
.push_back(std::make_pair(8, 34));
222 for (size_t i
= 0; i
< entropies
.size(); ++i
) {
223 RecordPacketReceipt(entropies
[i
].first
, entropies
[i
].second
);
226 std::sort(entropies
.begin(), entropies
.end());
228 QuicPacketEntropyHash hash
= 0;
230 for (size_t i
= 1; i
<= (*entropies
.rbegin()).first
; ++i
) {
231 if (entropies
[index
].first
== i
) {
232 hash
^= entropies
[index
].second
;
236 EXPECT_EQ(hash
, received_manager_
.EntropyHash(i
));
238 // Reorder by 5 when 2 is received after 7.
239 EXPECT_EQ(5u, stats_
.max_sequence_reordering
);
240 EXPECT_EQ(0, stats_
.max_time_reordering_us
);
241 EXPECT_EQ(2u, stats_
.packets_reordered
);
244 TEST_F(QuicReceivedPacketManagerTest
, EntropyHashBelowLeastObserved
) {
245 EXPECT_EQ(0, received_manager_
.EntropyHash(0));
246 RecordPacketReceipt(4, 5);
247 EXPECT_EQ(0, received_manager_
.EntropyHash(3));
250 TEST_F(QuicReceivedPacketManagerTest
, EntropyHashAboveLargestObserved
) {
251 EXPECT_EQ(0, received_manager_
.EntropyHash(0));
252 RecordPacketReceipt(4, 5);
253 EXPECT_EQ(0, received_manager_
.EntropyHash(3));
256 TEST_F(QuicReceivedPacketManagerTest
, SetCumulativeEntropyUpTo
) {
257 vector
<pair
<QuicPacketNumber
, QuicPacketEntropyHash
>> entropies
;
258 entropies
.push_back(std::make_pair(1, 12));
259 entropies
.push_back(std::make_pair(2, 1));
260 entropies
.push_back(std::make_pair(3, 33));
261 entropies
.push_back(std::make_pair(4, 3));
262 entropies
.push_back(std::make_pair(6, 34));
263 entropies
.push_back(std::make_pair(7, 29));
265 QuicPacketEntropyHash entropy_hash
= 0;
266 for (size_t i
= 0; i
< entropies
.size(); ++i
) {
267 RecordPacketReceipt(entropies
[i
].first
, entropies
[i
].second
);
268 entropy_hash
^= entropies
[i
].second
;
270 EXPECT_EQ(entropy_hash
, received_manager_
.EntropyHash(7));
272 // Now set the entropy hash up to 5 to be 100.
274 for (size_t i
= 0; i
< 4; ++i
) {
275 entropy_hash
^= entropies
[i
].second
;
277 QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo(
278 &received_manager_
, 5, 100);
279 EXPECT_EQ(entropy_hash
, received_manager_
.EntropyHash(7));
281 QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo(
282 &received_manager_
, 1, 50);
283 EXPECT_EQ(entropy_hash
, received_manager_
.EntropyHash(7));
286 EXPECT_EQ(0u, stats_
.max_sequence_reordering
);
287 EXPECT_EQ(0, stats_
.max_time_reordering_us
);
288 EXPECT_EQ(0u, stats_
.packets_reordered
);
291 TEST_F(QuicReceivedPacketManagerTest
, DontWaitForPacketsBefore
) {
292 QuicPacketHeader header
;
293 header
.packet_packet_number
= 2u;
294 received_manager_
.RecordPacketReceived(0u, header
, QuicTime::Zero());
295 header
.packet_packet_number
= 7u;
296 received_manager_
.RecordPacketReceived(0u, header
, QuicTime::Zero());
297 EXPECT_TRUE(received_manager_
.IsAwaitingPacket(3u));
298 EXPECT_TRUE(received_manager_
.IsAwaitingPacket(6u));
299 EXPECT_TRUE(QuicReceivedPacketManagerPeer::DontWaitForPacketsBefore(
300 &received_manager_
, 4));
301 EXPECT_FALSE(received_manager_
.IsAwaitingPacket(3u));
302 EXPECT_TRUE(received_manager_
.IsAwaitingPacket(6u));
305 TEST_F(QuicReceivedPacketManagerTest
, UpdateReceivedPacketInfo
) {
306 QuicPacketHeader header
;
307 header
.packet_packet_number
= 2u;
308 QuicTime two_ms
= QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2));
309 received_manager_
.RecordPacketReceived(0u, header
, two_ms
);
312 received_manager_
.UpdateReceivedPacketInfo(&ack
, QuicTime::Zero());
313 // When UpdateReceivedPacketInfo with a time earlier than the time of the
314 // largest observed packet, make sure that the delta is 0, not negative.
315 EXPECT_EQ(QuicTime::Delta::Zero(), ack
.delta_time_largest_observed
);
316 EXPECT_FALSE(ack
.received_packet_times
.empty());
318 QuicTime four_ms
= QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(4));
319 received_manager_
.UpdateReceivedPacketInfo(&ack
, four_ms
);
320 // When UpdateReceivedPacketInfo after not having received a new packet,
321 // the delta should still be accurate.
322 EXPECT_EQ(QuicTime::Delta::FromMilliseconds(2),
323 ack
.delta_time_largest_observed
);
326 TEST_F(QuicReceivedPacketManagerTest
, UpdateReceivedConnectionStats
) {
327 RecordPacketReceipt(1, 0);
328 RecordPacketReceipt(6, 0);
330 2, 0, QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(1)));
332 EXPECT_EQ(4u, stats_
.max_sequence_reordering
);
333 EXPECT_EQ(1000, stats_
.max_time_reordering_us
);
334 EXPECT_EQ(1u, stats_
.packets_reordered
);
337 TEST_F(QuicReceivedPacketManagerTest
, RevivedPacket
) {
338 RecordPacketReceipt(1, 0);
339 RecordPacketReceipt(3, 0);
340 RecordPacketRevived(2);
343 received_manager_
.UpdateReceivedPacketInfo(&ack
, QuicTime::Zero());
344 EXPECT_EQ(1u, ack
.missing_packets
.size());
345 EXPECT_EQ(2u, *ack
.missing_packets
.begin());
346 EXPECT_EQ(1u, ack
.revived_packets
.size());
347 EXPECT_EQ(2u, *ack
.missing_packets
.begin());
350 TEST_F(QuicReceivedPacketManagerTest
, PacketRevivedThenReceived
) {
351 RecordPacketReceipt(1, 0);
352 RecordPacketReceipt(3, 0);
353 RecordPacketRevived(2);
354 RecordPacketReceipt(2, 0);
357 received_manager_
.UpdateReceivedPacketInfo(&ack
, QuicTime::Zero());
358 EXPECT_TRUE(ack
.missing_packets
.empty());
359 EXPECT_TRUE(ack
.revived_packets
.empty());