Index: net/quic/quic_stream_sequencer_test.cc |
=================================================================== |
--- net/quic/quic_stream_sequencer_test.cc (revision 165858) |
+++ net/quic/quic_stream_sequencer_test.cc (working copy) |
@@ -1,413 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "net/quic/quic_stream_sequencer.h" |
- |
-#include <utility> |
-#include <vector> |
- |
-#include "base/rand_util.h" |
-#include "net/quic/reliable_quic_stream.h" |
-#include "testing/gmock/include/gmock/gmock.h" |
-#include "testing/gtest/include/gtest/gtest.h" |
- |
-using base::StringPiece; |
-using std::min; |
-using std::pair; |
-using std::vector; |
-using testing::_; |
-using testing::AnyNumber; |
-using testing::InSequence; |
-using testing::Return; |
-using testing::StrEq; |
- |
-namespace net { |
- |
-class QuicStreamSequencerPeer : public QuicStreamSequencer { |
- public: |
- explicit QuicStreamSequencerPeer(ReliableQuicStream* stream) |
- : QuicStreamSequencer(stream) { |
- } |
- |
- QuicStreamSequencerPeer(int32 max_mem, ReliableQuicStream* stream) |
- : QuicStreamSequencer(max_mem, stream) {} |
- |
- virtual bool OnFrame(QuicStreamOffset byte_offset, |
- const char* data, |
- uint32 data_len) { |
- QuicStreamFrame frame; |
- frame.stream_id = 1; |
- frame.offset = byte_offset; |
- frame.data = StringPiece(data, data_len); |
- return OnStreamFrame(frame); |
- } |
- |
- void SetMemoryLimit(size_t limit) { |
- max_frame_memory_ = limit; |
- } |
- |
- ReliableQuicStream* stream() { return stream_; } |
- uint64 num_bytes_consumed() { return num_bytes_consumed_; } |
- FrameMap* frames() { return &frames_; } |
- int32 max_frame_memory() { return max_frame_memory_; } |
- QuicStreamOffset close_offset() { return close_offset_; } |
-}; |
- |
-class MockStream : public ReliableQuicStream { |
- public: |
- MockStream(QuicSession* session, QuicStreamId id) |
- : ReliableQuicStream(id, session) { |
- } |
- |
- MOCK_METHOD1(TerminateFromPeer, void(bool half_close)); |
- MOCK_METHOD2(ProcessData, uint32(const char* data, uint32 data_len)); |
- MOCK_METHOD1(Close, void(QuicErrorCode error)); |
-}; |
- |
-namespace { |
- |
-static const char kPayload[] = |
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; |
- |
-class QuicStreamSequencerTest : public ::testing::Test { |
- protected: |
- QuicStreamSequencerTest() |
- : session_(NULL), |
- stream_(session_, 1), |
- sequencer_(new QuicStreamSequencerPeer(&stream_)) { |
- } |
- |
- QuicSession* session_; |
- testing::StrictMock<MockStream> stream_; |
- scoped_ptr<QuicStreamSequencerPeer> sequencer_; |
-}; |
- |
-TEST_F(QuicStreamSequencerTest, RejectOldFrame) { |
- EXPECT_CALL(stream_, ProcessData("abc", 3)) |
- .WillOnce(Return(3)); |
- |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
- EXPECT_EQ(0u, sequencer_->frames()->size()); |
- EXPECT_EQ(3u, sequencer_->num_bytes_consumed()); |
- // Nack this - it matches a past sequence number and we should not see it |
- // again. |
- EXPECT_FALSE(sequencer_->OnFrame(0, "def", 3)); |
- EXPECT_EQ(0u, sequencer_->frames()->size()); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, RejectOverlyLargeFrame) { |
- /* |
- EXPECT_DFATAL(sequencer_.reset(new QuicStreamSequencerPeer(2, &stream_)), |
- "Setting max frame memory to 2. " |
- "Some frames will be impossible to handle."); |
- |
- EXPECT_DEBUG_DEATH(sequencer_->OnFrame(0, "abc", 3), ""); |
- */ |
-} |
- |
-TEST_F(QuicStreamSequencerTest, DropFramePastBuffering) { |
- sequencer_->SetMemoryLimit(3); |
- |
- EXPECT_FALSE(sequencer_->OnFrame(3, "abc", 3)); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) { |
- EXPECT_CALL(stream_, ProcessData("abc", 3)); |
- |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
- EXPECT_EQ(1u, sequencer_->frames()->size()); |
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); |
- // Ignore this - it matches a buffered frame. |
- // Right now there's no checking that the payload is consistent. |
- EXPECT_FALSE(sequencer_->OnFrame(0, "def", 3)); |
- EXPECT_EQ(1u, sequencer_->frames()->size()); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, FullFrameConsumed) { |
- EXPECT_CALL(stream_, ProcessData("abc", 3)) |
- .WillOnce(Return(3)); |
- |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
- EXPECT_EQ(0u, sequencer_->frames()->size()); |
- EXPECT_EQ(3u, sequencer_->num_bytes_consumed()); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) { |
- EXPECT_CALL(stream_, ProcessData("abc", 3)) |
- .WillOnce(Return(2)); |
- |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
- EXPECT_EQ(1u, sequencer_->frames()->size()); |
- EXPECT_EQ(2u, sequencer_->num_bytes_consumed()); |
- EXPECT_EQ("c", sequencer_->frames()->find(2)->second); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) { |
- EXPECT_CALL(stream_, ProcessData("abc", 3)) |
- .WillOnce(Return(0)); |
- |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
- EXPECT_EQ(1u, sequencer_->frames()->size()); |
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); |
- EXPECT_EQ("abc", sequencer_->frames()->find(0)->second); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) { |
- EXPECT_TRUE(sequencer_->OnFrame(3, "abc", 3)); |
- EXPECT_EQ(1u, sequencer_->frames()->size()); |
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); |
- EXPECT_EQ("abc", sequencer_->frames()->find(3)->second); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) { |
- // Buffer the first |
- EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3)); |
- EXPECT_EQ(1u, sequencer_->frames()->size()); |
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); |
- // Buffer the second |
- EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); |
- EXPECT_EQ(2u, sequencer_->frames()->size()); |
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); |
- |
- InSequence s; |
- EXPECT_CALL(stream_, ProcessData("abc", 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, ProcessData(StrEq("ghi"), 3)).WillOnce(Return(3)); |
- |
- // Ack right away |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
- EXPECT_EQ(9u, sequencer_->num_bytes_consumed()); |
- |
- EXPECT_EQ(0u, sequencer_->frames()->size()); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, OutOfOrderFramesProcessedWithBuffering) { |
- sequencer_->SetMemoryLimit(9); |
- |
- // Too far to buffer. |
- EXPECT_FALSE(sequencer_->OnFrame(9, "jkl", 3)); |
- |
- // We can afford to buffer this. |
- EXPECT_TRUE(sequencer_->OnFrame(6, "ghi", 3)); |
- EXPECT_EQ(0u, sequencer_->num_bytes_consumed()); |
- |
- InSequence s; |
- EXPECT_CALL(stream_, ProcessData("abc", 3)).WillOnce(Return(3)); |
- |
- // Ack right away |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
- EXPECT_EQ(3u, sequencer_->num_bytes_consumed()); |
- |
- // We should be willing to buffer this now. |
- EXPECT_TRUE(sequencer_->OnFrame(9, "jkl", 3)); |
- EXPECT_EQ(3u, sequencer_->num_bytes_consumed()); |
- |
- EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, ProcessData(StrEq("ghi"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, ProcessData(StrEq("jkl"), 3)).WillOnce(Return(3)); |
- |
- EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); |
- EXPECT_EQ(12u, sequencer_->num_bytes_consumed()); |
- EXPECT_EQ(0u, sequencer_->frames()->size()); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, BasicCloseOrdered) { |
- InSequence s; |
- EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
- |
- EXPECT_CALL(stream_, TerminateFromPeer(false)); |
- sequencer_->CloseStreamAtOffset(3, false); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, BasicHalfOrdered) { |
- InSequence s; |
- |
- EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
- |
- EXPECT_CALL(stream_, TerminateFromPeer(true)); |
- sequencer_->CloseStreamAtOffset(3, true); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, BasicCloseUnordered) { |
- sequencer_->CloseStreamAtOffset(3, false); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
- |
- InSequence s; |
- EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, TerminateFromPeer(false)); |
- |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, BasicHalfUnorderedWithFlush) { |
- sequencer_->CloseStreamAtOffset(6, true); |
- EXPECT_EQ(6u, sequencer_->close_offset()); |
- InSequence s; |
- EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, TerminateFromPeer(true)); |
- |
- EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, BasicCloseUnorderedWithFlush) { |
- sequencer_->CloseStreamAtOffset(6, false); |
- EXPECT_EQ(6u, sequencer_->close_offset()); |
- |
- InSequence s; |
- EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, ProcessData(StrEq("def"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, TerminateFromPeer(false)); |
- |
- EXPECT_TRUE(sequencer_->OnFrame(3, "def", 3)); |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) { |
- sequencer_->CloseStreamAtOffset(3, true); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
- InSequence s; |
- EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, TerminateFromPeer(true)); |
- |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, CloseStreamBeforeCloseEqual) { |
- sequencer_->CloseStreamAtOffset(3, true); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
- |
- sequencer_->CloseStreamAtOffset(3, false); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
- |
- InSequence s; |
- EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, TerminateFromPeer(false)); |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, CloseBeforeTermianteEqual) { |
- sequencer_->CloseStreamAtOffset(3, false); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
- |
- sequencer_->CloseStreamAtOffset(3, true); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
- |
- InSequence s; |
- EXPECT_CALL(stream_, ProcessData(StrEq("abc"), 3)).WillOnce(Return(3)); |
- EXPECT_CALL(stream_, TerminateFromPeer(false)); |
- EXPECT_TRUE(sequencer_->OnFrame(0, "abc", 3)); |
-} |
- |
-TEST_F(QuicStreamSequencerTest, MutipleOffsets) { |
- sequencer_->CloseStreamAtOffset(3, false); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
- |
- EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS)); |
- sequencer_->CloseStreamAtOffset(5, false); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
- |
- EXPECT_CALL(stream_, Close(QUIC_MULTIPLE_TERMINATION_OFFSETS)); |
- sequencer_->CloseStreamAtOffset(1, false); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
- |
- sequencer_->CloseStreamAtOffset(3, false); |
- EXPECT_EQ(3u, sequencer_->close_offset()); |
-} |
- |
-class QuicSequencerRandomTest : public QuicStreamSequencerTest { |
- public: |
- typedef pair<int, string> Frame; |
- typedef vector<Frame> FrameList; |
- |
- void CreateFrames() { |
- int payload_size = arraysize(kPayload) - 1; |
- int remaining_payload = payload_size; |
- while (remaining_payload != 0) { |
- int size = min(OneToN(6), remaining_payload); |
- int idx = payload_size - remaining_payload; |
- list_.push_back(make_pair(idx, string(kPayload + idx, size))); |
- remaining_payload -= size; |
- } |
- } |
- |
- QuicSequencerRandomTest() { |
- //int32 seed = ACMRandom::HostnamePidTimeSeed(); |
- //LOG(INFO) << "**** The current seed is " << seed << " ****"; |
- //random_.reset(new ACMRandom(seed)); |
- |
- CreateFrames(); |
- } |
- |
- int OneToN(int n) { |
- return base::RandInt(1, n); |
- } |
- |
- int MaybeProcessMaybeBuffer(const char* data, uint32 len) { |
- int to_process = len; |
- if (base::RandUint64() % 2 != 0) { |
- to_process = base::RandInt(0, len); |
- } |
- output_.append(data, to_process); |
- LOG(ERROR) << output_; |
- return to_process; |
- } |
- |
- string output_; |
- //scoped_ptr<ACMRandom> random_; |
- FrameList list_; |
-}; |
- |
-// All frames are processed as soon as we have sequential data. |
-// Infinite buffering, so all frames are acked right away. |
-TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) { |
- InSequence s; |
- for (size_t i = 0; i < list_.size(); ++i) { |
- string* data = &list_[i].second; |
- EXPECT_CALL(stream_, ProcessData(StrEq(*data), data->size())) |
- .WillOnce(Return(data->size())); |
- } |
- |
- while (list_.size() != 0) { |
- int idx = OneToN(list_.size()) - 1; |
- LOG(ERROR) << "Sending index " << idx << " " << list_[idx].second.c_str(); |
- EXPECT_TRUE(sequencer_->OnFrame( |
- list_[idx].first, list_[idx].second.c_str(), |
- list_[idx].second.size())); |
- list_.erase(list_.begin() + idx); |
- } |
-} |
- |
-// All frames are processed as soon as we have sequential data. |
-// Buffering, so some frames are rejected. |
-TEST_F(QuicSequencerRandomTest, RandomFramesDroppingNoBackup) { |
- sequencer_->SetMemoryLimit(26); |
- |
- InSequence s; |
- for (size_t i = 0; i < list_.size(); ++i) { |
- string* data = &list_[i].second; |
- EXPECT_CALL(stream_, ProcessData(StrEq(*data), data->size())) |
- .WillOnce(Return(data->size())); |
- } |
- |
- while (list_.size() != 0) { |
- int idx = OneToN(list_.size()) - 1; |
- LOG(ERROR) << "Sending index " << idx << " " << list_[idx].second.c_str(); |
- bool acked = sequencer_->OnFrame( |
- list_[idx].first, list_[idx].second.c_str(), |
- list_[idx].second.size()); |
- if (acked) { |
- list_.erase(list_.begin() + idx); |
- } |
- } |
-} |
- |
-} // namespace |
- |
-} // namespace net |