Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / quic / quic_stream_sequencer_test.cc
blob86d6cf49f0e766a40bddfff5a1c7f804af04661f
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"
7 #include <utility>
8 #include <vector>
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;
22 using std::map;
23 using std::min;
24 using std::pair;
25 using std::string;
26 using std::vector;
27 using testing::_;
28 using testing::AnyNumber;
29 using testing::InSequence;
30 using testing::Return;
31 using testing::StrEq;
33 namespace net {
34 namespace test {
36 class MockStream : public ReliableQuicStream {
37 public:
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 {
52 return true;
56 namespace {
58 static const char kPayload[] =
59 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
61 class QuicStreamSequencerTest : public ::testing::Test {
62 protected:
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) {
70 iovec iovecs[5];
71 size_t num_iovecs =
72 sequencer_->GetReadableRegions(iovecs, arraysize(iovecs));
73 return VerifyIovecs(iovecs, num_iovecs, expected, num_expected);
76 bool VerifyIovecs(iovec* iovecs,
77 size_t num_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;
83 return false;
85 for (size_t i = 0; i < num_expected; ++i) {
86 if (!VerifyIovec(iovecs[i], expected[i])) {
87 return false;
90 return true;
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();
97 return false;
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;
102 return false;
104 return true;
107 void OnFinFrame(QuicStreamOffset byte_offset, const char* data) {
108 QuicStreamFrame frame;
109 frame.stream_id = 1;
110 frame.offset = byte_offset;
111 frame.data = StringPiece(data);
112 frame.fin = true;
113 sequencer_->OnStreamFrame(frame);
116 void OnFrame(QuicStreamOffset byte_offset, const char* data) {
117 QuicStreamFrame frame;
118 frame.stream_id = 1;
119 frame.offset = byte_offset;
120 frame.data = StringPiece(data);
121 frame.fin = false;
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(),
131 frame);
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));
143 OnFrame(0, "abc");
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
148 // again.
149 OnFrame(0, "def");
150 EXPECT_EQ(0u, NumBufferedFrames());
153 TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) {
154 EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3));
156 OnFrame(0, "abc");
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.
161 OnFrame(0, "def");
162 EXPECT_EQ(1u, NumBufferedFrames());
165 TEST_F(QuicStreamSequencerTest, FullFrameConsumed) {
166 EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
168 OnFrame(0, "abc");
169 EXPECT_EQ(0u, NumBufferedFrames());
170 EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
173 TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) {
174 sequencer_->SetBlockedUntilFlush();
176 OnFrame(0, "abc");
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) {
205 EXPECT_CALL(stream_,
206 CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME, _));
207 OnFrame(0, "");
208 EXPECT_EQ(0u, NumBufferedFrames());
209 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
212 TEST_F(QuicStreamSequencerTest, EmptyFinFrame) {
213 EXPECT_CALL(stream_, OnFinRead());
214 OnFinFrame(0, "");
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));
222 OnFrame(0, "abc");
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));
230 OnFrame(0, "abc");
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) {
237 OnFrame(3, "abc");
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) {
244 // Buffer the first
245 OnFrame(6, "ghi");
246 EXPECT_EQ(1u, NumBufferedFrames());
247 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
248 EXPECT_EQ(3u, sequencer_->num_bytes_buffered());
249 // Buffer the second
250 OnFrame(3, "def");
251 EXPECT_EQ(2u, NumBufferedFrames());
252 EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
253 EXPECT_EQ(6u, sequencer_->num_bytes_buffered());
255 InSequence s;
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));
260 // Ack right away
261 OnFrame(0, "abc");
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) {
269 InSequence s;
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) {
279 OnFinFrame(6, "");
280 EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
281 InSequence s;
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());
286 OnFrame(3, "def");
287 OnFrame(0, "abc");
290 TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
291 OnFinFrame(3, "");
292 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
293 InSequence s;
294 EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
295 EXPECT_CALL(stream_, OnFinRead());
297 OnFrame(0, "abc");
300 TEST_F(QuicStreamSequencerTest, TerminateWithReadv) {
301 char buffer[3];
303 OnFinFrame(3, "");
304 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
306 EXPECT_FALSE(sequencer_->IsClosed());
308 EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
309 OnFrame(0, "abc");
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) {
318 OnFinFrame(3, "");
319 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
321 EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS));
322 OnFinFrame(5, "");
323 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
325 EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS));
326 OnFinFrame(1, "");
327 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
329 OnFinFrame(3, "");
330 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
333 class QuicSequencerRandomTest : public QuicStreamSequencerTest {
334 public:
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() {
350 CreateFrames();
353 int OneToN(int n) {
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);
364 return to_process;
367 string output_;
368 // Data which peek at using GetReadableRegion if we back up.
369 string peeked_;
370 FrameList list_;
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) {
376 InSequence s;
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) {
393 char buffer[10];
394 iovec iov[2];
395 iov[0].iov_base = &buffer[0];
396 iov[0].iov_len = 5;
397 iov[1].iov_base = &buffer[5];
398 iov[1].iov_len = 5;
400 EXPECT_CALL(stream_, ProcessRawData(_, _))
401 .Times(AnyNumber())
402 .WillRepeatedly(
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();
412 iovec peek_iov[20];
413 int iovs_peeked = sequencer_->GetReadableRegions(peek_iov, 20);
414 if (has_bytes) {
415 ASSERT_LT(0, iovs_peeked);
416 } else {
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) {
425 break;
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) {
439 InSequence s;
440 EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
442 OnFrame(0, "abc");
443 OnFrame(3, "def");
444 OnFrame(6, "ghi");
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)));
453 // Consume 1 byte.
454 sequencer_->MarkConsumed(1);
455 EXPECT_EQ(1u, stream_.flow_controller()->bytes_consumed());
456 // Verify data.
457 const char* expected2[] = {"bc", "def", "ghi"};
458 ASSERT_TRUE(VerifyReadableRegions(expected2, arraysize(expected2)));
459 EXPECT_EQ(8u, sequencer_->num_bytes_buffered());
461 // Consume 2 bytes.
462 sequencer_->MarkConsumed(2);
463 EXPECT_EQ(3u, stream_.flow_controller()->bytes_consumed());
464 // Verify data.
465 const char* expected3[] = {"def", "ghi"};
466 ASSERT_TRUE(VerifyReadableRegions(expected3, arraysize(expected3)));
467 EXPECT_EQ(6u, sequencer_->num_bytes_buffered());
469 // Consume 5 bytes.
470 sequencer_->MarkConsumed(5);
471 EXPECT_EQ(8u, stream_.flow_controller()->bytes_consumed());
472 // Verify data.
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));
481 OnFrame(0, "abc");
482 OnFrame(9, "jklmnopqrstuvwxyz");
484 // Peek into the data. Only the first chunk should be readable because of the
485 // missing data.
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) {
498 InSequence s;
499 EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
501 OnFrame(0, "abc");
502 OnFrame(3, "def");
503 // Missing packet: 6, ghi.
504 OnFrame(9, "jkl");
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
541 // buffered frame.
542 EXPECT_FALSE(FrameOverlapsBufferedData(
543 QuicStreamFrame(1, false, kBufferedOffset - kNewDataLength, data)));
545 // New byte range entirely outside of buffered frames, start offset later than
546 // buffered frame.
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, _))
561 .Times(1);
562 sequencer_->OnStreamFrame(frame2);
565 } // namespace
566 } // namespace test
567 } // namespace net