Home | History | Annotate | Download | only in quic
      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.
      4 
      5 #include "net/quic/quic_stream_sequencer.h"
      6 
      7 #include <utility>
      8 #include <vector>
      9 
     10 #include "base/rand_util.h"
     11 #include "net/base/ip_endpoint.h"
     12 #include "net/quic/reliable_quic_stream.h"
     13 #include "net/quic/test_tools/quic_test_utils.h"
     14 #include "testing/gmock/include/gmock/gmock.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 using base::StringPiece;
     18 using std::min;
     19 using std::pair;
     20 using std::vector;
     21 using testing::_;
     22 using testing::AnyNumber;
     23 using testing::InSequence;
     24 using testing::Return;
     25 using testing::StrEq;
     26 
     27 namespace net {
     28 namespace test {
     29 
     30 class QuicStreamSequencerPeer : public QuicStreamSequencer {
     31  public:
     32   explicit QuicStreamSequencerPeer(ReliableQuicStream* stream)
     33       : QuicStreamSequencer(stream) {
     34   }
     35 
     36   QuicStreamSequencerPeer(int32 max_mem, ReliableQuicStream* stream)
     37       : QuicStreamSequencer(max_mem, stream) {
     38   }
     39 
     40   virtual bool OnFinFrame(QuicStreamOffset byte_offset, const char* data) {
     41     QuicStreamFrame frame;
     42     frame.stream_id = 1;
     43     frame.offset = byte_offset;
     44     frame.data.Append(const_cast<char*>(data), strlen(data));
     45     frame.fin = true;
     46     return OnStreamFrame(frame);
     47   }
     48 
     49   virtual bool OnFrame(QuicStreamOffset byte_offset, const char* data) {
     50     QuicStreamFrame frame;
     51     frame.stream_id = 1;
     52     frame.offset = byte_offset;
     53     frame.data.Append(const_cast<char*>(data), strlen(data));
     54     frame.fin = false;
     55     return OnStreamFrame(frame);
     56   }
     57 
     58   void SetMemoryLimit(size_t limit) {
     59     max_frame_memory_ = limit;
     60   }
     61   uint64 num_bytes_consumed() const { return num_bytes_consumed_; }
     62   const FrameMap* frames() const { return &frames_; }
     63   QuicStreamOffset close_offset() const { return close_offset_; }
     64 };
     65 
     66 class MockStream : public ReliableQuicStream {
     67  public:
     68   MockStream(QuicSession* session, QuicStreamId id)
     69       : ReliableQuicStream(id, session) {
     70   }
     71 
     72   MOCK_METHOD0(OnFinRead, void());
     73   MOCK_METHOD2(ProcessRawData, uint32(const char* data, uint32 data_len));
     74   MOCK_METHOD2(CloseConnectionWithDetails, void(QuicErrorCode error,
     75                                                 const string& details));
     76   MOCK_METHOD1(Reset, void(QuicRstStreamErrorCode error));
     77   MOCK_METHOD0(OnCanWrite, void());
     78   virtual QuicPriority EffectivePriority() const {
     79     return QuicUtils::HighestPriority();
     80   }
     81 };
     82 
     83 namespace {
     84 
     85 static const char kPayload[] =
     86     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
     87 
     88 class QuicStreamSequencerTest : public ::testing::Test {
     89  protected:
     90   QuicStreamSequencerTest()
     91       : connection_(new MockConnection(false)),
     92         session_(connection_),
     93         stream_(&session_, 1),
     94         sequencer_(new QuicStreamSequencerPeer(&stream_)) {
     95   }
     96 
     97   bool VerifyReadableRegions(const char** expected, size_t num_expected) {
     98     iovec iovecs[5];
     99     size_t num_iovecs = sequencer_->GetReadableRegions(iovecs,
    100                                                        arraysize(iovecs));
    101     return VerifyIovecs(iovecs, num_iovecs, expected, num_expected);
    102   }
    103 
    104   bool VerifyIovecs(iovec* iovecs,
    105                     size_t num_iovecs,
    106                     const char** expected,
    107                     size_t num_expected) {
    108     if (num_expected != num_iovecs) {
    109       LOG(ERROR) << "Incorrect number of iovecs.  Expected: "
    110                  << num_expected << " Actual: " << num_iovecs;
    111       return false;
    112     }
    113     for (size_t i = 0; i < num_expected; ++i) {
    114       if (!VerifyIovec(iovecs[i], expected[i])) {
    115         return false;
    116       }
    117     }
    118     return true;
    119   }
    120 
    121   bool VerifyIovec(const iovec& iovec, StringPiece expected) {
    122     if (iovec.iov_len != expected.length()) {
    123       LOG(ERROR) << "Invalid length: " << iovec.iov_len
    124                  << " vs " << expected.length();
    125       return false;
    126     }
    127     if (memcmp(iovec.iov_base, expected.data(), expected.length()) != 0) {
    128       LOG(ERROR) << "Invalid data: " << static_cast<char*>(iovec.iov_base)
    129                  << " vs " << expected.data();
    130       return false;
    131     }
    132     return true;
    133   }
    134 
    135   MockConnection* connection_;
    136   MockSession session_;
    137   testing::StrictMock<MockStream> stream_;
    138   scoped_ptr<QuicStreamSequencerPeer> sequencer_;
    139 };
    140 
    141 TEST_F(QuicStreamSequencerTest, RejectOldFrame) {
    142   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3))
    143       .WillOnce(Return(3));
    144 
    145   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    146   EXPECT_EQ(0u, sequencer_->frames()->size());
    147   EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
    148   // Ignore this - it matches a past sequence number and we should not see it
    149   // again.
    150   EXPECT_TRUE(sequencer_->OnFrame(0, "def"));
    151   EXPECT_EQ(0u, sequencer_->frames()->size());
    152 }
    153 
    154 TEST_F(QuicStreamSequencerTest, RejectOverlyLargeFrame) {
    155   // TODO(rch): enable when chromium supports EXPECT_DFATAL.
    156   /*
    157   EXPECT_DFATAL(sequencer_.reset(new QuicStreamSequencerPeer(2, &stream_)),
    158                 "Setting max frame memory to 2.  "
    159                 "Some frames will be impossible to handle.");
    160 
    161   EXPECT_DEBUG_DEATH(sequencer_->OnFrame(0, "abc"), "");
    162   */
    163 }
    164 
    165 TEST_F(QuicStreamSequencerTest, DropFramePastBuffering) {
    166   sequencer_->SetMemoryLimit(3);
    167 
    168   EXPECT_FALSE(sequencer_->OnFrame(3, "abc"));
    169 }
    170 
    171 TEST_F(QuicStreamSequencerTest, RejectBufferedFrame) {
    172   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3));
    173 
    174   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    175   EXPECT_EQ(1u, sequencer_->frames()->size());
    176   EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
    177   // Ignore this - it matches a buffered frame.
    178   // Right now there's no checking that the payload is consistent.
    179   EXPECT_TRUE(sequencer_->OnFrame(0, "def"));
    180   EXPECT_EQ(1u, sequencer_->frames()->size());
    181 }
    182 
    183 TEST_F(QuicStreamSequencerTest, FullFrameConsumed) {
    184   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
    185 
    186   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    187   EXPECT_EQ(0u, sequencer_->frames()->size());
    188   EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
    189 }
    190 
    191 TEST_F(QuicStreamSequencerTest, EmptyFrame) {
    192   EXPECT_CALL(stream_,
    193               CloseConnectionWithDetails(QUIC_INVALID_STREAM_FRAME, _));
    194   EXPECT_FALSE(sequencer_->OnFrame(0, ""));
    195   EXPECT_EQ(0u, sequencer_->frames()->size());
    196   EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
    197 }
    198 
    199 TEST_F(QuicStreamSequencerTest, EmptyFinFrame) {
    200   EXPECT_CALL(stream_, OnFinRead());
    201   EXPECT_TRUE(sequencer_->OnFinFrame(0, ""));
    202   EXPECT_EQ(0u, sequencer_->frames()->size());
    203   EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
    204 }
    205 
    206 TEST_F(QuicStreamSequencerTest, PartialFrameConsumed) {
    207   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(2));
    208 
    209   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    210   EXPECT_EQ(1u, sequencer_->frames()->size());
    211   EXPECT_EQ(2u, sequencer_->num_bytes_consumed());
    212   EXPECT_EQ("c", sequencer_->frames()->find(2)->second);
    213 }
    214 
    215 TEST_F(QuicStreamSequencerTest, NextxFrameNotConsumed) {
    216   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
    217 
    218   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    219   EXPECT_EQ(1u, sequencer_->frames()->size());
    220   EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
    221   EXPECT_EQ("abc", sequencer_->frames()->find(0)->second);
    222 }
    223 
    224 TEST_F(QuicStreamSequencerTest, FutureFrameNotProcessed) {
    225   EXPECT_TRUE(sequencer_->OnFrame(3, "abc"));
    226   EXPECT_EQ(1u, sequencer_->frames()->size());
    227   EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
    228   EXPECT_EQ("abc", sequencer_->frames()->find(3)->second);
    229 }
    230 
    231 TEST_F(QuicStreamSequencerTest, OutOfOrderFrameProcessed) {
    232   // Buffer the first
    233   EXPECT_TRUE(sequencer_->OnFrame(6, "ghi"));
    234   EXPECT_EQ(1u, sequencer_->frames()->size());
    235   EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
    236   // Buffer the second
    237   EXPECT_TRUE(sequencer_->OnFrame(3, "def"));
    238   EXPECT_EQ(2u, sequencer_->frames()->size());
    239   EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
    240 
    241   InSequence s;
    242   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
    243   EXPECT_CALL(stream_, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(3));
    244   EXPECT_CALL(stream_, ProcessRawData(StrEq("ghi"), 3)).WillOnce(Return(3));
    245 
    246   // Ack right away
    247   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    248   EXPECT_EQ(9u, sequencer_->num_bytes_consumed());
    249 
    250   EXPECT_EQ(0u, sequencer_->frames()->size());
    251 }
    252 
    253 TEST_F(QuicStreamSequencerTest, OutOfOrderFramesProcessedWithBuffering) {
    254   sequencer_->SetMemoryLimit(9);
    255 
    256   // Too far to buffer.
    257   EXPECT_FALSE(sequencer_->OnFrame(9, "jkl"));
    258 
    259   // We can afford to buffer this.
    260   EXPECT_TRUE(sequencer_->OnFrame(6, "ghi"));
    261   EXPECT_EQ(0u, sequencer_->num_bytes_consumed());
    262 
    263   InSequence s;
    264   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
    265 
    266   // Ack right away
    267   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    268   EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
    269 
    270   // We should be willing to buffer this now.
    271   EXPECT_TRUE(sequencer_->OnFrame(9, "jkl"));
    272   EXPECT_EQ(3u, sequencer_->num_bytes_consumed());
    273 
    274   EXPECT_CALL(stream_, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(3));
    275   EXPECT_CALL(stream_, ProcessRawData(StrEq("ghi"), 3)).WillOnce(Return(3));
    276   EXPECT_CALL(stream_, ProcessRawData(StrEq("jkl"), 3)).WillOnce(Return(3));
    277 
    278   EXPECT_TRUE(sequencer_->OnFrame(3, "def"));
    279   EXPECT_EQ(12u, sequencer_->num_bytes_consumed());
    280   EXPECT_EQ(0u, sequencer_->frames()->size());
    281 }
    282 
    283 TEST_F(QuicStreamSequencerTest, OutOfOrderFramesBlockignWithReadv) {
    284   sequencer_->SetMemoryLimit(9);
    285   char buffer[20];
    286   iovec iov[2];
    287   iov[0].iov_base = &buffer[0];
    288   iov[0].iov_len = 1;
    289   iov[1].iov_base = &buffer[1];
    290   iov[1].iov_len = 2;
    291 
    292   // Push abc - process.
    293   // Push jkl - buffer (not next data)
    294   // Push def - don't process.
    295   // Push mno - drop (too far out)
    296   // Push ghi - buffer (def not processed)
    297   // Read 2.
    298   // Push mno - buffer (not all read)
    299   // Read all
    300   // Push pqr - process
    301 
    302   InSequence s;
    303   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
    304   EXPECT_CALL(stream_, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(0));
    305   EXPECT_CALL(stream_, ProcessRawData(StrEq("pqr"), 3)).WillOnce(Return(3));
    306 
    307   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    308   EXPECT_TRUE(sequencer_->OnFrame(3, "def"));
    309   EXPECT_TRUE(sequencer_->OnFrame(9, "jkl"));
    310   EXPECT_FALSE(sequencer_->OnFrame(12, "mno"));
    311   EXPECT_TRUE(sequencer_->OnFrame(6, "ghi"));
    312 
    313   // Read 3 bytes.
    314   EXPECT_EQ(3, sequencer_->Readv(iov, 2));
    315   EXPECT_EQ(0, strncmp(buffer, "def", 3));
    316 
    317   // Now we have space to bufer this.
    318   EXPECT_TRUE(sequencer_->OnFrame(12, "mno"));
    319 
    320   // Read the remaining 9 bytes.
    321   iov[1].iov_len = 19;
    322   EXPECT_EQ(9, sequencer_->Readv(iov, 2));
    323   EXPECT_EQ(0, strncmp(buffer, "ghijklmno", 9));
    324 
    325   EXPECT_TRUE(sequencer_->OnFrame(15, "pqr"));
    326 }
    327 
    328 // Same as above, just using a different method for reading.
    329 TEST_F(QuicStreamSequencerTest, OutOfOrderFramesBlockignWithGetReadableRegion) {
    330   sequencer_->SetMemoryLimit(9);
    331 
    332   InSequence s;
    333   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
    334   EXPECT_CALL(stream_, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(0));
    335   EXPECT_CALL(stream_, ProcessRawData(StrEq("pqr"), 3)).WillOnce(Return(3));
    336 
    337   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    338   EXPECT_TRUE(sequencer_->OnFrame(3, "def"));
    339   EXPECT_TRUE(sequencer_->OnFrame(9, "jkl"));
    340   EXPECT_FALSE(sequencer_->OnFrame(12, "mno"));
    341   EXPECT_TRUE(sequencer_->OnFrame(6, "ghi"));
    342 
    343   // Read 3 bytes.
    344   const char* expected[] = {"def", "ghi", "jkl"};
    345   ASSERT_TRUE(VerifyReadableRegions(expected, arraysize(expected)));
    346   char buffer[9];
    347   iovec read_iov = { &buffer[0], 3 };
    348   ASSERT_EQ(3, sequencer_->Readv(&read_iov, 1));
    349 
    350   // Now we have space to bufer this.
    351   EXPECT_TRUE(sequencer_->OnFrame(12, "mno"));
    352 
    353   // Read the remaining 9 bytes.
    354   const char* expected2[] = {"ghi", "jkl", "mno"};
    355   ASSERT_TRUE(VerifyReadableRegions(expected2, arraysize(expected2)));
    356   read_iov.iov_len = 9;
    357   ASSERT_EQ(9, sequencer_->Readv(&read_iov, 1));
    358 
    359   EXPECT_TRUE(sequencer_->OnFrame(15, "pqr"));
    360 }
    361 
    362 // Same as above, just using a different method for reading.
    363 TEST_F(QuicStreamSequencerTest, MarkConsumed) {
    364   sequencer_->SetMemoryLimit(9);
    365 
    366   InSequence s;
    367   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
    368 
    369   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    370   EXPECT_TRUE(sequencer_->OnFrame(3, "def"));
    371   EXPECT_TRUE(sequencer_->OnFrame(6, "ghi"));
    372 
    373   // Peek into the data.
    374   const char* expected[] = {"abc", "def", "ghi"};
    375   ASSERT_TRUE(VerifyReadableRegions(expected, arraysize(expected)));
    376 
    377   // Consume 1 byte.
    378   sequencer_->MarkConsumed(1);
    379   // Verify data.
    380   const char* expected2[] = {"bc", "def", "ghi"};
    381   ASSERT_TRUE(VerifyReadableRegions(expected2, arraysize(expected2)));
    382 
    383   // Consume 2 bytes.
    384   sequencer_->MarkConsumed(2);
    385   // Verify data.
    386   const char* expected3[] = {"def", "ghi"};
    387   ASSERT_TRUE(VerifyReadableRegions(expected3, arraysize(expected3)));
    388 
    389   // Consume 5 bytes.
    390   sequencer_->MarkConsumed(5);
    391   // Verify data.
    392   const char* expected4[] = {"i"};
    393   ASSERT_TRUE(VerifyReadableRegions(expected4, arraysize(expected4)));
    394 }
    395 
    396 TEST_F(QuicStreamSequencerTest, MarkConsumedError) {
    397   // TODO(rch): enable when chromium supports EXPECT_DFATAL.
    398   /*
    399   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
    400 
    401   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    402   EXPECT_TRUE(sequencer_->OnFrame(9, "jklmnopqrstuvwxyz"));
    403 
    404   // Peek into the data.  Only the first chunk should be readable
    405   // because of the missing data.
    406   const char* expected[] = {"abc"};
    407   ASSERT_TRUE(VerifyReadableRegions(expected, arraysize(expected)));
    408 
    409   // Now, attempt to mark consumed more data than was readable
    410   // and expect the stream to be closed.
    411   EXPECT_CALL(stream_, Reset(QUIC_ERROR_PROCESSING_STREAM));
    412   EXPECT_DFATAL(sequencer_->MarkConsumed(4),
    413                 "Invalid argument to MarkConsumed.  num_bytes_consumed_: 3 "
    414                 "end_offset: 4 offset: 9 length: 17");
    415   */
    416 }
    417 
    418 TEST_F(QuicStreamSequencerTest, MarkConsumedWithMissingPacket) {
    419   InSequence s;
    420   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
    421 
    422   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    423   EXPECT_TRUE(sequencer_->OnFrame(3, "def"));
    424   // Missing packet: 6, ghi
    425   EXPECT_TRUE(sequencer_->OnFrame(9, "jkl"));
    426 
    427   const char* expected[] = {"abc", "def"};
    428   ASSERT_TRUE(VerifyReadableRegions(expected, arraysize(expected)));
    429 
    430   sequencer_->MarkConsumed(6);
    431 }
    432 
    433 TEST_F(QuicStreamSequencerTest, BasicHalfCloseOrdered) {
    434   InSequence s;
    435 
    436   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
    437   EXPECT_CALL(stream_, OnFinRead());
    438   EXPECT_TRUE(sequencer_->OnFinFrame(0, "abc"));
    439 
    440   EXPECT_EQ(3u, sequencer_->close_offset());
    441 }
    442 
    443 TEST_F(QuicStreamSequencerTest, BasicHalfCloseUnorderedWithFlush) {
    444   sequencer_->OnFinFrame(6, "");
    445   EXPECT_EQ(6u, sequencer_->close_offset());
    446   InSequence s;
    447   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
    448   EXPECT_CALL(stream_, ProcessRawData(StrEq("def"), 3)).WillOnce(Return(3));
    449   EXPECT_CALL(stream_, OnFinRead());
    450 
    451   EXPECT_TRUE(sequencer_->OnFrame(3, "def"));
    452   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    453 }
    454 
    455 TEST_F(QuicStreamSequencerTest, BasicHalfUnordered) {
    456   sequencer_->OnFinFrame(3, "");
    457   EXPECT_EQ(3u, sequencer_->close_offset());
    458   InSequence s;
    459   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(3));
    460   EXPECT_CALL(stream_, OnFinRead());
    461 
    462   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    463 }
    464 
    465 TEST_F(QuicStreamSequencerTest, TerminateWithReadv) {
    466   char buffer[3];
    467 
    468   sequencer_->OnFinFrame(3, "");
    469   EXPECT_EQ(3u, sequencer_->close_offset());
    470 
    471   EXPECT_FALSE(sequencer_->IsClosed());
    472 
    473   EXPECT_CALL(stream_, ProcessRawData(StrEq("abc"), 3)).WillOnce(Return(0));
    474   EXPECT_TRUE(sequencer_->OnFrame(0, "abc"));
    475 
    476   iovec iov = { &buffer[0], 3 };
    477   int bytes_read = sequencer_->Readv(&iov, 1);
    478   EXPECT_EQ(3, bytes_read);
    479   EXPECT_TRUE(sequencer_->IsClosed());
    480 }
    481 
    482 TEST_F(QuicStreamSequencerTest, MutipleOffsets) {
    483   sequencer_->OnFinFrame(3, "");
    484   EXPECT_EQ(3u, sequencer_->close_offset());
    485 
    486   EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS));
    487   sequencer_->OnFinFrame(5, "");
    488   EXPECT_EQ(3u, sequencer_->close_offset());
    489 
    490   EXPECT_CALL(stream_, Reset(QUIC_MULTIPLE_TERMINATION_OFFSETS));
    491   sequencer_->OnFinFrame(1, "");
    492   EXPECT_EQ(3u, sequencer_->close_offset());
    493 
    494   sequencer_->OnFinFrame(3, "");
    495   EXPECT_EQ(3u, sequencer_->close_offset());
    496 }
    497 
    498 class QuicSequencerRandomTest : public QuicStreamSequencerTest {
    499  public:
    500   typedef pair<int, string> Frame;
    501   typedef vector<Frame> FrameList;
    502 
    503   void CreateFrames() {
    504     int payload_size = arraysize(kPayload) - 1;
    505     int remaining_payload = payload_size;
    506     while (remaining_payload != 0) {
    507       int size = min(OneToN(6), remaining_payload);
    508       int index = payload_size - remaining_payload;
    509       list_.push_back(make_pair(index, string(kPayload + index, size)));
    510       remaining_payload -= size;
    511     }
    512   }
    513 
    514   QuicSequencerRandomTest() {
    515     CreateFrames();
    516   }
    517 
    518   int OneToN(int n) {
    519     return base::RandInt(1, n);
    520   }
    521 
    522   int MaybeProcessMaybeBuffer(const char* data, uint32 len) {
    523     int to_process = len;
    524     if (base::RandUint64() % 2 != 0) {
    525       to_process = base::RandInt(0, len);
    526     }
    527     output_.append(data, to_process);
    528     return to_process;
    529   }
    530 
    531   string output_;
    532   FrameList list_;
    533 };
    534 
    535 // All frames are processed as soon as we have sequential data.
    536 // Infinite buffering, so all frames are acked right away.
    537 TEST_F(QuicSequencerRandomTest, RandomFramesNoDroppingNoBackup) {
    538   InSequence s;
    539   for (size_t i = 0; i < list_.size(); ++i) {
    540     string* data = &list_[i].second;
    541     EXPECT_CALL(stream_, ProcessRawData(StrEq(*data), data->size()))
    542         .WillOnce(Return(data->size()));
    543   }
    544 
    545   while (!list_.empty()) {
    546     int index = OneToN(list_.size()) - 1;
    547     LOG(ERROR) << "Sending index " << index << " "
    548                << list_[index].second.data();
    549     EXPECT_TRUE(sequencer_->OnFrame(list_[index].first,
    550                                     list_[index].second.data()));
    551 
    552     list_.erase(list_.begin() + index);
    553   }
    554 }
    555 
    556 // All frames are processed as soon as we have sequential data.
    557 // Buffering, so some frames are rejected.
    558 TEST_F(QuicSequencerRandomTest, RandomFramesDroppingNoBackup) {
    559   sequencer_->SetMemoryLimit(26);
    560 
    561   InSequence s;
    562   for (size_t i = 0; i < list_.size(); ++i) {
    563     string* data = &list_[i].second;
    564     EXPECT_CALL(stream_, ProcessRawData(StrEq(*data), data->size()))
    565         .WillOnce(Return(data->size()));
    566   }
    567 
    568   while (!list_.empty()) {
    569     int index = OneToN(list_.size()) - 1;
    570     LOG(ERROR) << "Sending index " << index << " "
    571                << list_[index].second.data();
    572     bool acked = sequencer_->OnFrame(list_[index].first,
    573                                      list_[index].second.data());
    574 
    575     if (acked) {
    576       list_.erase(list_.begin() + index);
    577     }
    578   }
    579 }
    580 
    581 }  // namespace
    582 }  // namespace test
    583 }  // namespace net
    584