| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_stream_sequencer.h" | 5 #include "net/quic/quic_stream_sequencer.h" |
| 6 | 6 |
| 7 #include <string> |
| 7 #include <utility> | 8 #include <utility> |
| 8 #include <vector> | 9 #include <vector> |
| 9 | 10 |
| 10 #include "base/logging.h" | 11 #include "base/logging.h" |
| 11 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
| 12 #include "net/base/ip_endpoint.h" | 13 #include "net/base/ip_endpoint.h" |
| 13 #include "net/quic/quic_utils.h" | 14 #include "net/quic/quic_utils.h" |
| 14 #include "net/quic/reliable_quic_stream.h" | 15 #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_stream_sequencer_peer.h" |
| 16 #include "net/quic/test_tools/quic_test_utils.h" | 17 #include "net/quic/test_tools/quic_test_utils.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 34 | 35 |
| 35 class MockStream : public ReliableQuicStream { | 36 class MockStream : public ReliableQuicStream { |
| 36 public: | 37 public: |
| 37 MockStream(QuicSession* session, QuicStreamId id) | 38 MockStream(QuicSession* session, QuicStreamId id) |
| 38 : ReliableQuicStream(id, session) { | 39 : ReliableQuicStream(id, session) { |
| 39 } | 40 } |
| 40 | 41 |
| 41 MOCK_METHOD0(OnFinRead, void()); | 42 MOCK_METHOD0(OnFinRead, void()); |
| 42 MOCK_METHOD2(ProcessRawData, uint32(const char* data, uint32 data_len)); | 43 MOCK_METHOD2(ProcessRawData, uint32(const char* data, uint32 data_len)); |
| 43 MOCK_METHOD2(CloseConnectionWithDetails, void(QuicErrorCode error, | 44 MOCK_METHOD2(CloseConnectionWithDetails, void(QuicErrorCode error, |
| 44 const string& details)); | 45 const std::string& details)); |
| 45 MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error)); | 46 MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error)); |
| 46 MOCK_METHOD0(OnCanWrite, void()); | 47 MOCK_METHOD0(OnCanWrite, void()); |
| 47 QuicPriority EffectivePriority() const override { | 48 QuicPriority EffectivePriority() const override { |
| 48 return QuicUtils::HighestPriority(); | 49 return QuicUtils::HighestPriority(); |
| 49 } | 50 } |
| 50 virtual bool IsFlowControlEnabled() const { | 51 virtual bool IsFlowControlEnabled() const { |
| 51 return true; | 52 return true; |
| 52 } | 53 } |
| 53 }; | 54 }; |
| 54 | 55 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 frame.offset = byte_offset; | 122 frame.offset = byte_offset; |
| 122 frame.data.Append(const_cast<char*>(data), strlen(data)); | 123 frame.data.Append(const_cast<char*>(data), strlen(data)); |
| 123 frame.fin = false; | 124 frame.fin = false; |
| 124 sequencer_->OnStreamFrame(frame); | 125 sequencer_->OnStreamFrame(frame); |
| 125 } | 126 } |
| 126 | 127 |
| 127 MockConnection* connection_; | 128 MockConnection* connection_; |
| 128 MockSession session_; | 129 MockSession session_; |
| 129 testing::StrictMock<MockStream> stream_; | 130 testing::StrictMock<MockStream> stream_; |
| 130 scoped_ptr<QuicStreamSequencer> sequencer_; | 131 scoped_ptr<QuicStreamSequencer> sequencer_; |
| 131 map<QuicStreamOffset, string>* buffered_frames_; | 132 map<QuicStreamOffset, std::string>* buffered_frames_; |
| 132 }; | 133 }; |
| 133 | 134 |
| 134 TEST_F(QuicStreamSequencerTest, RejectOldFrame) { | 135 TEST_F(QuicStreamSequencerTest, RejectOldFrame) { |
| 135 EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3)); | 136 EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3)); |
| 136 | 137 |
| 137 OnFrame(0, "abc"); | 138 OnFrame(0, "abc"); |
| 138 EXPECT_EQ(0u, buffered_frames_->size()); | 139 EXPECT_EQ(0u, buffered_frames_->size()); |
| 139 EXPECT_EQ(3u, sequencer_->num_bytes_consumed()); | 140 EXPECT_EQ(3u, sequencer_->num_bytes_consumed()); |
| 140 // Ignore this - it matches a past sequence number and we should not see it | 141 // Ignore this - it matches a past sequence number and we should not see it |
| 141 // again. | 142 // again. |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS)); | 320 EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS)); |
| 320 OnFinFrame(1, ""); | 321 OnFinFrame(1, ""); |
| 321 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | 322 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); |
| 322 | 323 |
| 323 OnFinFrame(3, ""); | 324 OnFinFrame(3, ""); |
| 324 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); | 325 EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get())); |
| 325 } | 326 } |
| 326 | 327 |
| 327 class QuicSequencerRandomTest : public QuicStreamSequencerTest { | 328 class QuicSequencerRandomTest : public QuicStreamSequencerTest { |
| 328 public: | 329 public: |
| 329 typedef pair<int, string> Frame; | 330 typedef pair<int, std::string> Frame; |
| 330 typedef vector<Frame> FrameList; | 331 typedef vector<Frame> FrameList; |
| 331 | 332 |
| 332 void CreateFrames() { | 333 void CreateFrames() { |
| 333 int payload_size = arraysize(kPayload) - 1; | 334 int payload_size = arraysize(kPayload) - 1; |
| 334 int remaining_payload = payload_size; | 335 int remaining_payload = payload_size; |
| 335 while (remaining_payload != 0) { | 336 while (remaining_payload != 0) { |
| 336 int size = min(OneToN(6), remaining_payload); | 337 int size = min(OneToN(6), remaining_payload); |
| 337 int index = payload_size - remaining_payload; | 338 int index = payload_size - remaining_payload; |
| 338 list_.push_back(make_pair(index, string(kPayload + index, size))); | 339 list_.push_back(make_pair(index, std::string(kPayload + index, size))); |
| 339 remaining_payload -= size; | 340 remaining_payload -= size; |
| 340 } | 341 } |
| 341 } | 342 } |
| 342 | 343 |
| 343 QuicSequencerRandomTest() { | 344 QuicSequencerRandomTest() { |
| 344 CreateFrames(); | 345 CreateFrames(); |
| 345 } | 346 } |
| 346 | 347 |
| 347 int OneToN(int n) { | 348 int OneToN(int n) { |
| 348 return base::RandInt(1, n); | 349 return base::RandInt(1, n); |
| 349 } | 350 } |
| 350 | 351 |
| 351 int MaybeProcessMaybeBuffer(const char* data, uint32 len) { | 352 int MaybeProcessMaybeBuffer(const char* data, uint32 len) { |
| 352 int to_process = len; | 353 int to_process = len; |
| 353 if (base::RandUint64() % 2 != 0) { | 354 if (base::RandUint64() % 2 != 0) { |
| 354 to_process = base::RandInt(0, len); | 355 to_process = base::RandInt(0, len); |
| 355 } | 356 } |
| 356 output_.append(data, to_process); | 357 output_.append(data, to_process); |
| 357 return to_process; | 358 return to_process; |
| 358 } | 359 } |
| 359 | 360 |
| 360 string output_; | 361 std::string output_; |
| 361 FrameList list_; | 362 FrameList list_; |
| 362 }; | 363 }; |
| 363 | 364 |
| 364 // All frames are processed as soon as we have sequential data. | 365 // All frames are processed as soon as we have sequential data. |
| 365 // Infinite buffering, so all frames are acked right away. | 366 // Infinite buffering, so all frames are acked right away. |
| 366 TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) { | 367 TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) { |
| 367 InSequence s; | 368 InSequence s; |
| 368 for (size_t i = 0; i < list_.size(); ++i) { | 369 for (size_t i = 0; i < list_.size(); ++i) { |
| 369 string* data = &list_[i].second; | 370 std::string* data = &list_[i].second; |
| 370 EXPECT_CALL(stream_, ProcessRawData(StrEq(*data), data->size())) | 371 EXPECT_CALL(stream_, ProcessRawData(StrEq(*data), data->size())) |
| 371 .WillOnce(Return(data->size())); | 372 .WillOnce(Return(data->size())); |
| 372 } | 373 } |
| 373 | 374 |
| 374 while (!list_.empty()) { | 375 while (!list_.empty()) { |
| 375 int index = OneToN(list_.size()) - 1; | 376 int index = OneToN(list_.size()) - 1; |
| 376 LOG(ERROR) << "Sending index " << index << " " << list_[index].second; | 377 LOG(ERROR) << "Sending index " << index << " " << list_[index].second; |
| 377 OnFrame(list_[index].first, list_[index].second.data()); | 378 OnFrame(list_[index].first, list_[index].second.data()); |
| 378 | 379 |
| 379 list_.erase(list_.begin() + index); | 380 list_.erase(list_.begin() + index); |
| 380 } | 381 } |
| 381 } | 382 } |
| 382 | 383 |
| 383 TEST_F(QuicStreamSequencerTest, FrameOverlapsBufferedData) { | 384 TEST_F(QuicStreamSequencerTest, FrameOverlapsBufferedData) { |
| 384 // Ensure that FrameOverlapsBufferedData returns appropriate responses when | 385 // Ensure that FrameOverlapsBufferedData returns appropriate responses when |
| 385 // there is existing data buffered. | 386 // there is existing data buffered. |
| 386 | 387 |
| 387 map<QuicStreamOffset, string>* buffered_frames = | 388 map<QuicStreamOffset, std::string>* buffered_frames = |
| 388 QuicStreamSequencerPeer::GetBufferedFrames(sequencer_.get()); | 389 QuicStreamSequencerPeer::GetBufferedFrames(sequencer_.get()); |
| 389 | 390 |
| 390 const int kBufferedOffset = 10; | 391 const int kBufferedOffset = 10; |
| 391 const int kBufferedDataLength = 3; | 392 const int kBufferedDataLength = 3; |
| 392 const int kNewDataLength = 3; | 393 const int kNewDataLength = 3; |
| 393 IOVector data = MakeIOVector(string(kNewDataLength, '.')); | 394 IOVector data = MakeIOVector(std::string(kNewDataLength, '.')); |
| 394 | 395 |
| 395 // No overlap if no buffered frames. | 396 // No overlap if no buffered frames. |
| 396 EXPECT_TRUE(buffered_frames_->empty()); | 397 EXPECT_TRUE(buffered_frames_->empty()); |
| 397 EXPECT_FALSE(sequencer_->FrameOverlapsBufferedData( | 398 EXPECT_FALSE(sequencer_->FrameOverlapsBufferedData( |
| 398 QuicStreamFrame(1, false, kBufferedOffset - 1, data))); | 399 QuicStreamFrame(1, false, kBufferedOffset - 1, data))); |
| 399 | 400 |
| 400 // Add a buffered frame. | 401 // Add a buffered frame. |
| 401 buffered_frames->insert( | 402 buffered_frames->insert( |
| 402 make_pair(kBufferedOffset, string(kBufferedDataLength, '.'))); | 403 make_pair(kBufferedOffset, std::string(kBufferedDataLength, '.'))); |
| 403 | 404 |
| 404 // New byte range partially overlaps with buffered frame, start offset | 405 // New byte range partially overlaps with buffered frame, start offset |
| 405 // preceeding buffered frame. | 406 // preceeding buffered frame. |
| 406 EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData( | 407 EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData( |
| 407 QuicStreamFrame(1, false, kBufferedOffset - 1, data))); | 408 QuicStreamFrame(1, false, kBufferedOffset - 1, data))); |
| 408 EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData( | 409 EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData( |
| 409 QuicStreamFrame(1, false, kBufferedOffset - kNewDataLength + 1, data))); | 410 QuicStreamFrame(1, false, kBufferedOffset - kNewDataLength + 1, data))); |
| 410 | 411 |
| 411 // New byte range partially overlaps with buffered frame, start offset | 412 // New byte range partially overlaps with buffered frame, start offset |
| 412 // inside existing buffered frame. | 413 // inside existing buffered frame. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 436 QuicStreamFrame frame2(kClientDataStreamId1, false, 2, MakeIOVector("hello")); | 437 QuicStreamFrame frame2(kClientDataStreamId1, false, 2, MakeIOVector("hello")); |
| 437 EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData(frame2)); | 438 EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData(frame2)); |
| 438 EXPECT_CALL(stream_, CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME, _)) | 439 EXPECT_CALL(stream_, CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME, _)) |
| 439 .Times(1); | 440 .Times(1); |
| 440 sequencer_->OnStreamFrame(frame2); | 441 sequencer_->OnStreamFrame(frame2); |
| 441 } | 442 } |
| 442 | 443 |
| 443 } // namespace | 444 } // namespace |
| 444 } // namespace test | 445 } // namespace test |
| 445 } // namespace net | 446 } // namespace net |
| OLD | NEW |