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.
5 #include "net/quic/quic_stream_sequencer.h"
10 #include "base/logging.h"
11 #include "base/rand_util.h"
12 #include "net/base/ip_endpoint.h"
13 #include "net/quic/quic_utils.h"
14 #include "net/quic/reliable_quic_stream.h"
15 #include "net/quic/test_tools/quic_stream_sequencer_peer.h"
16 #include "net/quic/test_tools/quic_test_utils.h"
17 #include "net/test/gtest_util.h"
18 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gmock_mutant.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using base::StringPiece
;
29 using testing::AnyNumber
;
30 using testing::CreateFunctor
;
31 using testing::InSequence
;
32 using testing::Return
;
38 class MockStream
: public ReliableQuicStream
{
40 MockStream(QuicSession
* session
, QuicStreamId id
)
41 : ReliableQuicStream(id
, session
) {
44 MOCK_METHOD0(OnFinRead
, void());
45 MOCK_METHOD0(OnDataAvailable
, void());
46 MOCK_METHOD2(CloseConnectionWithDetails
, void(QuicErrorCode error
,
47 const string
& details
));
48 MOCK_METHOD1(Reset
, void(QuicRstStreamErrorCode error
));
49 MOCK_METHOD0(OnCanWrite
, void());
50 QuicPriority
EffectivePriority() const override
{
51 return QuicUtils::HighestPriority();
53 virtual bool IsFlowControlEnabled() const {
60 static const char kPayload
[] =
61 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
63 class QuicStreamSequencerTest
: public ::testing::Test
{
65 void ConsumeData(size_t num_bytes
) {
67 ASSERT_GT(arraysize(buffer
), num_bytes
);
69 iov
.iov_base
= buffer
;
70 iov
.iov_len
= num_bytes
;
71 ASSERT_EQ(static_cast<int>(num_bytes
), sequencer_
->Readv(&iov
, 1));
75 QuicStreamSequencerTest()
76 : connection_(new MockConnection(Perspective::IS_CLIENT
)),
77 session_(connection_
),
78 stream_(&session_
, 1),
79 sequencer_(new QuicStreamSequencer(&stream_
)) {}
81 bool VerifyReadableRegions(const char** expected
, size_t num_expected
) {
84 sequencer_
->GetReadableRegions(iovecs
, arraysize(iovecs
));
85 return VerifyIovecs(iovecs
, num_iovecs
, expected
, num_expected
);
88 bool VerifyIovecs(iovec
* iovecs
,
90 const char** expected
,
91 size_t num_expected
) {
92 if (num_expected
!= num_iovecs
) {
93 LOG(ERROR
) << "Incorrect number of iovecs. Expected: " << num_expected
94 << " Actual: " << num_iovecs
;
97 for (size_t i
= 0; i
< num_expected
; ++i
) {
98 if (!VerifyIovec(iovecs
[i
], expected
[i
])) {
105 bool VerifyIovec(const iovec
& iovec
, StringPiece expected
) {
106 if (iovec
.iov_len
!= expected
.length()) {
107 LOG(ERROR
) << "Invalid length: " << iovec
.iov_len
108 << " vs " << expected
.length();
111 if (memcmp(iovec
.iov_base
, expected
.data(), expected
.length()) != 0) {
112 LOG(ERROR
) << "Invalid data: " << static_cast<char*>(iovec
.iov_base
)
113 << " vs " << expected
;
119 void OnFinFrame(QuicStreamOffset byte_offset
, const char* data
) {
120 QuicStreamFrame frame
;
122 frame
.offset
= byte_offset
;
123 frame
.data
= StringPiece(data
);
125 sequencer_
->OnStreamFrame(frame
);
128 void OnFrame(QuicStreamOffset byte_offset
, const char* data
) {
129 QuicStreamFrame frame
;
131 frame
.offset
= byte_offset
;
132 frame
.data
= StringPiece(data
);
134 sequencer_
->OnStreamFrame(frame
);
137 size_t NumBufferedFrames() {
138 return QuicStreamSequencerPeer::GetNumBufferedFrames(sequencer_
.get());
141 bool FrameOverlapsBufferedData(const QuicStreamFrame
& frame
) {
142 return QuicStreamSequencerPeer::FrameOverlapsBufferedData(sequencer_
.get(),
146 MockConnection
* connection_
;
147 MockQuicSpdySession session_
;
148 testing::StrictMock
<MockStream
> stream_
;
149 scoped_ptr
<QuicStreamSequencer
> sequencer_
;
152 // TODO(rch): reorder these tests so they build on each other.
154 TEST_F(QuicStreamSequencerTest
, RejectOldFrame
) {
155 EXPECT_CALL(stream_
, OnDataAvailable())
156 .WillOnce(testing::Invoke(
157 CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData
, 3)));
161 EXPECT_EQ(0u, NumBufferedFrames());
162 EXPECT_EQ(3u, sequencer_
->num_bytes_consumed());
163 EXPECT_EQ(3u, stream_
.flow_controller()->bytes_consumed());
164 // Ignore this - it matches a past packet number and we should not see it
167 EXPECT_EQ(0u, NumBufferedFrames());
170 TEST_F(QuicStreamSequencerTest
, RejectBufferedFrame
) {
171 EXPECT_CALL(stream_
, OnDataAvailable());
174 EXPECT_EQ(1u, NumBufferedFrames());
175 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
177 // Ignore this - it matches a buffered frame.
178 // Right now there's no checking that the payload is consistent.
180 EXPECT_EQ(1u, NumBufferedFrames());
183 TEST_F(QuicStreamSequencerTest
, FullFrameConsumed
) {
184 EXPECT_CALL(stream_
, OnDataAvailable())
185 .WillOnce(testing::Invoke(
186 CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData
, 3)));
189 EXPECT_EQ(0u, NumBufferedFrames());
190 EXPECT_EQ(3u, sequencer_
->num_bytes_consumed());
193 TEST_F(QuicStreamSequencerTest
, BlockedThenFullFrameConsumed
) {
194 sequencer_
->SetBlockedUntilFlush();
197 EXPECT_EQ(1u, NumBufferedFrames());
198 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
200 EXPECT_CALL(stream_
, OnDataAvailable())
201 .WillOnce(testing::Invoke(
202 CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData
, 3)));
203 sequencer_
->SetUnblocked();
204 EXPECT_EQ(0u, NumBufferedFrames());
205 EXPECT_EQ(3u, sequencer_
->num_bytes_consumed());
207 EXPECT_CALL(stream_
, OnDataAvailable())
208 .WillOnce(testing::Invoke(
209 CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData
, 3)));
210 EXPECT_FALSE(sequencer_
->IsClosed());
211 OnFinFrame(3, "def");
212 EXPECT_TRUE(sequencer_
->IsClosed());
215 TEST_F(QuicStreamSequencerTest
, BlockedThenFullFrameAndFinConsumed
) {
216 sequencer_
->SetBlockedUntilFlush();
218 OnFinFrame(0, "abc");
219 EXPECT_EQ(1u, NumBufferedFrames());
220 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
222 EXPECT_CALL(stream_
, OnDataAvailable())
223 .WillOnce(testing::Invoke(
224 CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData
, 3)));
225 EXPECT_FALSE(sequencer_
->IsClosed());
226 sequencer_
->SetUnblocked();
227 EXPECT_TRUE(sequencer_
->IsClosed());
228 EXPECT_EQ(0u, NumBufferedFrames());
229 EXPECT_EQ(3u, sequencer_
->num_bytes_consumed());
232 TEST_F(QuicStreamSequencerTest
, EmptyFrame
) {
234 CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME
, _
));
236 EXPECT_EQ(0u, NumBufferedFrames());
237 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
240 TEST_F(QuicStreamSequencerTest
, EmptyFinFrame
) {
241 EXPECT_CALL(stream_
, OnDataAvailable());
243 EXPECT_EQ(0u, NumBufferedFrames());
244 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
247 TEST_F(QuicStreamSequencerTest
, PartialFrameConsumed
) {
248 EXPECT_CALL(stream_
, OnDataAvailable())
249 .WillOnce(testing::Invoke(
250 CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData
, 2)));
253 EXPECT_EQ(1u, NumBufferedFrames());
254 EXPECT_EQ(2u, sequencer_
->num_bytes_consumed());
257 TEST_F(QuicStreamSequencerTest
, NextxFrameNotConsumed
) {
258 EXPECT_CALL(stream_
, OnDataAvailable());
261 EXPECT_EQ(1u, NumBufferedFrames());
262 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
263 EXPECT_EQ(0, sequencer_
->num_early_frames_received());
266 TEST_F(QuicStreamSequencerTest
, FutureFrameNotProcessed
) {
268 EXPECT_EQ(1u, NumBufferedFrames());
269 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
270 EXPECT_EQ(1, sequencer_
->num_early_frames_received());
273 TEST_F(QuicStreamSequencerTest
, OutOfOrderFrameProcessed
) {
276 EXPECT_EQ(1u, NumBufferedFrames());
277 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
278 EXPECT_EQ(3u, sequencer_
->num_bytes_buffered());
281 EXPECT_EQ(2u, NumBufferedFrames());
282 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
283 EXPECT_EQ(6u, sequencer_
->num_bytes_buffered());
285 EXPECT_CALL(stream_
, OnDataAvailable())
286 .WillOnce(testing::Invoke(
287 CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData
, 9)));
289 // Now process all of them at once.
291 EXPECT_EQ(9u, sequencer_
->num_bytes_consumed());
292 EXPECT_EQ(0u, sequencer_
->num_bytes_buffered());
294 EXPECT_EQ(0u, NumBufferedFrames());
297 TEST_F(QuicStreamSequencerTest
, BasicHalfCloseOrdered
) {
300 EXPECT_CALL(stream_
, OnDataAvailable())
301 .WillOnce(testing::Invoke(
302 CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData
, 3)));
303 OnFinFrame(0, "abc");
305 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
308 TEST_F(QuicStreamSequencerTest
, BasicHalfCloseUnorderedWithFlush
) {
310 EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
313 EXPECT_CALL(stream_
, OnDataAvailable())
314 .WillOnce(testing::Invoke(
315 CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData
, 6)));
316 EXPECT_FALSE(sequencer_
->IsClosed());
318 EXPECT_TRUE(sequencer_
->IsClosed());
321 TEST_F(QuicStreamSequencerTest
, BasicHalfUnordered
) {
323 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
325 EXPECT_CALL(stream_
, OnDataAvailable())
326 .WillOnce(testing::Invoke(
327 CreateFunctor(this, &QuicStreamSequencerTest::ConsumeData
, 3)));
328 EXPECT_FALSE(sequencer_
->IsClosed());
330 EXPECT_TRUE(sequencer_
->IsClosed());
333 TEST_F(QuicStreamSequencerTest
, TerminateWithReadv
) {
337 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
339 EXPECT_FALSE(sequencer_
->IsClosed());
341 EXPECT_CALL(stream_
, OnDataAvailable());
344 iovec iov
= {&buffer
[0], 3};
345 int bytes_read
= sequencer_
->Readv(&iov
, 1);
346 EXPECT_EQ(3, bytes_read
);
347 EXPECT_TRUE(sequencer_
->IsClosed());
350 TEST_F(QuicStreamSequencerTest
, MutipleOffsets
) {
352 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
354 EXPECT_CALL(stream_
, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS
));
356 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
358 EXPECT_CALL(stream_
, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS
));
360 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
363 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
366 class QuicSequencerRandomTest
: public QuicStreamSequencerTest
{
368 typedef pair
<int, string
> Frame
;
369 typedef vector
<Frame
> FrameList
;
371 void CreateFrames() {
372 int payload_size
= arraysize(kPayload
) - 1;
373 int remaining_payload
= payload_size
;
374 while (remaining_payload
!= 0) {
375 int size
= min(OneToN(6), remaining_payload
);
376 int index
= payload_size
- remaining_payload
;
377 list_
.push_back(std::make_pair(index
, string(kPayload
+ index
, size
)));
378 remaining_payload
-= size
;
382 QuicSequencerRandomTest() {
387 return base::RandInt(1, n
);
390 void ReadAvailableData() {
391 // Read all available data
392 char output
[arraysize(kPayload
) + 1];
394 iov
.iov_base
= output
;
395 iov
.iov_len
= arraysize(output
);
396 int bytes_read
= sequencer_
->Readv(&iov
, 1);
397 EXPECT_NE(0, bytes_read
);
398 output_
.append(output
, bytes_read
);
402 // Data which peek at using GetReadableRegion if we back up.
407 // All frames are processed as soon as we have sequential data.
408 // Infinite buffering, so all frames are acked right away.
409 TEST_F(QuicSequencerRandomTest
, RandomFramesNoDroppingNoBackup
) {
411 EXPECT_CALL(stream_
, OnDataAvailable())
414 Invoke(this, &QuicSequencerRandomTest::ReadAvailableData
));
416 while (!list_
.empty()) {
417 int index
= OneToN(list_
.size()) - 1;
418 LOG(ERROR
) << "Sending index " << index
<< " " << list_
[index
].second
;
419 OnFrame(list_
[index
].first
, list_
[index
].second
.data());
421 list_
.erase(list_
.begin() + index
);
424 ASSERT_EQ(arraysize(kPayload
) - 1, output_
.size());
425 EXPECT_EQ(kPayload
, output_
);
428 TEST_F(QuicSequencerRandomTest
, RandomFramesNoDroppingBackup
) {
431 iov
[0].iov_base
= &buffer
[0];
433 iov
[1].iov_base
= &buffer
[5];
436 EXPECT_CALL(stream_
, OnDataAvailable()).Times(AnyNumber());
438 while (output_
.size() != arraysize(kPayload
) - 1) {
439 if (!list_
.empty() && (base::RandUint64() % 2 == 0)) { // Send data
440 int index
= OneToN(list_
.size()) - 1;
441 OnFrame(list_
[index
].first
, list_
[index
].second
.data());
442 list_
.erase(list_
.begin() + index
);
443 } else { // Read data
444 bool has_bytes
= sequencer_
->HasBytesToRead();
446 int iovs_peeked
= sequencer_
->GetReadableRegions(peek_iov
, 20);
448 ASSERT_LT(0, iovs_peeked
);
450 ASSERT_EQ(0, iovs_peeked
);
452 int total_bytes_to_peek
= arraysize(buffer
);
453 for (int i
= 0; i
< iovs_peeked
; ++i
) {
454 int bytes_to_peek
= min
<int>(peek_iov
[i
].iov_len
, total_bytes_to_peek
);
455 peeked_
.append(static_cast<char*>(peek_iov
[i
].iov_base
), bytes_to_peek
);
456 total_bytes_to_peek
-= bytes_to_peek
;
457 if (total_bytes_to_peek
== 0) {
461 int bytes_read
= sequencer_
->Readv(iov
, 2);
462 output_
.append(buffer
, bytes_read
);
463 ASSERT_EQ(output_
.size(), peeked_
.size());
466 EXPECT_EQ(string(kPayload
), output_
);
467 EXPECT_EQ(string(kPayload
), peeked_
);
470 // Same as above, just using a different method for reading.
471 TEST_F(QuicStreamSequencerTest
, MarkConsumed
) {
473 EXPECT_CALL(stream_
, OnDataAvailable());
479 // abcdefghi buffered.
480 EXPECT_EQ(9u, sequencer_
->num_bytes_buffered());
482 // Peek into the data.
483 const char* expected
[] = {"abc", "def", "ghi"};
484 ASSERT_TRUE(VerifyReadableRegions(expected
, arraysize(expected
)));
487 sequencer_
->MarkConsumed(1);
488 EXPECT_EQ(1u, stream_
.flow_controller()->bytes_consumed());
490 const char* expected2
[] = {"bc", "def", "ghi"};
491 ASSERT_TRUE(VerifyReadableRegions(expected2
, arraysize(expected2
)));
492 EXPECT_EQ(8u, sequencer_
->num_bytes_buffered());
495 sequencer_
->MarkConsumed(2);
496 EXPECT_EQ(3u, stream_
.flow_controller()->bytes_consumed());
498 const char* expected3
[] = {"def", "ghi"};
499 ASSERT_TRUE(VerifyReadableRegions(expected3
, arraysize(expected3
)));
500 EXPECT_EQ(6u, sequencer_
->num_bytes_buffered());
503 sequencer_
->MarkConsumed(5);
504 EXPECT_EQ(8u, stream_
.flow_controller()->bytes_consumed());
506 const char* expected4
[] = {"i"};
507 ASSERT_TRUE(VerifyReadableRegions(expected4
, arraysize(expected4
)));
508 EXPECT_EQ(1u, sequencer_
->num_bytes_buffered());
511 TEST_F(QuicStreamSequencerTest
, MarkConsumedError
) {
512 EXPECT_CALL(stream_
, OnDataAvailable());
515 OnFrame(9, "jklmnopqrstuvwxyz");
517 // Peek into the data. Only the first chunk should be readable because of the
519 const char* expected
[] = {"abc"};
520 ASSERT_TRUE(VerifyReadableRegions(expected
, arraysize(expected
)));
522 // Now, attempt to mark consumed more data than was readable and expect the
523 // stream to be closed.
524 EXPECT_CALL(stream_
, Reset(QUIC_ERROR_PROCESSING_STREAM
));
525 EXPECT_DFATAL(sequencer_
->MarkConsumed(4),
526 "Invalid argument to MarkConsumed. num_bytes_consumed_: 3 "
527 "end_offset: 4 offset: 9 length: 17");
530 TEST_F(QuicStreamSequencerTest
, MarkConsumedWithMissingPacket
) {
532 EXPECT_CALL(stream_
, OnDataAvailable());
536 // Missing packet: 6, ghi.
539 const char* expected
[] = {"abc", "def"};
540 ASSERT_TRUE(VerifyReadableRegions(expected
, arraysize(expected
)));
542 sequencer_
->MarkConsumed(6);
545 TEST_F(QuicStreamSequencerTest
, FrameOverlapsBufferedData
) {
546 // Ensure that FrameOverlapsBufferedData returns appropriate responses when
547 // there is existing data buffered.
548 const int kBufferedOffset
= 10;
549 const int kBufferedDataLength
= 3;
550 const int kNewDataLength
= 3;
551 string
data(kNewDataLength
, '.');
553 // No overlap if no buffered frames.
554 EXPECT_EQ(0u, NumBufferedFrames());
555 // Add a buffered frame.
556 sequencer_
->OnStreamFrame(QuicStreamFrame(1, false, kBufferedOffset
,
557 string(kBufferedDataLength
, '.')));
559 // New byte range partially overlaps with buffered frame, start offset
560 // preceding buffered frame.
561 EXPECT_TRUE(FrameOverlapsBufferedData(
562 QuicStreamFrame(1, false, kBufferedOffset
- 1, data
)));
563 EXPECT_TRUE(FrameOverlapsBufferedData(
564 QuicStreamFrame(1, false, kBufferedOffset
- kNewDataLength
+ 1, data
)));
566 // New byte range partially overlaps with buffered frame, start offset inside
567 // existing buffered frame.
568 EXPECT_TRUE(FrameOverlapsBufferedData(
569 QuicStreamFrame(1, false, kBufferedOffset
+ 1, data
)));
570 EXPECT_TRUE(FrameOverlapsBufferedData(QuicStreamFrame(
571 1, false, kBufferedOffset
+ kBufferedDataLength
- 1, data
)));
573 // New byte range entirely outside of buffered frames, start offset preceeding
575 EXPECT_FALSE(FrameOverlapsBufferedData(
576 QuicStreamFrame(1, false, kBufferedOffset
- kNewDataLength
, data
)));
578 // New byte range entirely outside of buffered frames, start offset later than
580 EXPECT_FALSE(FrameOverlapsBufferedData(
581 QuicStreamFrame(1, false, kBufferedOffset
+ kBufferedDataLength
, data
)));
584 TEST_F(QuicStreamSequencerTest
, DontAcceptOverlappingFrames
) {
585 // The peer should never send us non-identical stream frames which contain
586 // overlapping byte ranges - if they do, we close the connection.
588 QuicStreamFrame
frame1(kClientDataStreamId1
, false, 1, StringPiece("hello"));
589 sequencer_
->OnStreamFrame(frame1
);
591 QuicStreamFrame
frame2(kClientDataStreamId1
, false, 2, StringPiece("hello"));
592 EXPECT_TRUE(FrameOverlapsBufferedData(frame2
));
593 EXPECT_CALL(stream_
, CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME
, _
))
595 sequencer_
->OnStreamFrame(frame2
);