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"
22 class EntropyTrackerPeer
{
24 static QuicPacketSequenceNumber
first_gap(
25 const QuicReceivedPacketManager::EntropyTracker
& tracker
) {
26 return tracker
.first_gap_
;
28 static QuicPacketSequenceNumber
largest_observed(
29 const QuicReceivedPacketManager::EntropyTracker
& tracker
) {
30 return tracker
.largest_observed_
;
32 static int packets_entropy_size(
33 const QuicReceivedPacketManager::EntropyTracker
& tracker
) {
34 return tracker
.packets_entropy_
.size();
36 static bool IsTrackingPacket(
37 const QuicReceivedPacketManager::EntropyTracker
& tracker
,
38 QuicPacketSequenceNumber sequence_number
) {
39 return sequence_number
>= tracker
.first_gap_
&&
41 (tracker
.first_gap_
+ tracker
.packets_entropy_
.size()) &&
42 tracker
.packets_entropy_
[sequence_number
- tracker
.first_gap_
].second
;
48 // Entropy of individual packets is not tracked if there are no gaps.
49 TEST(EntropyTrackerTest
, NoGaps
) {
50 QuicReceivedPacketManager::EntropyTracker tracker
;
52 tracker
.RecordPacketEntropyHash(1, 23);
53 tracker
.RecordPacketEntropyHash(2, 42);
55 EXPECT_EQ(23 ^ 42, tracker
.EntropyHash(2));
56 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker
));
58 EXPECT_EQ(2u, EntropyTrackerPeer::largest_observed(tracker
));
59 EXPECT_EQ(0, EntropyTrackerPeer::packets_entropy_size(tracker
));
60 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 1));
61 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 2));
64 // Entropy of individual packets is tracked as long as there are gaps.
65 // Filling the first gap results in entropy getting garbage collected.
66 TEST(EntropyTrackerTest
, FillGaps
) {
67 QuicReceivedPacketManager::EntropyTracker tracker
;
69 tracker
.RecordPacketEntropyHash(2, 5);
70 tracker
.RecordPacketEntropyHash(5, 17);
71 tracker
.RecordPacketEntropyHash(6, 23);
72 tracker
.RecordPacketEntropyHash(9, 42);
74 EXPECT_EQ(1u, EntropyTrackerPeer::first_gap(tracker
));
75 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
76 EXPECT_EQ(9, EntropyTrackerPeer::packets_entropy_size(tracker
));
78 EXPECT_EQ(5, tracker
.EntropyHash(2));
79 EXPECT_EQ(5 ^ 17, tracker
.EntropyHash(5));
80 EXPECT_EQ(5 ^ 17 ^ 23, tracker
.EntropyHash(6));
81 EXPECT_EQ(5 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
83 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 1));
84 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 2));
85 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 5));
86 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 6));
87 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 9));
90 tracker
.RecordPacketEntropyHash(1, 2);
92 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker
));
93 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
94 EXPECT_EQ(7, EntropyTrackerPeer::packets_entropy_size(tracker
));
96 EXPECT_EQ(2 ^ 5 ^ 17, tracker
.EntropyHash(5));
97 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23, tracker
.EntropyHash(6));
98 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
100 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 1));
101 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 2));
102 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 5));
103 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 6));
104 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 9));
106 // Fill the gap at 4.
107 tracker
.RecordPacketEntropyHash(4, 2);
109 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker
));
110 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
111 EXPECT_EQ(7, EntropyTrackerPeer::packets_entropy_size(tracker
));
113 EXPECT_EQ(5, tracker
.EntropyHash(4));
114 EXPECT_EQ(5 ^ 17, tracker
.EntropyHash(5));
115 EXPECT_EQ(5 ^ 17 ^ 23, tracker
.EntropyHash(6));
116 EXPECT_EQ(5 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
118 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 3));
119 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 4));
120 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 5));
121 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 6));
122 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 9));
124 // Fill the gap at 3. Entropy for packets 3 to 6 are forgotten.
125 tracker
.RecordPacketEntropyHash(3, 2);
127 EXPECT_EQ(7u, EntropyTrackerPeer::first_gap(tracker
));
128 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
129 EXPECT_EQ(3, EntropyTrackerPeer::packets_entropy_size(tracker
));
131 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
133 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 3));
134 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 4));
135 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 5));
136 EXPECT_FALSE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 6));
137 EXPECT_TRUE(EntropyTrackerPeer::IsTrackingPacket(tracker
, 9));
140 tracker
.RecordPacketEntropyHash(7, 2);
141 tracker
.RecordPacketEntropyHash(8, 2);
143 EXPECT_EQ(10u, EntropyTrackerPeer::first_gap(tracker
));
144 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
145 EXPECT_EQ(0, EntropyTrackerPeer::packets_entropy_size(tracker
));
147 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
150 TEST(EntropyTrackerTest
, SetCumulativeEntropyUpTo
) {
151 QuicReceivedPacketManager::EntropyTracker tracker
;
153 tracker
.RecordPacketEntropyHash(2, 5);
154 tracker
.RecordPacketEntropyHash(5, 17);
155 tracker
.RecordPacketEntropyHash(6, 23);
156 tracker
.RecordPacketEntropyHash(9, 42);
158 EXPECT_EQ(1u, EntropyTrackerPeer::first_gap(tracker
));
159 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
160 EXPECT_EQ(9, EntropyTrackerPeer::packets_entropy_size(tracker
));
162 // Inform the tracker about value of the hash at a gap.
163 tracker
.SetCumulativeEntropyUpTo(3, 7);
164 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker
));
165 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
166 EXPECT_EQ(7, EntropyTrackerPeer::packets_entropy_size(tracker
));
168 EXPECT_EQ(7 ^ 17, tracker
.EntropyHash(5));
169 EXPECT_EQ(7 ^ 17 ^ 23, tracker
.EntropyHash(6));
170 EXPECT_EQ(7 ^ 17 ^ 23 ^ 42, tracker
.EntropyHash(9));
172 // Inform the tracker about value of the hash at a known location.
173 tracker
.SetCumulativeEntropyUpTo(6, 1);
174 EXPECT_EQ(7u, EntropyTrackerPeer::first_gap(tracker
));
175 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
176 EXPECT_EQ(3, EntropyTrackerPeer::packets_entropy_size(tracker
));
178 EXPECT_EQ(1 ^ 23 ^ 42, tracker
.EntropyHash(9));
180 // Inform the tracker about value of the hash at the last location.
181 tracker
.SetCumulativeEntropyUpTo(9, 21);
182 EXPECT_EQ(10u, EntropyTrackerPeer::first_gap(tracker
));
183 EXPECT_EQ(9u, EntropyTrackerPeer::largest_observed(tracker
));
184 EXPECT_EQ(0, EntropyTrackerPeer::packets_entropy_size(tracker
));
186 EXPECT_EQ(42 ^ 21, tracker
.EntropyHash(9));
189 class QuicReceivedPacketManagerTest
: public ::testing::Test
{
191 QuicReceivedPacketManagerTest() : received_manager_(&stats_
) {}
193 void RecordPacketReceipt(QuicPacketSequenceNumber sequence_number
,
194 QuicPacketEntropyHash entropy_hash
) {
195 RecordPacketReceipt(sequence_number
, entropy_hash
, QuicTime::Zero());
198 void RecordPacketReceipt(QuicPacketSequenceNumber sequence_number
,
199 QuicPacketEntropyHash entropy_hash
,
200 QuicTime receipt_time
) {
201 QuicPacketHeader header
;
202 header
.packet_sequence_number
= sequence_number
;
203 header
.entropy_hash
= entropy_hash
;
204 received_manager_
.RecordPacketReceived(0u, header
, receipt_time
);
207 void RecordPacketRevived(QuicPacketSequenceNumber sequence_number
) {
208 received_manager_
.RecordPacketRevived(sequence_number
);
211 QuicConnectionStats stats_
;
212 QuicReceivedPacketManager received_manager_
;
215 TEST_F(QuicReceivedPacketManagerTest
, ReceivedPacketEntropyHash
) {
216 vector
<pair
<QuicPacketSequenceNumber
, QuicPacketEntropyHash
> > entropies
;
217 entropies
.push_back(make_pair(1, 12));
218 entropies
.push_back(make_pair(7, 1));
219 entropies
.push_back(make_pair(2, 33));
220 entropies
.push_back(make_pair(5, 3));
221 entropies
.push_back(make_pair(8, 34));
223 for (size_t i
= 0; i
< entropies
.size(); ++i
) {
224 RecordPacketReceipt(entropies
[i
].first
, entropies
[i
].second
);
227 sort(entropies
.begin(), entropies
.end());
229 QuicPacketEntropyHash hash
= 0;
231 for (size_t i
= 1; i
<= (*entropies
.rbegin()).first
; ++i
) {
232 if (entropies
[index
].first
== i
) {
233 hash
^= entropies
[index
].second
;
237 EXPECT_EQ(hash
, received_manager_
.EntropyHash(i
));
239 // Reorder by 5 when 2 is received after 7.
240 EXPECT_EQ(5u, stats_
.max_sequence_reordering
);
241 EXPECT_EQ(0u, stats_
.max_time_reordering_us
);
242 EXPECT_EQ(2u, stats_
.packets_reordered
);
245 TEST_F(QuicReceivedPacketManagerTest
, EntropyHashBelowLeastObserved
) {
246 EXPECT_EQ(0, received_manager_
.EntropyHash(0));
247 RecordPacketReceipt(4, 5);
248 EXPECT_EQ(0, received_manager_
.EntropyHash(3));
251 TEST_F(QuicReceivedPacketManagerTest
, EntropyHashAboveLargestObserved
) {
252 EXPECT_EQ(0, received_manager_
.EntropyHash(0));
253 RecordPacketReceipt(4, 5);
254 EXPECT_EQ(0, received_manager_
.EntropyHash(3));
257 TEST_F(QuicReceivedPacketManagerTest
, SetCumulativeEntropyUpTo
) {
258 vector
<pair
<QuicPacketSequenceNumber
, QuicPacketEntropyHash
> > entropies
;
259 entropies
.push_back(make_pair(1, 12));
260 entropies
.push_back(make_pair(2, 1));
261 entropies
.push_back(make_pair(3, 33));
262 entropies
.push_back(make_pair(4, 3));
263 entropies
.push_back(make_pair(6, 34));
264 entropies
.push_back(make_pair(7, 29));
266 QuicPacketEntropyHash entropy_hash
= 0;
267 for (size_t i
= 0; i
< entropies
.size(); ++i
) {
268 RecordPacketReceipt(entropies
[i
].first
, entropies
[i
].second
);
269 entropy_hash
^= entropies
[i
].second
;
271 EXPECT_EQ(entropy_hash
, received_manager_
.EntropyHash(7));
273 // Now set the entropy hash up to 5 to be 100.
275 for (size_t i
= 0; i
< 4; ++i
) {
276 entropy_hash
^= entropies
[i
].second
;
278 QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo(
279 &received_manager_
, 5, 100);
280 EXPECT_EQ(entropy_hash
, received_manager_
.EntropyHash(7));
282 QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo(
283 &received_manager_
, 1, 50);
284 EXPECT_EQ(entropy_hash
, received_manager_
.EntropyHash(7));
287 EXPECT_EQ(0u, stats_
.max_sequence_reordering
);
288 EXPECT_EQ(0u, stats_
.max_time_reordering_us
);
289 EXPECT_EQ(0u, stats_
.packets_reordered
);
292 TEST_F(QuicReceivedPacketManagerTest
, DontWaitForPacketsBefore
) {
293 QuicPacketHeader header
;
294 header
.packet_sequence_number
= 2u;
295 received_manager_
.RecordPacketReceived(0u, header
, QuicTime::Zero());
296 header
.packet_sequence_number
= 7u;
297 received_manager_
.RecordPacketReceived(0u, header
, QuicTime::Zero());
298 EXPECT_TRUE(received_manager_
.IsAwaitingPacket(3u));
299 EXPECT_TRUE(received_manager_
.IsAwaitingPacket(6u));
300 EXPECT_TRUE(QuicReceivedPacketManagerPeer::DontWaitForPacketsBefore(
301 &received_manager_
, 4));
302 EXPECT_FALSE(received_manager_
.IsAwaitingPacket(3u));
303 EXPECT_TRUE(received_manager_
.IsAwaitingPacket(6u));
306 TEST_F(QuicReceivedPacketManagerTest
, UpdateReceivedPacketInfo
) {
307 QuicPacketHeader header
;
308 header
.packet_sequence_number
= 2u;
309 QuicTime two_ms
= QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2));
310 received_manager_
.RecordPacketReceived(0u, header
, two_ms
);
313 received_manager_
.UpdateReceivedPacketInfo(&ack
, QuicTime::Zero());
314 // When UpdateReceivedPacketInfo with a time earlier than the time of the
315 // largest observed packet, make sure that the delta is 0, not negative.
316 EXPECT_EQ(QuicTime::Delta::Zero(), ack
.delta_time_largest_observed
);
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(1000u, 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());