15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/quic_stream_sequencer.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/rand_util.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/base/ip_endpoint.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/quic_utils.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/quic/reliable_quic_stream.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/quic/test_tools/quic_stream_sequencer_peer.h"
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/test/gtest_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::StringPiece;
22f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using std::map;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::min;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::pair;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using std::vector;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::_;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::AnyNumber;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::InSequence;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::Return;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using testing::StrEq;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockStream : public ReliableQuicStream {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockStream(QuicSession* session, QuicStreamId id)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : ReliableQuicStream(id, session) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD0(OnFinRead, void());
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOCK_METHOD2(ProcessRawData, uint32(const char* data, uint32 data_len));
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  MOCK_METHOD2(CloseConnectionWithDetails, void(QuicErrorCode error,
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                                const string& details));
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error));
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(OnCanWrite, void());
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual QuicPriority EffectivePriority() const OVERRIDE {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return QuicUtils::HighestPriority();
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
50e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  virtual bool IsFlowControlEnabled() const {
51e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    return true;
52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char kPayload[] =
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QuicStreamSequencerTest : public ::testing::Test {
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicStreamSequencerTest()
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : connection_(new MockConnection(false)),
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        session_(connection_),
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        stream_(&session_, 1),
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        sequencer_(new QuicStreamSequencer(&stream_)),
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        buffered_frames_(
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            QuicStreamSequencerPeer::GetBufferedFrames(sequencer_.get())) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool VerifyReadableRegions(const char** expected, size_t num_expected) {
72b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    iovec iovecs[5];
73b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    size_t num_iovecs = sequencer_->GetReadableRegions(iovecs,
74b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                                                       arraysize(iovecs));
75b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return VerifyIovecs(iovecs, num_iovecs, expected, num_expected);
76b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
77b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
78b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool VerifyIovecs(iovec* iovecs,
79b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    size_t num_iovecs,
80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    const char** expected,
81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    size_t num_expected) {
82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (num_expected != num_iovecs) {
83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      LOG(ERROR) << "Incorrect number of iovecs.  Expected: "
84b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                 << num_expected << " Actual: " << num_iovecs;
85b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      return false;
86b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    for (size_t i = 0; i < num_expected; ++i) {
88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      if (!VerifyIovec(iovecs[i], expected[i])) {
89b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        return false;
90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      }
91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return true;
93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool VerifyIovec(const iovec& iovec, StringPiece expected) {
96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (iovec.iov_len != expected.length()) {
97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      LOG(ERROR) << "Invalid length: " << iovec.iov_len
98b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                 << " vs " << expected.length();
99b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      return false;
100b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    if (memcmp(iovec.iov_base, expected.data(), expected.length()) != 0) {
102b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      LOG(ERROR) << "Invalid data: " << static_cast<char*>(iovec.iov_base)
103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                 << " vs " << expected.data();
104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      return false;
105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    }
106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    return true;
107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  }
108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnFinFrame(QuicStreamOffset byte_offset, const char* data) {
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    QuicStreamFrame frame;
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame.stream_id = 1;
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame.offset = byte_offset;
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame.data.Append(const_cast<char*>(data), strlen(data));
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame.fin = true;
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    sequencer_->OnStreamFrame(frame);
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnFrame(QuicStreamOffset byte_offset, const char* data) {
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    QuicStreamFrame frame;
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame.stream_id = 1;
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame.offset = byte_offset;
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame.data.Append(const_cast<char*>(data), strlen(data));
123f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    frame.fin = false;
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    sequencer_->OnStreamFrame(frame);
125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
126f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  MockConnection* connection_;
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  MockSession session_;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  testing::StrictMock<MockStream> stream_;
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<QuicStreamSequencer> sequencer_;
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  map<QuicStreamOffset, string>* buffered_frames_;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, RejectOldFrame) {
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "abc");
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0u, buffered_frames_->size());
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ignore this - it matches a past sequence number and we should not see it
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // again.
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "def");
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0u, buffered_frames_->size());
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) {
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3));
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "abc");
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, buffered_frames_->size());
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ignore this - it matches a buffered frame.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Right now there's no checking that the payload is consistent.
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "def");
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, buffered_frames_->size());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, FullFrameConsumed) {
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "abc");
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0u, buffered_frames_->size());
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameConsumed) {
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sequencer_->SetBlockedUntilFlush();
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "abc");
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, buffered_frames_->size());
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sequencer_->FlushBufferedFrames();
175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0u, buffered_frames_->size());
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(3));
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, OnFinRead());
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFinFrame(3, "def");
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, BlockedThenFullFrameAndFinConsumed) {
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sequencer_->SetBlockedUntilFlush();
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFinFrame(0, "abc");
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, buffered_frames_->size());
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, OnFinRead());
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  sequencer_->FlushBufferedFrames();
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0u, buffered_frames_->size());
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(QuicStreamSequencerTest, EmptyFrame) {
1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  EXPECT_CALL(stream_,
1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME, _));
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "");
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0u, buffered_frames_->size());
202558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
203558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
204558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
205558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(QuicStreamSequencerTest, EmptyFinFrame) {
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(stream_, OnFinRead());
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFinFrame(0, "");
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0u, buffered_frames_->size());
209558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
210558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
211558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(2));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "abc");
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, buffered_frames_->size());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2u, sequencer_->num_bytes_consumed());
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ("c", buffered_frames_->find(2)->second);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) {
2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "abc");
225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, buffered_frames_->size());
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
227f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ("abc", buffered_frames_->find(0)->second);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) {
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(3, "abc");
232f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, buffered_frames_->size());
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
234f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ("abc", buffered_frames_->find(3)->second);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffer the first
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(6, "ghi");
240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, buffered_frames_->size());
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(3u, sequencer_->num_bytes_buffered());
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Buffer the second
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(3, "def");
245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(2u, buffered_frames_->size());
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(6u, sequencer_->num_bytes_buffered());
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(3));
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("ghi"), 3)).WillOnce(Return(3));
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ack right away
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "abc");
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(9u, sequencer_->num_bytes_consumed());
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(0u, sequencer_->num_bytes_buffered());
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(0u, buffered_frames_->size());
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(stream_, OnFinRead());
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFinFrame(0, "abc");
268558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
269f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) {
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OnFinFrame(6, "");
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(6u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(3));
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(stream_, OnFinRead());
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(3, "def");
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "abc");
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OnFinFrame(3, "");
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(stream_, OnFinRead());
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "abc");
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
294b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)TEST_F(QuicStreamSequencerTest, TerminateWithReadv) {
295b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  char buffer[3];
296b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OnFinFrame(3, "");
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
299b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
300a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_FALSE(sequencer_->IsClosed());
301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  OnFrame(0, "abc");
304b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  iovec iov = {&buffer[0], 3};
306b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  int bytes_read = sequencer_->Readv(&iov, 1);
307b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_EQ(3, bytes_read);
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_TRUE(sequencer_->IsClosed());
309b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
310b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, MutipleOffsets) {
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OnFinFrame(3, "");
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS));
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OnFinFrame(5, "");
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
319a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS));
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OnFinFrame(1, "");
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  OnFinFrame(3, "");
324f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(3u, QuicStreamSequencerPeer::GetCloseOffset(sequencer_.get()));
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QuicSequencerRandomTest : public QuicStreamSequencerTest {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef pair<int, string> Frame;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef vector<Frame> FrameList;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateFrames() {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int payload_size = arraysize(kPayload) - 1;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int remaining_payload = payload_size;
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (remaining_payload != 0) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int size = min(OneToN(6), remaining_payload);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int index = payload_size - remaining_payload;
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      list_.push_back(make_pair(index, string(kPayload + index, size)));
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      remaining_payload -= size;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QuicSequencerRandomTest() {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateFrames();
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int OneToN(int n) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return base::RandInt(1, n);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int MaybeProcessMaybeBuffer(const char* data, uint32 len) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int to_process = len;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::RandUint64() % 2 != 0) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      to_process = base::RandInt(0, len);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    output_.append(data, to_process);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return to_process;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string output_;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FrameList list_;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All frames are processed as soon as we have sequential data.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Infinite buffering, so all frames are acked right away.
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InSequence s;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < list_.size(); ++i) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string* data = &list_[i].second;
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EXPECT_CALL(stream_, ProcessRawData(StrEq(*data), data->size()))
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .WillOnce(Return(data->size()));
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  while (!list_.empty()) {
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index = OneToN(list_.size()) - 1;
376010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    LOG(ERROR) << "Sending index " << index << " " << list_[index].second;
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    OnFrame(list_[index].first, list_[index].second.data());
378558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    list_.erase(list_.begin() + index);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
383f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, FrameOverlapsBufferedData) {
384f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Ensure that FrameOverlapsBufferedData returns appropriate responses when
385f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // there is existing data buffered.
386f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
387f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  map<QuicStreamOffset, string>* buffered_frames =
388f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      QuicStreamSequencerPeer::GetBufferedFrames(sequencer_.get());
389f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
390f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const int kBufferedOffset = 10;
391f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const int kBufferedDataLength = 3;
392f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const int kNewDataLength = 3;
393f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  IOVector data = MakeIOVector(string(kNewDataLength, '.'));
394f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
395f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // No overlap if no buffered frames.
396f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(buffered_frames_->empty());
397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(sequencer_->FrameOverlapsBufferedData(
398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      QuicStreamFrame(1, false, kBufferedOffset - 1, data)));
399f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
400f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Add a buffered frame.
401f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  buffered_frames->insert(
402f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      make_pair(kBufferedOffset, string(kBufferedDataLength, '.')));
403f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
404f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // New byte range partially overlaps with buffered frame, start offset
405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // preceeding buffered frame.
406f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData(
407f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      QuicStreamFrame(1, false, kBufferedOffset - 1, data)));
408f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData(
409f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      QuicStreamFrame(1, false, kBufferedOffset - kNewDataLength + 1, data)));
410f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
411f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // New byte range partially overlaps with buffered frame, start offset
412f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // inside existing buffered frame.
413f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData(
414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      QuicStreamFrame(1, false, kBufferedOffset + 1, data)));
415f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData(QuicStreamFrame(
416f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      1, false, kBufferedOffset + kBufferedDataLength - 1, data)));
417f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
418f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // New byte range entirely outside of buffered frames, start offset preceeding
419f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // buffered frame.
420f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(sequencer_->FrameOverlapsBufferedData(
421f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      QuicStreamFrame(1, false, kBufferedOffset - kNewDataLength, data)));
422f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
423f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // New byte range entirely outside of buffered frames, start offset later than
424f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // buffered frame.
425f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(sequencer_->FrameOverlapsBufferedData(QuicStreamFrame(
426f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      1, false, kBufferedOffset + kBufferedDataLength, data)));
427f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
428f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
429f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(QuicStreamSequencerTest, DontAcceptOverlappingFrames) {
430f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The peer should never send us non-identical stream frames which contain
431f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // overlapping byte ranges - if they do, we close the connection.
432f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
433f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicStreamFrame frame1(kClientDataStreamId1, false, 1, MakeIOVector("hello"));
434f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sequencer_->OnStreamFrame(frame1);
435f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
436f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicStreamFrame frame2(kClientDataStreamId1, false, 2, MakeIOVector("hello"));
437f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(sequencer_->FrameOverlapsBufferedData(frame2));
438f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(stream_, CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME, _))
439f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      .Times(1);
440f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  sequencer_->OnStreamFrame(frame2);
441f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
442f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace test
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
446