quic_packet_generator_test.cc revision 558790d6acca3451cf3a6b497803a5f07d0bec58
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;
2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using std::string;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::InSequence;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Return;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::SaveArg;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::_;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockDelegate : public QuicPacketGenerator::DelegateInterface {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockDelegate() {}
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~MockDelegate() {}
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MOCK_METHOD2(CanWrite, bool(Retransmission retransmission,
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                              HasRetransmittableData retransmittable));
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(CreateAckFrame, QuicAckFrame*());
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(CreateFeedbackFrame, QuicCongestionFeedbackFrame*());
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD1(OnSerializedPacket, bool(const SerializedPacket& packet));
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void SetCanWriteAnything() {
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, _))
44558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(true));
45558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA))
46558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(true));
47558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
48558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
49558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void SetCanNotWrite() {
50558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, _))
51558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(false));
52558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA))
53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(false));
54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Use this when only ack and feedback frames should be allowed to be written.
57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void SetCanWriteOnlyNonRetransmittable() {
58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, _))
59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(false));
60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    EXPECT_CALL(*this, CanWrite(NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA))
61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(true));
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockDelegate);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Simple struct for describing the contents of a packet.
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Useful in conjunction with a SimpleQuicFrame for validating
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// that a packet contains the expected frames.
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct PacketContents {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents()
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : num_ack_frames(0),
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_connection_close_frames(0),
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_feedback_frames(0),
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_goaway_frames(0),
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_rst_stream_frames(0),
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_stream_frames(0),
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        fec_group(0) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_ack_frames;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_connection_close_frames;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_feedback_frames;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_goaway_frames;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_rst_stream_frames;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_stream_frames;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFecGroupNumber fec_group;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class QuicPacketGeneratorTest : public ::testing::Test {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketGeneratorTest()
97558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      : framer_(QuicVersionMax(), QuicTime::Zero(), false),
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        creator_(42, &framer_, &random_, false),
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        generator_(&delegate_, NULL, &creator_),
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        packet_(0, NULL, 0, NULL),
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        packet2_(0, NULL, 0, NULL),
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        packet3_(0, NULL, 0, NULL),
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        packet4_(0, NULL, 0, NULL),
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        packet5_(0, NULL, 0, NULL) {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~QuicPacketGeneratorTest() {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet_.packet;
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet_.retransmittable_frames;
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet2_.packet;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet2_.retransmittable_frames;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet3_.packet;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet3_.retransmittable_frames;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet4_.packet;
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet4_.retransmittable_frames;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet5_.packet;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet5_.retransmittable_frames;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicAckFrame* CreateAckFrame() {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(rch): Initialize this so it can be verified later.
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return new QuicAckFrame(0, QuicTime::Zero(), 0);
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicCongestionFeedbackFrame* CreateFeedbackFrame() {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicCongestionFeedbackFrame* frame = new QuicCongestionFeedbackFrame;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    frame->type = kFixRate;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    frame->fix_rate.bitrate = QuicBandwidth::FromBytesPerSecond(42);
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return frame;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicRstStreamFrame* CreateRstStreamFrame() {
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return new QuicRstStreamFrame(1, QUIC_STREAM_NO_ERROR);
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicGoAwayFrame* CreateGoAwayFrame() {
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return new QuicGoAwayFrame(QUIC_NO_ERROR, 1, string());
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckPacketContains(const PacketContents& contents,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const SerializedPacket& packet) {
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t num_retransmittable_frames = contents.num_connection_close_frames +
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        contents.num_goaway_frames + contents.num_rst_stream_frames +
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        contents.num_stream_frames;
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t num_frames = contents.num_feedback_frames + contents.num_ack_frames +
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_retransmittable_frames;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (num_retransmittable_frames == 0) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(packet.retransmittable_frames == NULL);
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(packet.retransmittable_frames != NULL);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(num_retransmittable_frames,
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                packet.retransmittable_frames->frames().size());
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.packet != NULL);
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(num_frames, simple_framer_.num_frames());
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size());
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_connection_close_frames,
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.connection_close_frames().size());
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_feedback_frames,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.feedback_frames().size());
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_goaway_frames,
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.goaway_frames().size());
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_rst_stream_frames,
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.rst_stream_frames().size());
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_stream_frames,
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.stream_frames().size());
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.fec_group, simple_framer_.header().fec_group);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckPacketHasSingleStreamFrame(const SerializedPacket& packet) {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.retransmittable_frames != NULL);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, packet.retransmittable_frames->frames().size());
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.packet != NULL);
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, simple_framer_.num_frames());
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, simple_framer_.stream_frames().size());
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckPacketIsFec(const SerializedPacket& packet,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        QuicPacketSequenceNumber fec_group) {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.retransmittable_frames == NULL);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.packet != NULL);
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(simple_framer_.header().fec_flag);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(fec_group, simple_framer_.fec_data().fec_group);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringPiece CreateData(size_t len) {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_array_.reset(new char[len]);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memset(data_array_.get(), '?', len);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return StringPiece(data_array_.get(), len);
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFramer framer_;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRandom random_;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketCreator creator_;
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  testing::StrictMock<MockDelegate> delegate_;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketGenerator generator_;
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SimpleQuicFramer simple_framer_;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet_;
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet2_;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet3_;
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet4_;
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet5_;
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<char[]> data_array_;
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) {
214558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanNotWrite();
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(false);
217868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) {
221558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteOnlyNonRetransmittable();
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(false);
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) {
231558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteOnlyNonRetransmittable();
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(false);
238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest,
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ShouldSendAckWithFeedback_WritableAndShouldNotFlush) {
247558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteOnlyNonRetransmittable();
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(true);
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest,
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ShouldSendAckWithFeedback_WritableAndShouldFlush) {
260558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteOnlyNonRetransmittable();
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(true);
270868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_feedback_frames = 1;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritable) {
279558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanNotWrite();
280558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
281558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
282558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_TRUE(generator_.HasQueuedFrames());
283558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
284558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
285558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(QuicPacketGeneratorTest, AddControlFrame_OnlyAckWritable) {
286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteOnlyNonRetransmittable();
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
289868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) {
293558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
297868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) {
301558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_rst_stream_frames = 1;
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_NotWritable) {
315558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanNotWrite();
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true);
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, consumed.bytes_consumed);
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(consumed.fin_consumed);
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) {
324558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true);
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3u, consumed.bytes_consumed);
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) {
334558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(1, "foo", 2, true);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3u, consumed.bytes_consumed);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 1;
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest,
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
350558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.ConsumeData(1, "foo", 2, true);
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(3, "quux", 7, false);
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4u, consumed.bytes_consumed);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(consumed.fin_consumed);
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_BatchOperations) {
361558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.ConsumeData(1, "foo", 2, true);
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(3, "quux", 7, false);
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4u, consumed.bytes_consumed);
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(consumed.fin_consumed);
368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now both frames will be flushed out.
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.FinishBatchOperations();
374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 2;
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeDataFEC) {
382558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send FEC every two packets.
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  creator_.options()->max_packets_per_fec_group = 2;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InSequence dummy;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet_), Return(true)));
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet2_), Return(true)));
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet3_), Return(true)));
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet4_), Return(true)));
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet5_), Return(true)));
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send enough data to create 3 packets: two full and one partial.
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t data_len = 2 * kMaxPacketSize + 100;
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed =
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      generator_.ConsumeData(3, CreateData(data_len), 0, true);
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
407868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet_);
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet2_);
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketIsFec(packet3_, 1);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet4_);
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketIsFec(packet5_, 4);
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeDataSendsFecAtEnd) {
418558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send FEC every six packets.
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  creator_.options()->max_packets_per_fec_group = 6;
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InSequence dummy;
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet_), Return(true)));
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet2_), Return(true)));
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        DoAll(SaveArg<0>(&packet3_), Return(true)));
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send enough data to create 2 packets: one full and one partial.
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t data_len = 1 * kMaxPacketSize + 100;
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed =
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      generator_.ConsumeData(3, CreateData(data_len), 0, true);
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
439868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet_);
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet2_);
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketIsFec(packet3_, 1);
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) {
447558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanNotWrite();
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(true);
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
451868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
453558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // When the first write operation is invoked, the ack and feedback
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frames will be returned.
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send some data and a control frame
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.ConsumeData(3, "quux", 7, false);
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All five frames will be flushed out in a single packet.
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.FinishBatchOperations();
471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_goaway_frames = 1;
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_feedback_frames = 1;
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_rst_stream_frames = 1;
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 1;
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
483558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanNotWrite();
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.SetShouldSendAck(true);
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
489558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // When the first write operation is invoked, the ack and feedback
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frames will be returned.
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InSequence dummy;
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All five frames will be flushed out in a single packet
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet_), Return(true)));
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DoAll(SaveArg<0>(&packet2_), Return(true)));
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send enough data to exceed one packet
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t data_len = kMaxPacketSize + 100;
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed =
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      generator_.ConsumeData(3, CreateData(data_len), 0, true);
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.FinishBatchOperations();
517868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first packet should have the queued data and part of the stream data.
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_feedback_frames = 1;
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_rst_stream_frames = 1;
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 1;
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second should have the remainder of the stream data.
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents2;
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents2.num_goaway_frames = 1;
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents2.num_stream_frames = 1;
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents2, packet2_);
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace test
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
536