quic_packet_generator_test.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_packet_generator.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/crypto_protocol.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/null_encrypter.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/quic_decrypter.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/crypto/quic_encrypter.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/quic_utils.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/simple_quic_framer.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::StringPiece;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::InSequence;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Return;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::SaveArg;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::_;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockDelegate : public QuicPacketGenerator::DelegateInterface {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockDelegate() {}
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~MockDelegate() {}
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD2(CanWrite, bool(Retransmission retransmission,
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              HasRetransmittableData retransmittable));
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(CreateAckFrame, QuicAckFrame*());
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(CreateFeedbackFrame, QuicCongestionFeedbackFrame*());
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD1(OnSerializedPacket, bool(const SerializedPacket& packet));
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetCanWrite(bool can_write) {
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, _))
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        .WillRepeatedly(Return(can_write));
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockDelegate);
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Simple struct for describing the contents of a packet.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Useful in conjunction with a SimpleQuicFrame for validating
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// that a packet contains the expected frames.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct PacketContents {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents()
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : num_ack_frames(0),
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_connection_close_frames(0),
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_feedback_frames(0),
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_goaway_frames(0),
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_rst_stream_frames(0),
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_stream_frames(0),
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        fec_group(0) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_ack_frames;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_connection_close_frames;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_feedback_frames;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_goaway_frames;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_rst_stream_frames;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_stream_frames;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFecGroupNumber fec_group;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class QuicPacketGeneratorTest : public ::testing::Test {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketGeneratorTest()
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : framer_(kQuicVersion1, QuicTime::Zero(), false),
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        creator_(42, &framer_, &random_, false),
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        generator_(&delegate_, &creator_),
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        packet_(0, NULL, 0, NULL),
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        packet2_(0, NULL, 0, NULL),
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        packet3_(0, NULL, 0, NULL),
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        packet4_(0, NULL, 0, NULL),
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        packet5_(0, NULL, 0, NULL) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~QuicPacketGeneratorTest() {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet_.packet;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet_.retransmittable_frames;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet2_.packet;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet2_.retransmittable_frames;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet3_.packet;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet3_.retransmittable_frames;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet4_.packet;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet4_.retransmittable_frames;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet5_.packet;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet5_.retransmittable_frames;
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicAckFrame* CreateAckFrame() {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(rch): Initialize this so it can be verified later.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new QuicAckFrame(0, QuicTime::Zero(), 0);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicCongestionFeedbackFrame* CreateFeedbackFrame() {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicCongestionFeedbackFrame* frame = new QuicCongestionFeedbackFrame;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    frame->type = kFixRate;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    frame->fix_rate.bitrate = QuicBandwidth::FromBytesPerSecond(42);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return frame;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicRstStreamFrame* CreateRstStreamFrame() {
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return new QuicRstStreamFrame(1, QUIC_STREAM_NO_ERROR);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicGoAwayFrame* CreateGoAwayFrame() {
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return new QuicGoAwayFrame(QUIC_NO_ERROR, 1, std::string());
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckPacketContains(const PacketContents& contents,
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const SerializedPacket& packet) {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t num_retransmittable_frames = contents.num_connection_close_frames +
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        contents.num_goaway_frames + contents.num_rst_stream_frames +
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        contents.num_stream_frames;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t num_frames = contents.num_feedback_frames + contents.num_ack_frames +
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_retransmittable_frames;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (num_retransmittable_frames == 0) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(packet.retransmittable_frames == NULL);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(packet.retransmittable_frames != NULL);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(num_retransmittable_frames,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                packet.retransmittable_frames->frames().size());
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.packet != NULL);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(num_frames, simple_framer_.num_frames());
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size());
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_connection_close_frames,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.connection_close_frames().size());
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_feedback_frames,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.feedback_frames().size());
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_goaway_frames,
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.goaway_frames().size());
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_rst_stream_frames,
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.rst_stream_frames().size());
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_stream_frames,
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.stream_frames().size());
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.fec_group, simple_framer_.header().fec_group);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckPacketHasSingleStreamFrame(const SerializedPacket& packet) {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.retransmittable_frames != NULL);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, packet.retransmittable_frames->frames().size());
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.packet != NULL);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, simple_framer_.num_frames());
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, simple_framer_.stream_frames().size());
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckPacketIsFec(const SerializedPacket& packet,
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        QuicPacketSequenceNumber fec_group) {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.retransmittable_frames == NULL);
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.packet != NULL);
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(simple_framer_.header().fec_flag);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(fec_group, simple_framer_.fec_data().fec_group);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringPiece CreateData(size_t len) {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_array_.reset(new char[len]);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memset(data_array_.get(), '?', len);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return StringPiece(data_array_.get(), len);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFramer framer_;
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRandom random_;
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketCreator creator_;
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing::StrictMock<MockDelegate> delegate_;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketGenerator generator_;
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SimpleQuicFramer simple_framer_;
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet_;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet2_;
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet3_;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet4_;
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet5_;
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<char[]> data_array_;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) {
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(false);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(false);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedData());
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) {
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(false);
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedData());
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(false);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedData());
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest,
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ShouldSendAckWithFeedback_WritableAndShouldNotFlush) {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(true);
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedData());
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest,
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ShouldSendAckWithFeedback_WritableAndShouldFlush) {
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(true);
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedData());
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_feedback_frames = 1;
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritable) {
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(false);
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedData());
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedData());
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) {
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedData());
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_rst_stream_frames = 1;
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_NotWritable) {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(false);
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true);
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, consumed.bytes_consumed);
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(consumed.fin_consumed);
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedData());
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) {
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true);
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3u, consumed.bytes_consumed);
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedData());
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) {
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true);
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3u, consumed.bytes_consumed);
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedData());
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 1;
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest,
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.ConsumeData(1, "foo", 2, true);
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(3, "quux", 7, false);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4u, consumed.bytes_consumed);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(consumed.fin_consumed);
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedData());
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_BatchOperations) {
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.ConsumeData(1, "foo", 2, true);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(3, "quux", 7, false);
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4u, consumed.bytes_consumed);
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(consumed.fin_consumed);
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedData());
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now both frames will be flushed out.
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.FinishBatchOperations();
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedData());
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 2;
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeDataFEC) {
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send FEC every two packets.
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  creator_.options()->max_packets_per_fec_group = 2;
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InSequence dummy;
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet_), Return(true)));
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet2_), Return(true)));
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet3_), Return(true)));
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet4_), Return(true)));
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet5_), Return(true)));
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send enough data to create 3 packets: two full and one partial.
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t data_len = 2 * kMaxPacketSize + 100;
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed =
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      generator_.ConsumeData(3, CreateData(data_len), 0, true);
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedData());
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet_);
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet2_);
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketIsFec(packet3_, 1);
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet4_);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketIsFec(packet5_, 4);
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeDataSendsFecAtEnd) {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send FEC every six packets.
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  creator_.options()->max_packets_per_fec_group = 6;
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InSequence dummy;
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet_), Return(true)));
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet2_), Return(true)));
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet3_), Return(true)));
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send enough data to create 2 packets: one full and one partial.
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t data_len = 1 * kMaxPacketSize + 100;
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed =
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      generator_.ConsumeData(3, CreateData(data_len), 0, true);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedData());
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet_);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet2_);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketIsFec(packet3_, 1);
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) {
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(false);
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(true);
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedData());
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // When the first write operation is invoked, the ack and feedback
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frames will be returned.
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send some data and a control frame
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.ConsumeData(3, "quux", 7, false);
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All five frames will be flushed out in a single packet.
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.FinishBatchOperations();
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedData());
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_goaway_frames = 1;
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_feedback_frames = 1;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_rst_stream_frames = 1;
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 1;
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(false);
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(true);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedData());
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delegate_.SetCanWrite(true);
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // When the first write operation is invoked, the ack and feedback
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frames will be returned.
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InSequence dummy;
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All five frames will be flushed out in a single packet
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet2_), Return(true)));
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send enough data to exceed one packet
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t data_len = kMaxPacketSize + 100;
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed =
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      generator_.ConsumeData(3, CreateData(data_len), 0, true);
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.FinishBatchOperations();
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedData());
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first packet should have the queued data and part of the stream data.
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_feedback_frames = 1;
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_rst_stream_frames = 1;
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 1;
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second should have the remainder of the stream data.
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents2;
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents2.num_goaway_frames = 1;
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents2.num_stream_frames = 1;
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents2, packet2_);
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace test
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
511