OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/quic/quic_received_packet_manager.h" | |
6 | |
7 #include <algorithm> | |
8 #include <vector> | |
9 | |
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" | |
14 | |
15 using std::pair; | |
16 using std::vector; | |
17 | |
18 namespace net { | |
19 namespace test { | |
20 | |
21 class EntropyTrackerPeer { | |
22 public: | |
23 static QuicPacketSequenceNumber first_gap( | |
24 const QuicReceivedPacketManager::EntropyTracker& tracker) { | |
25 return tracker.first_gap_; | |
26 } | |
27 static QuicPacketSequenceNumber largest_observed( | |
28 const QuicReceivedPacketManager::EntropyTracker& tracker) { | |
29 return tracker.largest_observed_; | |
30 } | |
31 static int packets_entropy_size( | |
32 const QuicReceivedPacketManager::EntropyTracker& tracker) { | |
33 return tracker.packets_entropy_.size(); | |
34 } | |
35 static bool IsTrackingPacket( | |
36 const QuicReceivedPacketManager::EntropyTracker& tracker, | |
37 QuicPacketSequenceNumber sequence_number) { | |
38 return sequence_number >= tracker.first_gap_ && | |
39 sequence_number < | |
40 (tracker.first_gap_ + tracker.packets_entropy_.size()) && | |
41 tracker.packets_entropy_[sequence_number - tracker.first_gap_].second; | |
42 } | |
43 }; | |
44 | |
45 namespace { | |
46 | |
47 // Entropy of individual packets is not tracked if there are no gaps. | |
48 TEST(EntropyTrackerTest, NoGaps) { | |
49 QuicReceivedPacketManager::EntropyTracker tracker; | |
50 | |
51 tracker.RecordPacketEntropyHash(1, 23); | |
52 tracker.RecordPacketEntropyHash(2, 42); | |
53 | |
54 EXPECT_EQ(23 ^ 42, tracker.EntropyHash(2)); | |
55 EXPECT_EQ(3u, EntropyTrackerPeer::first_gap(tracker)); | |
56 | |
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)); | |
61 } | |
62 | |
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; | |
67 | |
68 tracker.RecordPacketEntropyHash(2, 5); | |
69 tracker.RecordPacketEntropyHash(5, 17); | |
70 tracker.RecordPacketEntropyHash(6, 23); | |
71 tracker.RecordPacketEntropyHash(9, 42); | |
72 | |
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)); | |
76 | |
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)); | |
81 | |
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)); | |
87 | |
88 // Fill the gap at 1. | |
89 tracker.RecordPacketEntropyHash(1, 2); | |
90 | |
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)); | |
94 | |
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)); | |
98 | |
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)); | |
104 | |
105 // Fill the gap at 4. | |
106 tracker.RecordPacketEntropyHash(4, 2); | |
107 | |
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)); | |
111 | |
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)); | |
116 | |
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)); | |
122 | |
123 // Fill the gap at 3. Entropy for packets 3 to 6 are forgotten. | |
124 tracker.RecordPacketEntropyHash(3, 2); | |
125 | |
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)); | |
129 | |
130 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker.EntropyHash(9)); | |
131 | |
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)); | |
137 | |
138 // Fill in the rest. | |
139 tracker.RecordPacketEntropyHash(7, 2); | |
140 tracker.RecordPacketEntropyHash(8, 2); | |
141 | |
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)); | |
145 | |
146 EXPECT_EQ(2 ^ 5 ^ 17 ^ 23 ^ 42, tracker.EntropyHash(9)); | |
147 } | |
148 | |
149 TEST(EntropyTrackerTest, SetCumulativeEntropyUpTo) { | |
150 QuicReceivedPacketManager::EntropyTracker tracker; | |
151 | |
152 tracker.RecordPacketEntropyHash(2, 5); | |
153 tracker.RecordPacketEntropyHash(5, 17); | |
154 tracker.RecordPacketEntropyHash(6, 23); | |
155 tracker.RecordPacketEntropyHash(9, 42); | |
156 | |
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)); | |
160 | |
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)); | |
166 | |
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)); | |
170 | |
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)); | |
176 | |
177 EXPECT_EQ(1 ^ 23 ^ 42, tracker.EntropyHash(9)); | |
178 | |
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)); | |
184 | |
185 EXPECT_EQ(42 ^ 21, tracker.EntropyHash(9)); | |
186 } | |
187 | |
188 class QuicReceivedPacketManagerTest : public ::testing::Test { | |
189 protected: | |
190 QuicReceivedPacketManagerTest() : received_manager_(&stats_) {} | |
191 | |
192 void RecordPacketReceipt(QuicPacketSequenceNumber sequence_number, | |
193 QuicPacketEntropyHash entropy_hash) { | |
194 RecordPacketReceipt(sequence_number, entropy_hash, QuicTime::Zero()); | |
195 } | |
196 | |
197 void RecordPacketReceipt(QuicPacketSequenceNumber sequence_number, | |
198 QuicPacketEntropyHash entropy_hash, | |
199 QuicTime receipt_time) { | |
200 QuicPacketHeader header; | |
201 header.packet_sequence_number = sequence_number; | |
202 header.entropy_hash = entropy_hash; | |
203 received_manager_.RecordPacketReceived(0u, header, receipt_time); | |
204 } | |
205 | |
206 void RecordPacketRevived(QuicPacketSequenceNumber sequence_number) { | |
207 received_manager_.RecordPacketRevived(sequence_number); | |
208 } | |
209 | |
210 QuicConnectionStats stats_; | |
211 QuicReceivedPacketManager received_manager_; | |
212 }; | |
213 | |
214 TEST_F(QuicReceivedPacketManagerTest, ReceivedPacketEntropyHash) { | |
215 vector<pair<QuicPacketSequenceNumber, 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)); | |
221 | |
222 for (size_t i = 0; i < entropies.size(); ++i) { | |
223 RecordPacketReceipt(entropies[i].first, entropies[i].second); | |
224 } | |
225 | |
226 std::sort(entropies.begin(), entropies.end()); | |
227 | |
228 QuicPacketEntropyHash hash = 0; | |
229 size_t index = 0; | |
230 for (size_t i = 1; i <= (*entropies.rbegin()).first; ++i) { | |
231 if (entropies[index].first == i) { | |
232 hash ^= entropies[index].second; | |
233 ++index; | |
234 } | |
235 if (i < 3) continue; | |
236 EXPECT_EQ(hash, received_manager_.EntropyHash(i)); | |
237 } | |
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); | |
242 } | |
243 | |
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)); | |
248 } | |
249 | |
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)); | |
254 } | |
255 | |
256 TEST_F(QuicReceivedPacketManagerTest, SetCumulativeEntropyUpTo) { | |
257 vector<pair<QuicPacketSequenceNumber, 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)); | |
264 | |
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; | |
269 } | |
270 EXPECT_EQ(entropy_hash, received_manager_.EntropyHash(7)); | |
271 | |
272 // Now set the entropy hash up to 5 to be 100. | |
273 entropy_hash ^= 100; | |
274 for (size_t i = 0; i < 4; ++i) { | |
275 entropy_hash ^= entropies[i].second; | |
276 } | |
277 QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo( | |
278 &received_manager_, 5, 100); | |
279 EXPECT_EQ(entropy_hash, received_manager_.EntropyHash(7)); | |
280 | |
281 QuicReceivedPacketManagerPeer::SetCumulativeEntropyUpTo( | |
282 &received_manager_, 1, 50); | |
283 EXPECT_EQ(entropy_hash, received_manager_.EntropyHash(7)); | |
284 | |
285 // No reordering. | |
286 EXPECT_EQ(0u, stats_.max_sequence_reordering); | |
287 EXPECT_EQ(0, stats_.max_time_reordering_us); | |
288 EXPECT_EQ(0u, stats_.packets_reordered); | |
289 } | |
290 | |
291 TEST_F(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) { | |
292 QuicPacketHeader header; | |
293 header.packet_sequence_number = 2u; | |
294 received_manager_.RecordPacketReceived(0u, header, QuicTime::Zero()); | |
295 header.packet_sequence_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)); | |
303 } | |
304 | |
305 TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedPacketInfo) { | |
306 QuicPacketHeader header; | |
307 header.packet_sequence_number = 2u; | |
308 QuicTime two_ms = QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(2)); | |
309 received_manager_.RecordPacketReceived(0u, header, two_ms); | |
310 | |
311 QuicAckFrame ack; | |
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()); | |
317 | |
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); | |
324 } | |
325 | |
326 TEST_F(QuicReceivedPacketManagerTest, UpdateReceivedConnectionStats) { | |
327 RecordPacketReceipt(1, 0); | |
328 RecordPacketReceipt(6, 0); | |
329 RecordPacketReceipt( | |
330 2, 0, QuicTime::Zero().Add(QuicTime::Delta::FromMilliseconds(1))); | |
331 | |
332 EXPECT_EQ(4u, stats_.max_sequence_reordering); | |
333 EXPECT_EQ(1000, stats_.max_time_reordering_us); | |
334 EXPECT_EQ(1u, stats_.packets_reordered); | |
335 } | |
336 | |
337 TEST_F(QuicReceivedPacketManagerTest, RevivedPacket) { | |
338 RecordPacketReceipt(1, 0); | |
339 RecordPacketReceipt(3, 0); | |
340 RecordPacketRevived(2); | |
341 | |
342 QuicAckFrame ack; | |
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()); | |
348 } | |
349 | |
350 TEST_F(QuicReceivedPacketManagerTest, PacketRevivedThenReceived) { | |
351 RecordPacketReceipt(1, 0); | |
352 RecordPacketReceipt(3, 0); | |
353 RecordPacketRevived(2); | |
354 RecordPacketReceipt(2, 0); | |
355 | |
356 QuicAckFrame ack; | |
357 received_manager_.UpdateReceivedPacketInfo(&ack, QuicTime::Zero()); | |
358 EXPECT_TRUE(ack.missing_packets.empty()); | |
359 EXPECT_TRUE(ack.revived_packets.empty()); | |
360 } | |
361 | |
362 | |
363 } // namespace | |
364 } // namespace test | |
365 } // namespace net | |
OLD | NEW |