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 |