OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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_stream_sequencer.h" | |
6 | |
7 #include <algorithm> | |
8 #include <cstdint> | |
9 #include <memory> | |
10 #include <utility> | |
11 #include <vector> | |
12 | |
13 #include "base/logging.h" | |
14 #include "base/rand_util.h" | |
15 #include "net/base/ip_endpoint.h" | |
16 #include "net/quic/quic_flags.h" | |
17 #include "net/quic/quic_utils.h" | |
18 #include "net/quic/reliable_quic_stream.h" | |
19 #include "net/quic/test_tools/mock_clock.h" | |
20 #include "net/quic/test_tools/quic_stream_sequencer_peer.h" | |
21 #include "net/quic/test_tools/quic_test_utils.h" | |
22 #include "net/test/gtest_util.h" | |
23 #include "testing/gmock/include/gmock/gmock.h" | |
24 #include "testing/gmock_mutant.h" | |
25 #include "testing/gtest/include/gtest/gtest.h" | |
26 | |
27 using base::StringPiece; | |
28 using std::map; | |
29 using std::min; | |
30 using std::pair; | |
31 using std::string; | |
32 using std::vector; | |
33 using testing::_; | |
34 using testing::AnyNumber; | |
35 using testing::CreateFunctor; | |
36 using testing::InSequence; | |
37 using testing::Return; | |
38 using testing::StrEq; | |
39 | |
40 namespace net { | |
41 namespace test { | |
42 | |
43 class MockStream : public ReliableQuicStream { | |
44 public: | |
45 MockStream(QuicSession* session, QuicStreamId id) | |
46 : ReliableQuicStream(id, session) {} | |
47 | |
48 MOCK_METHOD0(OnFinRead, void()); | |
49 MOCK_METHOD0(OnDataAvailable, void()); | |
50 MOCK_METHOD2(CloseConnectionWithDetails, | |
51 void(QuicErrorCode error, const string& details)); | |
52 MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error)); | |
53 MOCK_METHOD0(OnCanWrite, void()); | |
54 virtual bool IsFlowControlEnabled() const { return true; } | |
55 | |
56 const IPEndPoint& PeerAddressOfLatestPacket() const override { | |
57 return peer_address_; | |
58 } | |
59 | |
60 protected: | |
61 IPEndPoint peer_address_ = IPEndPoint(net::test::Any4(), 65535); | |
62 }; | |
63 | |
64 namespace { | |
65 | |
66 static const char kPayload[] = | |
67 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | |
68 | |
69 class QuicStreamSequencerTest : public ::testing::Test { | |
70 public: | |
71 void ConsumeData(size_t num_bytes) { | |
72 char buffer[1024]; | |
73 ASSERT_GT(arraysize(buffer), num_bytes); | |
74 struct iovec iov; | |
75 iov.iov_base = buffer; | |
76 iov.iov_len = num_bytes; | |
77 ASSERT_EQ(static_cast<int>(num_bytes), sequencer_->Readv(&iov, 1)); | |
78 } | |
79 | |
80 protected: | |
81 QuicStreamSequencerTest() | |
82 : connection_(new MockQuicConnection(&helper_, | |
83 &alarm_factory_, | |
84 Perspective::IS_CLIENT)), | |
85 session_(connection_), | |
86 stream_(&session_, 1), | |
87 sequencer_(new QuicStreamSequencer(&stream_, &clock_)) {} | |
88 | |
89 // Verify that the data in first region match with the expected[0]. | |
90 bool VerifyReadableRegion(const vector<string>& expected) { | |
91 iovec iovecs[1]; | |
92 if (sequencer_->GetReadableRegions(iovecs, 1)) { | |
93 return (VerifyIovecs(iovecs, 1, vector<string>{expected[0]})); | |
94 } | |
95 return false; | |
96 } | |
97 | |
98 // Verify that the data in each of currently readable regions match with each | |
99 // item given in |expected|. | |
100 bool VerifyReadableRegions(const vector<string>& expected) { | |
101 iovec iovecs[5]; | |
102 size_t num_iovecs = | |
103 sequencer_->GetReadableRegions(iovecs, arraysize(iovecs)); | |
104 return VerifyReadableRegion(expected) && | |
105 VerifyIovecs(iovecs, num_iovecs, expected); | |
106 } | |
107 | |
108 bool VerifyIovecs(iovec* iovecs, | |
109 size_t num_iovecs, | |
110 const vector<string>& expected) { | |
111 int start_position = 0; | |
112 for (size_t i = 0; i < num_iovecs; ++i) { | |
113 if (!VerifyIovec(iovecs[i], | |
114 expected[0].substr(start_position, iovecs[i].iov_len))) { | |
115 return false; | |
116 } | |
117 start_position += iovecs[i].iov_len; | |
118 } | |
119 return true; | |
120 } | |
121 | |
122 bool VerifyIovec(const iovec& iovec, StringPiece expected) { | |
123 if (iovec.iov_len != expected.length()) { | |
124 LOG(ERROR) << "Invalid length: " << iovec.iov_len << " vs " | |
125 << expected.length(); | |
126 return false; | |
127 } | |
128 if (memcmp(iovec.iov_base, expected.data(), expected.length()) != 0) { | |
129 LOG(ERROR) << "Invalid data: " << static_cast<char*>(iovec.iov_base) | |
130 << " vs " << expected; | |
131 return false; | |
132 } | |
133 return true; | |
134 } | |
135 | |
136 void OnFinFrame(QuicStreamOffset byte_offset, const char* data) { | |
137 QuicStreamFrame frame; | |
138 frame.stream_id = 1; | |
139 frame.offset = byte_offset; | |
140 frame.data_buffer = data; | |
141 frame.data_length = strlen(data); | |
142 frame.fin = true; | |
143 sequencer_->OnStreamFrame(frame); | |
144 } | |
145 | |
146 void OnFrame(QuicStreamOffset byte_offset, const char* data) { | |
147 QuicStreamFrame frame; | |
148 frame.stream_id = 1; | |
149 frame.offset = byte_offset; | |
150 frame.data_buffer = data; | |
151 frame.data_length = strlen(data); | |
152 frame.fin = false; | |
153 sequencer_->OnStreamFrame(frame); | |
154 } | |
155 | |
156 size_t NumBufferedBytes() { | |
157 return QuicStreamSequencerPeer::GetNumBufferedBytes(sequencer_.get()); | |
158 } | |
159 | |
160 MockQuicConnectionHelper helper_; | |
161 MockAlarmFactory alarm_factory_; | |
162 MockQuicConnection* connection_; | |
163 MockClock clock_; | |
164 MockQuicSpdySession session_; | |
165 testing::StrictMock<MockStream> stream_; | |
166 std::unique_ptr<QuicStreamSequencer> sequencer_; | |
167 }; | |
168 | |
169 // TODO(rch): reorder these tests so they build on each other. | |
170 | |
171 TEST_F(QuicStreamSequencerTest, RejectOldFrame) { | |
172 EXPECT_CALL(stream_, OnDataAvailable()) | |
173 .WillOnce(testing::Invoke( | |
174 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
175 base::Unretained(this), 3))); | |
176 | |
177 OnFrame(0, "abc"); | |
178 | |
179 EXPECT_EQ(0u, NumBufferedBytes()); | |
180 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
181 EXPECT_EQ(3u, stream_.flow_controller()->bytes_consumed()); | |
182 // Ignore this - it matches a past packet number and we should not see it | |
183 // again. | |
184 OnFrame(0, "def"); | |
185 EXPECT_EQ(0u, NumBufferedBytes()); | |
186 } | |
187 | |
188 TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) { | |
189 EXPECT_CALL(stream_, OnDataAvailable()); | |
190 | |
191 OnFrame(0, "abc"); | |
192 EXPECT_EQ(3u, NumBufferedBytes()); | |
193 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
194 | |
195 // Ignore this - it matches a buffered frame. | |
196 // Right now there's no checking that the payload is consistent. | |
197 OnFrame(0, "def"); | |
198 EXPECT_EQ(3u, NumBufferedBytes()); | |
199 } | |
200 | |
201 TEST_F(QuicStreamSequencerTest, FullFrameConsumed) { | |
202 EXPECT_CALL(stream_, OnDataAvailable()) | |
203 .WillOnce(testing::Invoke( | |
204 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
205 base::Unretained(this), 3))); | |
206 | |
207 OnFrame(0, "abc"); | |
208 EXPECT_EQ(0u, NumBufferedBytes()); | |
209 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
210 } | |
211 | |
212 TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) { | |
213 sequencer_->SetBlockedUntilFlush(); | |
214 | |
215 OnFrame(0, "abc"); | |
216 EXPECT_EQ(3u, NumBufferedBytes()); | |
217 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
218 | |
219 EXPECT_CALL(stream_, OnDataAvailable()) | |
220 .WillOnce(testing::Invoke( | |
221 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
222 base::Unretained(this), 3))); | |
223 sequencer_->SetUnblocked(); | |
224 EXPECT_EQ(0u, NumBufferedBytes()); | |
225 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
226 | |
227 EXPECT_CALL(stream_, OnDataAvailable()) | |
228 .WillOnce(testing::Invoke( | |
229 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
230 base::Unretained(this), 3))); | |
231 EXPECT_FALSE(sequencer_->IsClosed()); | |
232 OnFinFrame(3, "def"); | |
233 EXPECT_TRUE(sequencer_->IsClosed()); | |
234 } | |
235 | |
236 TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) { | |
237 sequencer_->SetBlockedUntilFlush(); | |
238 | |
239 OnFinFrame(0, "abc"); | |
240 EXPECT_EQ(3u, NumBufferedBytes()); | |
241 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
242 | |
243 EXPECT_CALL(stream_, OnDataAvailable()) | |
244 .WillOnce(testing::Invoke( | |
245 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
246 base::Unretained(this), 3))); | |
247 EXPECT_FALSE(sequencer_->IsClosed()); | |
248 sequencer_->SetUnblocked(); | |
249 EXPECT_TRUE(sequencer_->IsClosed()); | |
250 EXPECT_EQ(0u, NumBufferedBytes()); | |
251 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
252 } | |
253 | |
254 TEST_F(QuicStreamSequencerTest, EmptyFrame) { | |
255 EXPECT_CALL(stream_, | |
256 CloseConnectionWithDetails(QUIC_EMPTY_STREAM_FRAME_NO_FIN, _)); | |
257 OnFrame(0, ""); | |
258 EXPECT_EQ(0u, NumBufferedBytes()); | |
259 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
260 } | |
261 | |
262 TEST_F(QuicStreamSequencerTest, EmptyFinFrame) { | |
263 EXPECT_CALL(stream_, OnDataAvailable()); | |
264 OnFinFrame(0, ""); | |
265 EXPECT_EQ(0u, NumBufferedBytes()); | |
266 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
267 } | |
268 | |
269 TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) { | |
270 EXPECT_CALL(stream_, OnDataAvailable()) | |
271 .WillOnce(testing::Invoke( | |
272 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
273 base::Unretained(this), 2))); | |
274 | |
275 OnFrame(0, "abc"); | |
276 EXPECT_EQ(1u, NumBufferedBytes()); | |
277 EXPECT_EQ(2u, sequencer_->NumBytesConsumed()); | |
278 } | |
279 | |
280 TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) { | |
281 EXPECT_CALL(stream_, OnDataAvailable()); | |
282 | |
283 OnFrame(0, "abc"); | |
284 EXPECT_EQ(3u, NumBufferedBytes()); | |
285 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
286 EXPECT_EQ(0, sequencer_->num_early_frames_received()); | |
287 } | |
288 | |
289 TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) { | |
290 OnFrame(3, "abc"); | |
291 EXPECT_EQ(3u, NumBufferedBytes()); | |
292 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
293 EXPECT_EQ(1, sequencer_->num_early_frames_received()); | |
294 } | |
295 | |
296 TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) { | |
297 // Buffer the first | |
298 OnFrame(6, "ghi"); | |
299 EXPECT_EQ(3u, NumBufferedBytes()); | |
300 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
301 EXPECT_EQ(3u, sequencer_->NumBytesBuffered()); | |
302 // Buffer the second | |
303 OnFrame(3, "def"); | |
304 EXPECT_EQ(6u, NumBufferedBytes()); | |
305 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
306 EXPECT_EQ(6u, sequencer_->NumBytesBuffered()); | |
307 | |
308 EXPECT_CALL(stream_, OnDataAvailable()) | |
309 .WillOnce(testing::Invoke( | |
310 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
311 base::Unretained(this), 9))); | |
312 | |
313 // Now process all of them at once. | |
314 OnFrame(0, "abc"); | |
315 EXPECT_EQ(9u, sequencer_->NumBytesConsumed()); | |
316 EXPECT_EQ(0u, sequencer_->NumBytesBuffered()); | |
317 | |
318 EXPECT_EQ(0u, NumBufferedBytes()); | |
319 } | |
320 | |
321 TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) { | |
322 InSequence s; | |
323 | |
324 EXPECT_CALL(stream_, OnDataAvailable()) | |
325 .WillOnce(testing::Invoke( | |
326 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
327 base::Unretained(this), 3))); | |
328 OnFinFrame(0, "abc"); | |
329 | |
330 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
331 } | |
332 | |
333 TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) { | |
334 OnFinFrame(6, ""); | |
335 EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
336 | |
337 OnFrame(3, "def"); | |
338 EXPECT_CALL(stream_, OnDataAvailable()) | |
339 .WillOnce(testing::Invoke( | |
340 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
341 base::Unretained(this), 6))); | |
342 EXPECT_FALSE(sequencer_->IsClosed()); | |
343 OnFrame(0, "abc"); | |
344 EXPECT_TRUE(sequencer_->IsClosed()); | |
345 } | |
346 | |
347 TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) { | |
348 OnFinFrame(3, ""); | |
349 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
350 | |
351 EXPECT_CALL(stream_, OnDataAvailable()) | |
352 .WillOnce(testing::Invoke( | |
353 CreateFunctor(&QuicStreamSequencerTest::ConsumeData, | |
354 base::Unretained(this), 3))); | |
355 EXPECT_FALSE(sequencer_->IsClosed()); | |
356 OnFrame(0, "abc"); | |
357 EXPECT_TRUE(sequencer_->IsClosed()); | |
358 } | |
359 | |
360 TEST_F(QuicStreamSequencerTest, TerminateWithReadv) { | |
361 char buffer[3]; | |
362 | |
363 OnFinFrame(3, ""); | |
364 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
365 | |
366 EXPECT_FALSE(sequencer_->IsClosed()); | |
367 | |
368 EXPECT_CALL(stream_, OnDataAvailable()); | |
369 OnFrame(0, "abc"); | |
370 | |
371 iovec iov = {&buffer[0], 3}; | |
372 int bytes_read = sequencer_->Readv(&iov, 1); | |
373 EXPECT_EQ(3, bytes_read); | |
374 EXPECT_TRUE(sequencer_->IsClosed()); | |
375 } | |
376 | |
377 TEST_F(QuicStreamSequencerTest, MutipleOffsets) { | |
378 OnFinFrame(3, ""); | |
379 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
380 | |
381 EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS)); | |
382 OnFinFrame(5, ""); | |
383 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
384 | |
385 EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS)); | |
386 OnFinFrame(1, ""); | |
387 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
388 | |
389 OnFinFrame(3, ""); | |
390 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | |
391 } | |
392 | |
393 class QuicSequencerRandomTest : public QuicStreamSequencerTest { | |
394 public: | |
395 typedef pair<int, string> Frame; | |
396 typedef vector<Frame> FrameList; | |
397 | |
398 void CreateFrames() { | |
399 int payload_size = arraysize(kPayload) - 1; | |
400 int remaining_payload = payload_size; | |
401 while (remaining_payload != 0) { | |
402 int size = min(OneToN(6), remaining_payload); | |
403 int index = payload_size - remaining_payload; | |
404 list_.push_back(std::make_pair(index, string(kPayload + index, size))); | |
405 remaining_payload -= size; | |
406 } | |
407 } | |
408 | |
409 QuicSequencerRandomTest() { CreateFrames(); } | |
410 | |
411 int OneToN(int n) { return base::RandInt(1, n); } | |
412 | |
413 void ReadAvailableData() { | |
414 // Read all available data | |
415 char output[arraysize(kPayload) + 1]; | |
416 iovec iov; | |
417 iov.iov_base = output; | |
418 iov.iov_len = arraysize(output); | |
419 int bytes_read = sequencer_->Readv(&iov, 1); | |
420 EXPECT_NE(0, bytes_read); | |
421 output_.append(output, bytes_read); | |
422 } | |
423 | |
424 string output_; | |
425 // Data which peek at using GetReadableRegion if we back up. | |
426 string peeked_; | |
427 FrameList list_; | |
428 }; | |
429 | |
430 // All frames are processed as soon as we have sequential data. | |
431 // Infinite buffering, so all frames are acked right away. | |
432 TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) { | |
433 InSequence s; | |
434 EXPECT_CALL(stream_, OnDataAvailable()) | |
435 .Times(AnyNumber()) | |
436 .WillRepeatedly( | |
437 Invoke(this, &QuicSequencerRandomTest::ReadAvailableData)); | |
438 | |
439 while (!list_.empty()) { | |
440 int index = OneToN(list_.size()) - 1; | |
441 LOG(ERROR) << "Sending index " << index << " " << list_[index].second; | |
442 OnFrame(list_[index].first, list_[index].second.data()); | |
443 | |
444 list_.erase(list_.begin() + index); | |
445 } | |
446 | |
447 ASSERT_EQ(arraysize(kPayload) - 1, output_.size()); | |
448 EXPECT_EQ(kPayload, output_); | |
449 } | |
450 | |
451 TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingBackup) { | |
452 char buffer[10]; | |
453 iovec iov[2]; | |
454 iov[0].iov_base = &buffer[0]; | |
455 iov[0].iov_len = 5; | |
456 iov[1].iov_base = &buffer[5]; | |
457 iov[1].iov_len = 5; | |
458 | |
459 EXPECT_CALL(stream_, OnDataAvailable()).Times(AnyNumber()); | |
460 | |
461 while (output_.size() != arraysize(kPayload) - 1) { | |
462 if (!list_.empty() && (base::RandUint64() % 2 == 0)) { // Send data | |
463 int index = OneToN(list_.size()) - 1; | |
464 OnFrame(list_[index].first, list_[index].second.data()); | |
465 list_.erase(list_.begin() + index); | |
466 } else { // Read data | |
467 bool has_bytes = sequencer_->HasBytesToRead(); | |
468 iovec peek_iov[20]; | |
469 int iovs_peeked = sequencer_->GetReadableRegions(peek_iov, 20); | |
470 QuicTime timestamp = clock_.ApproximateNow(); | |
471 if (has_bytes) { | |
472 ASSERT_LT(0, iovs_peeked); | |
473 ASSERT_TRUE(sequencer_->GetReadableRegion(peek_iov, ×tamp)); | |
474 } else { | |
475 ASSERT_EQ(0, iovs_peeked); | |
476 ASSERT_FALSE(sequencer_->GetReadableRegion(peek_iov, ×tamp)); | |
477 } | |
478 int total_bytes_to_peek = arraysize(buffer); | |
479 for (int i = 0; i < iovs_peeked; ++i) { | |
480 int bytes_to_peek = min<int>(peek_iov[i].iov_len, total_bytes_to_peek); | |
481 peeked_.append(static_cast<char*>(peek_iov[i].iov_base), bytes_to_peek); | |
482 total_bytes_to_peek -= bytes_to_peek; | |
483 if (total_bytes_to_peek == 0) { | |
484 break; | |
485 } | |
486 } | |
487 int bytes_read = sequencer_->Readv(iov, 2); | |
488 output_.append(buffer, bytes_read); | |
489 ASSERT_EQ(output_.size(), peeked_.size()); | |
490 } | |
491 } | |
492 EXPECT_EQ(string(kPayload), output_); | |
493 EXPECT_EQ(string(kPayload), peeked_); | |
494 } | |
495 | |
496 // Same as above, just using a different method for reading. | |
497 TEST_F(QuicStreamSequencerTest, MarkConsumed) { | |
498 InSequence s; | |
499 EXPECT_CALL(stream_, OnDataAvailable()); | |
500 | |
501 OnFrame(0, "abc"); | |
502 OnFrame(3, "def"); | |
503 OnFrame(6, "ghi"); | |
504 | |
505 // abcdefghi buffered. | |
506 EXPECT_EQ(9u, sequencer_->NumBytesBuffered()); | |
507 | |
508 // Peek into the data. | |
509 vector<string> expected = {"abcdefghi"}; | |
510 ASSERT_TRUE(VerifyReadableRegions(expected)); | |
511 | |
512 // Consume 1 byte. | |
513 sequencer_->MarkConsumed(1); | |
514 EXPECT_EQ(1u, stream_.flow_controller()->bytes_consumed()); | |
515 // Verify data. | |
516 vector<string> expected2 = {"bcdefghi"}; | |
517 ASSERT_TRUE(VerifyReadableRegions(expected2)); | |
518 EXPECT_EQ(8u, sequencer_->NumBytesBuffered()); | |
519 | |
520 // Consume 2 bytes. | |
521 sequencer_->MarkConsumed(2); | |
522 EXPECT_EQ(3u, stream_.flow_controller()->bytes_consumed()); | |
523 // Verify data. | |
524 vector<string> expected3 = {"defghi"}; | |
525 ASSERT_TRUE(VerifyReadableRegions(expected3)); | |
526 EXPECT_EQ(6u, sequencer_->NumBytesBuffered()); | |
527 | |
528 // Consume 5 bytes. | |
529 sequencer_->MarkConsumed(5); | |
530 EXPECT_EQ(8u, stream_.flow_controller()->bytes_consumed()); | |
531 // Verify data. | |
532 vector<string> expected4{"i"}; | |
533 ASSERT_TRUE(VerifyReadableRegions(expected4)); | |
534 EXPECT_EQ(1u, sequencer_->NumBytesBuffered()); | |
535 } | |
536 | |
537 TEST_F(QuicStreamSequencerTest, MarkConsumedError) { | |
538 EXPECT_CALL(stream_, OnDataAvailable()); | |
539 | |
540 OnFrame(0, "abc"); | |
541 OnFrame(9, "jklmnopqrstuvwxyz"); | |
542 | |
543 // Peek into the data. Only the first chunk should be readable because of the | |
544 // missing data. | |
545 vector<string> expected{"abc"}; | |
546 ASSERT_TRUE(VerifyReadableRegions(expected)); | |
547 | |
548 // Now, attempt to mark consumed more data than was readable and expect the | |
549 // stream to be closed. | |
550 EXPECT_CALL(stream_, Reset(QUIC_ERROR_PROCESSING_STREAM)); | |
551 EXPECT_DFATAL(sequencer_->MarkConsumed(4), | |
552 "Invalid argument to MarkConsumed." | |
553 " expect to consume: 4, but not enough bytes available."); | |
554 } | |
555 | |
556 TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) { | |
557 InSequence s; | |
558 EXPECT_CALL(stream_, OnDataAvailable()); | |
559 | |
560 OnFrame(0, "abc"); | |
561 OnFrame(3, "def"); | |
562 // Missing packet: 6, ghi. | |
563 OnFrame(9, "jkl"); | |
564 | |
565 vector<string> expected = {"abcdef"}; | |
566 ASSERT_TRUE(VerifyReadableRegions(expected)); | |
567 | |
568 sequencer_->MarkConsumed(6); | |
569 } | |
570 | |
571 TEST_F(QuicStreamSequencerTest, DontAcceptOverlappingFrames) { | |
572 // The peer should never send us non-identical stream frames which contain | |
573 // overlapping byte ranges - if they do, we close the connection. | |
574 | |
575 QuicStreamFrame frame1(kClientDataStreamId1, false, 1, StringPiece("hello")); | |
576 sequencer_->OnStreamFrame(frame1); | |
577 | |
578 QuicStreamFrame frame2(kClientDataStreamId1, false, 2, StringPiece("hello")); | |
579 EXPECT_CALL(stream_, | |
580 CloseConnectionWithDetails(QUIC_OVERLAPPING_STREAM_DATA, _)) | |
581 .Times(1); | |
582 sequencer_->OnStreamFrame(frame2); | |
583 } | |
584 | |
585 TEST_F(QuicStreamSequencerTest, InOrderTimestamps) { | |
586 // This test verifies that timestamps returned by | |
587 // GetReadableRegion() are in the correct sequence when frames | |
588 // arrive at the sequencer in order. | |
589 EXPECT_CALL(stream_, OnDataAvailable()); | |
590 | |
591 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
592 | |
593 // Buffer the first frame. | |
594 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
595 QuicTime t1 = clock_.ApproximateNow(); | |
596 OnFrame(0, "abc"); | |
597 EXPECT_EQ(3u, NumBufferedBytes()); | |
598 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
599 EXPECT_EQ(3u, sequencer_->NumBytesBuffered()); | |
600 // Buffer the second frame. | |
601 QuicTime t2 = clock_.ApproximateNow(); | |
602 OnFrame(3, "def"); | |
603 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
604 EXPECT_EQ(6u, NumBufferedBytes()); | |
605 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
606 EXPECT_EQ(6u, sequencer_->NumBytesBuffered()); | |
607 | |
608 iovec iovecs[1]; | |
609 QuicTime timestamp(QuicTime::Zero()); | |
610 | |
611 EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, ×tamp)); | |
612 EXPECT_EQ(timestamp, t1); | |
613 QuicStreamSequencerTest::ConsumeData(3); | |
614 EXPECT_EQ(3u, NumBufferedBytes()); | |
615 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
616 EXPECT_EQ(3u, sequencer_->NumBytesBuffered()); | |
617 | |
618 EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, ×tamp)); | |
619 EXPECT_EQ(timestamp, t2); | |
620 QuicStreamSequencerTest::ConsumeData(3); | |
621 EXPECT_EQ(0u, NumBufferedBytes()); | |
622 EXPECT_EQ(6u, sequencer_->NumBytesConsumed()); | |
623 EXPECT_EQ(0u, sequencer_->NumBytesBuffered()); | |
624 } | |
625 | |
626 TEST_F(QuicStreamSequencerTest, OutOfOrderTimestamps) { | |
627 // This test verifies that timestamps returned by | |
628 // GetReadableRegion() are in the correct sequence when frames | |
629 // arrive at the sequencer out of order. | |
630 EXPECT_CALL(stream_, OnDataAvailable()); | |
631 | |
632 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
633 | |
634 // Buffer the first frame | |
635 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
636 QuicTime t1 = clock_.ApproximateNow(); | |
637 OnFrame(3, "def"); | |
638 EXPECT_EQ(3u, NumBufferedBytes()); | |
639 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
640 EXPECT_EQ(3u, sequencer_->NumBytesBuffered()); | |
641 // Buffer the second frame | |
642 QuicTime t2 = clock_.ApproximateNow(); | |
643 OnFrame(0, "abc"); | |
644 clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1)); | |
645 EXPECT_EQ(6u, NumBufferedBytes()); | |
646 EXPECT_EQ(0u, sequencer_->NumBytesConsumed()); | |
647 EXPECT_EQ(6u, sequencer_->NumBytesBuffered()); | |
648 | |
649 iovec iovecs[1]; | |
650 QuicTime timestamp(QuicTime::Zero()); | |
651 | |
652 EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, ×tamp)); | |
653 EXPECT_EQ(timestamp, t2); | |
654 QuicStreamSequencerTest::ConsumeData(3); | |
655 EXPECT_EQ(3u, NumBufferedBytes()); | |
656 EXPECT_EQ(3u, sequencer_->NumBytesConsumed()); | |
657 EXPECT_EQ(3u, sequencer_->NumBytesBuffered()); | |
658 | |
659 EXPECT_TRUE(sequencer_->GetReadableRegion(iovecs, ×tamp)); | |
660 EXPECT_EQ(timestamp, t1); | |
661 QuicStreamSequencerTest::ConsumeData(3); | |
662 EXPECT_EQ(0u, NumBufferedBytes()); | |
663 EXPECT_EQ(6u, sequencer_->NumBytesConsumed()); | |
664 EXPECT_EQ(0u, sequencer_->NumBytesBuffered()); | |
665 } | |
666 | |
667 } // namespace | |
668 } // namespace test | |
669 } // namespace net | |
OLD | NEW |