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/gtest/include/gtest/gtest.h"
21 using base::StringPiece
;
28 using testing::AnyNumber
;
29 using testing::InSequence
;
30 using testing::Return
;
36 class MockStream
: public ReliableQuicStream
{
38 MockStream(QuicSession
* session
, QuicStreamId id
)
39 : ReliableQuicStream(id
, session
) {
42 MOCK_METHOD0(OnFinRead
, void());
43 MOCK_METHOD2(ProcessRawData
, uint32(const char* data
, uint32 data_len
));
44 MOCK_METHOD2(CloseConnectionWithDetails
, void(QuicErrorCode error
,
45 const string
& details
));
46 MOCK_METHOD1(Reset
, void(QuicRstStreamErrorCode error
));
47 MOCK_METHOD0(OnCanWrite
, void());
48 QuicPriority
EffectivePriority() const override
{
49 return QuicUtils::HighestPriority();
51 virtual bool IsFlowControlEnabled() const {
58 static const char kPayload
[] =
59 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
61 class QuicStreamSequencerTest
: public ::testing::Test
{
63 QuicStreamSequencerTest()
64 : connection_(new MockConnection(Perspective::IS_CLIENT
)),
65 session_(connection_
),
66 stream_(&session_
, 1),
67 sequencer_(new QuicStreamSequencer(&stream_
)) {}
69 bool VerifyReadableRegions(const char** expected
, size_t num_expected
) {
72 sequencer_
->GetReadableRegions(iovecs
, arraysize(iovecs
));
73 return VerifyIovecs(iovecs
, num_iovecs
, expected
, num_expected
);
76 bool VerifyIovecs(iovec
* iovecs
,
78 const char** expected
,
79 size_t num_expected
) {
80 if (num_expected
!= num_iovecs
) {
81 LOG(ERROR
) << "Incorrect number of iovecs. Expected: " << num_expected
82 << " Actual: " << num_iovecs
;
85 for (size_t i
= 0; i
< num_expected
; ++i
) {
86 if (!VerifyIovec(iovecs
[i
], expected
[i
])) {
93 bool VerifyIovec(const iovec
& iovec
, StringPiece expected
) {
94 if (iovec
.iov_len
!= expected
.length()) {
95 LOG(ERROR
) << "Invalid length: " << iovec
.iov_len
96 << " vs " << expected
.length();
99 if (memcmp(iovec
.iov_base
, expected
.data(), expected
.length()) != 0) {
100 LOG(ERROR
) << "Invalid data: " << static_cast<char*>(iovec
.iov_base
)
101 << " vs " << expected
;
107 void OnFinFrame(QuicStreamOffset byte_offset
, const char* data
) {
108 QuicStreamFrame frame
;
110 frame
.offset
= byte_offset
;
111 frame
.data
= StringPiece(data
);
113 sequencer_
->OnStreamFrame(frame
);
116 void OnFrame(QuicStreamOffset byte_offset
, const char* data
) {
117 QuicStreamFrame frame
;
119 frame
.offset
= byte_offset
;
120 frame
.data
= StringPiece(data
);
122 sequencer_
->OnStreamFrame(frame
);
125 size_t NumBufferedFrames() {
126 return QuicStreamSequencerPeer::GetNumBufferedFrames(sequencer_
.get());
129 bool FrameOverlapsBufferedData(const QuicStreamFrame
& frame
) {
130 return QuicStreamSequencerPeer::FrameOverlapsBufferedData(sequencer_
.get(),
134 MockConnection
* connection_
;
135 MockQuicSpdySession session_
;
136 testing::StrictMock
<MockStream
> stream_
;
137 scoped_ptr
<QuicStreamSequencer
> sequencer_
;
140 TEST_F(QuicStreamSequencerTest
, RejectOldFrame
) {
141 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
144 EXPECT_EQ(0u, NumBufferedFrames());
145 EXPECT_EQ(3u, sequencer_
->num_bytes_consumed());
146 EXPECT_EQ(3u, stream_
.flow_controller()->bytes_consumed());
147 // Ignore this - it matches a past sequence number and we should not see it
150 EXPECT_EQ(0u, NumBufferedFrames());
153 TEST_F(QuicStreamSequencerTest
, RejectBufferedFrame
) {
154 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3));
157 EXPECT_EQ(1u, NumBufferedFrames());
158 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
159 // Ignore this - it matches a buffered frame.
160 // Right now there's no checking that the payload is consistent.
162 EXPECT_EQ(1u, NumBufferedFrames());
165 TEST_F(QuicStreamSequencerTest
, FullFrameConsumed
) {
166 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
169 EXPECT_EQ(0u, NumBufferedFrames());
170 EXPECT_EQ(3u, sequencer_
->num_bytes_consumed());
173 TEST_F(QuicStreamSequencerTest
, BlockedThenFullFrameConsumed
) {
174 sequencer_
->SetBlockedUntilFlush();
177 EXPECT_EQ(1u, NumBufferedFrames());
178 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
180 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
181 sequencer_
->FlushBufferedFrames();
182 EXPECT_EQ(0u, NumBufferedFrames());
183 EXPECT_EQ(3u, sequencer_
->num_bytes_consumed());
185 EXPECT_CALL(stream_
, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(3));
186 EXPECT_CALL(stream_
, OnFinRead());
187 OnFinFrame(3, "def");
190 TEST_F(QuicStreamSequencerTest
, BlockedThenFullFrameAndFinConsumed
) {
191 sequencer_
->SetBlockedUntilFlush();
193 OnFinFrame(0, "abc");
194 EXPECT_EQ(1u, NumBufferedFrames());
195 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
197 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
198 EXPECT_CALL(stream_
, OnFinRead());
199 sequencer_
->FlushBufferedFrames();
200 EXPECT_EQ(0u, NumBufferedFrames());
201 EXPECT_EQ(3u, sequencer_
->num_bytes_consumed());
204 TEST_F(QuicStreamSequencerTest
, EmptyFrame
) {
206 CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME
, _
));
208 EXPECT_EQ(0u, NumBufferedFrames());
209 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
212 TEST_F(QuicStreamSequencerTest
, EmptyFinFrame
) {
213 EXPECT_CALL(stream_
, OnFinRead());
215 EXPECT_EQ(0u, NumBufferedFrames());
216 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
219 TEST_F(QuicStreamSequencerTest
, PartialFrameConsumed
) {
220 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(2));
223 EXPECT_EQ(1u, NumBufferedFrames());
224 EXPECT_EQ(2u, sequencer_
->num_bytes_consumed());
227 TEST_F(QuicStreamSequencerTest
, NextxFrameNotConsumed
) {
228 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
231 EXPECT_EQ(1u, NumBufferedFrames());
232 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
233 EXPECT_EQ(0, sequencer_
->num_early_frames_received());
236 TEST_F(QuicStreamSequencerTest
, FutureFrameNotProcessed
) {
238 EXPECT_EQ(1u, NumBufferedFrames());
239 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
240 EXPECT_EQ(1, sequencer_
->num_early_frames_received());
243 TEST_F(QuicStreamSequencerTest
, OutOfOrderFrameProcessed
) {
246 EXPECT_EQ(1u, NumBufferedFrames());
247 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
248 EXPECT_EQ(3u, sequencer_
->num_bytes_buffered());
251 EXPECT_EQ(2u, NumBufferedFrames());
252 EXPECT_EQ(0u, sequencer_
->num_bytes_consumed());
253 EXPECT_EQ(6u, sequencer_
->num_bytes_buffered());
256 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
257 EXPECT_CALL(stream_
, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(3));
258 EXPECT_CALL(stream_
, ProcessRawData(StrEq("ghi"), 3)).WillOnce(Return(3));
262 EXPECT_EQ(9u, sequencer_
->num_bytes_consumed());
263 EXPECT_EQ(0u, sequencer_
->num_bytes_buffered());
265 EXPECT_EQ(0u, NumBufferedFrames());
268 TEST_F(QuicStreamSequencerTest
, BasicHalfCloseOrdered
) {
271 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
272 EXPECT_CALL(stream_
, OnFinRead());
273 OnFinFrame(0, "abc");
275 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
278 TEST_F(QuicStreamSequencerTest
, BasicHalfCloseUnorderedWithFlush
) {
280 EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
282 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
283 EXPECT_CALL(stream_
, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(3));
284 EXPECT_CALL(stream_
, OnFinRead());
290 TEST_F(QuicStreamSequencerTest
, BasicHalfUnordered
) {
292 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
294 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
295 EXPECT_CALL(stream_
, OnFinRead());
300 TEST_F(QuicStreamSequencerTest
, TerminateWithReadv
) {
304 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
306 EXPECT_FALSE(sequencer_
->IsClosed());
308 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
311 iovec iov
= {&buffer
[0], 3};
312 int bytes_read
= sequencer_
->Readv(&iov
, 1);
313 EXPECT_EQ(3, bytes_read
);
314 EXPECT_TRUE(sequencer_
->IsClosed());
317 TEST_F(QuicStreamSequencerTest
, MutipleOffsets
) {
319 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
321 EXPECT_CALL(stream_
, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS
));
323 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
325 EXPECT_CALL(stream_
, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS
));
327 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
330 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_
.get()));
333 class QuicSequencerRandomTest
: public QuicStreamSequencerTest
{
335 typedef pair
<int, string
> Frame
;
336 typedef vector
<Frame
> FrameList
;
338 void CreateFrames() {
339 int payload_size
= arraysize(kPayload
) - 1;
340 int remaining_payload
= payload_size
;
341 while (remaining_payload
!= 0) {
342 int size
= min(OneToN(6), remaining_payload
);
343 int index
= payload_size
- remaining_payload
;
344 list_
.push_back(std::make_pair(index
, string(kPayload
+ index
, size
)));
345 remaining_payload
-= size
;
349 QuicSequencerRandomTest() {
354 return base::RandInt(1, n
);
357 int MaybeProcessMaybeBuffer(const char* data
, uint32 len
) {
358 int to_process
= len
;
359 if (base::RandUint64() % 2 != 0) {
360 to_process
= base::RandInt(0, len
);
362 output_
.append(data
, to_process
);
363 peeked_
.append(data
, to_process
);
368 // Data which peek at using GetReadableRegion if we back up.
373 // All frames are processed as soon as we have sequential data.
374 // Infinite buffering, so all frames are acked right away.
375 TEST_F(QuicSequencerRandomTest
, RandomFramesNoDroppingNoBackup
) {
377 for (size_t i
= 0; i
< list_
.size(); ++i
) {
378 string
* data
= &list_
[i
].second
;
379 EXPECT_CALL(stream_
, ProcessRawData(StrEq(*data
), data
->size()))
380 .WillOnce(Return(data
->size()));
383 while (!list_
.empty()) {
384 int index
= OneToN(list_
.size()) - 1;
385 LOG(ERROR
) << "Sending index " << index
<< " " << list_
[index
].second
;
386 OnFrame(list_
[index
].first
, list_
[index
].second
.data());
388 list_
.erase(list_
.begin() + index
);
392 TEST_F(QuicSequencerRandomTest
, RandomFramesNoDroppingBackup
) {
395 iov
[0].iov_base
= &buffer
[0];
397 iov
[1].iov_base
= &buffer
[5];
400 EXPECT_CALL(stream_
, ProcessRawData(_
, _
))
403 Invoke(this, &QuicSequencerRandomTest::MaybeProcessMaybeBuffer
));
405 while (output_
.size() != arraysize(kPayload
) - 1) {
406 if (!list_
.empty() && (base::RandUint64() % 2 == 0)) { // Send data
407 int index
= OneToN(list_
.size()) - 1;
408 OnFrame(list_
[index
].first
, list_
[index
].second
.data());
409 list_
.erase(list_
.begin() + index
);
410 } else { // Read data
411 bool has_bytes
= sequencer_
->HasBytesToRead();
413 int iovs_peeked
= sequencer_
->GetReadableRegions(peek_iov
, 20);
415 ASSERT_LT(0, iovs_peeked
);
417 ASSERT_EQ(0, iovs_peeked
);
419 int total_bytes_to_peek
= arraysize(buffer
);
420 for (int i
= 0; i
< iovs_peeked
; ++i
) {
421 int bytes_to_peek
= min
<int>(peek_iov
[i
].iov_len
, total_bytes_to_peek
);
422 peeked_
.append(static_cast<char*>(peek_iov
[i
].iov_base
), bytes_to_peek
);
423 total_bytes_to_peek
-= bytes_to_peek
;
424 if (total_bytes_to_peek
== 0) {
428 int bytes_read
= sequencer_
->Readv(iov
, 2);
429 output_
.append(buffer
, bytes_read
);
430 ASSERT_EQ(output_
.size(), peeked_
.size());
433 EXPECT_EQ(0, strcmp(kPayload
, output_
.data()));
434 EXPECT_EQ(0, strcmp(kPayload
, peeked_
.data()));
437 // Same as above, just using a different method for reading.
438 TEST_F(QuicStreamSequencerTest
, MarkConsumed
) {
440 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
446 // abcdefghi buffered.
447 EXPECT_EQ(9u, sequencer_
->num_bytes_buffered());
449 // Peek into the data.
450 const char* expected
[] = {"abc", "def", "ghi"};
451 ASSERT_TRUE(VerifyReadableRegions(expected
, arraysize(expected
)));
454 sequencer_
->MarkConsumed(1);
455 EXPECT_EQ(1u, stream_
.flow_controller()->bytes_consumed());
457 const char* expected2
[] = {"bc", "def", "ghi"};
458 ASSERT_TRUE(VerifyReadableRegions(expected2
, arraysize(expected2
)));
459 EXPECT_EQ(8u, sequencer_
->num_bytes_buffered());
462 sequencer_
->MarkConsumed(2);
463 EXPECT_EQ(3u, stream_
.flow_controller()->bytes_consumed());
465 const char* expected3
[] = {"def", "ghi"};
466 ASSERT_TRUE(VerifyReadableRegions(expected3
, arraysize(expected3
)));
467 EXPECT_EQ(6u, sequencer_
->num_bytes_buffered());
470 sequencer_
->MarkConsumed(5);
471 EXPECT_EQ(8u, stream_
.flow_controller()->bytes_consumed());
473 const char* expected4
[] = {"i"};
474 ASSERT_TRUE(VerifyReadableRegions(expected4
, arraysize(expected4
)));
475 EXPECT_EQ(1u, sequencer_
->num_bytes_buffered());
478 TEST_F(QuicStreamSequencerTest
, MarkConsumedError
) {
479 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
482 OnFrame(9, "jklmnopqrstuvwxyz");
484 // Peek into the data. Only the first chunk should be readable because of the
486 const char* expected
[] = {"abc"};
487 ASSERT_TRUE(VerifyReadableRegions(expected
, arraysize(expected
)));
489 // Now, attempt to mark consumed more data than was readable and expect the
490 // stream to be closed.
491 EXPECT_CALL(stream_
, Reset(QUIC_ERROR_PROCESSING_STREAM
));
492 EXPECT_DFATAL(sequencer_
->MarkConsumed(4),
493 "Invalid argument to MarkConsumed. num_bytes_consumed_: 3 "
494 "end_offset: 4 offset: 9 length: 17");
497 TEST_F(QuicStreamSequencerTest
, MarkConsumedWithMissingPacket
) {
499 EXPECT_CALL(stream_
, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
503 // Missing packet: 6, ghi.
506 const char* expected
[] = {"abc", "def"};
507 ASSERT_TRUE(VerifyReadableRegions(expected
, arraysize(expected
)));
509 sequencer_
->MarkConsumed(6);
512 TEST_F(QuicStreamSequencerTest
, FrameOverlapsBufferedData
) {
513 // Ensure that FrameOverlapsBufferedData returns appropriate responses when
514 // there is existing data buffered.
515 const int kBufferedOffset
= 10;
516 const int kBufferedDataLength
= 3;
517 const int kNewDataLength
= 3;
518 string
data(kNewDataLength
, '.');
520 // No overlap if no buffered frames.
521 EXPECT_EQ(0u, NumBufferedFrames());
522 // Add a buffered frame.
523 sequencer_
->OnStreamFrame(QuicStreamFrame(1, false, kBufferedOffset
,
524 string(kBufferedDataLength
, '.')));
526 // New byte range partially overlaps with buffered frame, start offset
527 // preceding buffered frame.
528 EXPECT_TRUE(FrameOverlapsBufferedData(
529 QuicStreamFrame(1, false, kBufferedOffset
- 1, data
)));
530 EXPECT_TRUE(FrameOverlapsBufferedData(
531 QuicStreamFrame(1, false, kBufferedOffset
- kNewDataLength
+ 1, data
)));
533 // New byte range partially overlaps with buffered frame, start offset inside
534 // existing buffered frame.
535 EXPECT_TRUE(FrameOverlapsBufferedData(
536 QuicStreamFrame(1, false, kBufferedOffset
+ 1, data
)));
537 EXPECT_TRUE(FrameOverlapsBufferedData(QuicStreamFrame(
538 1, false, kBufferedOffset
+ kBufferedDataLength
- 1, data
)));
540 // New byte range entirely outside of buffered frames, start offset preceeding
542 EXPECT_FALSE(FrameOverlapsBufferedData(
543 QuicStreamFrame(1, false, kBufferedOffset
- kNewDataLength
, data
)));
545 // New byte range entirely outside of buffered frames, start offset later than
547 EXPECT_FALSE(FrameOverlapsBufferedData(
548 QuicStreamFrame(1, false, kBufferedOffset
+ kBufferedDataLength
, data
)));
551 TEST_F(QuicStreamSequencerTest
, DontAcceptOverlappingFrames
) {
552 // The peer should never send us non-identical stream frames which contain
553 // overlapping byte ranges - if they do, we close the connection.
555 QuicStreamFrame
frame1(kClientDataStreamId1
, false, 1, StringPiece("hello"));
556 sequencer_
->OnStreamFrame(frame1
);
558 QuicStreamFrame
frame2(kClientDataStreamId1
, false, 2, StringPiece("hello"));
559 EXPECT_TRUE(FrameOverlapsBufferedData(frame2
));
560 EXPECT_CALL(stream_
, CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME
, _
))
562 sequencer_
->OnStreamFrame(frame2
);