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"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "net/quic/test_tools/quic_packet_creator_peer.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "net/quic/test_tools/quic_packet_generator_peer.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/quic/test_tools/simple_quic_framer.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::StringPiece;
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using std::string;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::InSequence;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::Return;
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::SaveArg;
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)using testing::StrictMock;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using testing::_;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace test {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MockDelegate : public QuicPacketGenerator::DelegateInterface {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockDelegate() {}
36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~MockDelegate() OVERRIDE {}
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MOCK_METHOD3(ShouldGeneratePacket,
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)               bool(TransmissionType transmission_type,
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                    HasRetransmittableData retransmittable,
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                    IsHandshake handshake));
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(CreateAckFrame, QuicAckFrame*());
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MOCK_METHOD0(CreateFeedbackFrame, QuicCongestionFeedbackFrame*());
44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MOCK_METHOD0(CreateStopWaitingFrame, QuicStopWaitingFrame*());
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  MOCK_METHOD1(OnSerializedPacket, void(const SerializedPacket& packet));
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  MOCK_METHOD2(CloseConnection, void(QuicErrorCode, bool));
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
48558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void SetCanWriteAnything() {
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_CALL(*this, ShouldGeneratePacket(NOT_RETRANSMISSION, _, _))
50558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(true));
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_CALL(*this, ShouldGeneratePacket(NOT_RETRANSMISSION,
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                            NO_RETRANSMITTABLE_DATA, _))
53558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(true));
54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void SetCanNotWrite() {
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_CALL(*this, ShouldGeneratePacket(NOT_RETRANSMISSION, _, _))
58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(false));
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_CALL(*this, ShouldGeneratePacket(NOT_RETRANSMISSION,
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                            NO_RETRANSMITTABLE_DATA, _))
61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(false));
62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
63558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // Use this when only ack and feedback frames should be allowed to be written.
65558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void SetCanWriteOnlyNonRetransmittable() {
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_CALL(*this, ShouldGeneratePacket(NOT_RETRANSMISSION, _, _))
67558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(false));
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    EXPECT_CALL(*this, ShouldGeneratePacket(NOT_RETRANSMISSION,
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                            NO_RETRANSMITTABLE_DATA, _))
70558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        .WillRepeatedly(Return(true));
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockDelegate);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Simple struct for describing the contents of a packet.
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Useful in conjunction with a SimpleQuicFrame for validating
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// that a packet contains the expected frames.
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct PacketContents {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents()
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : num_ack_frames(0),
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_connection_close_frames(0),
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_feedback_frames(0),
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_goaway_frames(0),
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_rst_stream_frames(0),
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        num_stop_waiting_frames(0),
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        num_stream_frames(0),
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        fec_group(0) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_ack_frames;
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_connection_close_frames;
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_feedback_frames;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_goaway_frames;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_rst_stream_frames;
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_t num_stop_waiting_frames;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t num_stream_frames;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFecGroupNumber fec_group;
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class QuicPacketGeneratorTest : public ::testing::Test {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketGeneratorTest()
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      : framer_(QuicSupportedVersions(), QuicTime::Zero(), false),
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        generator_(42, &framer_, &random_, &delegate_),
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        creator_(QuicPacketGeneratorPeer::GetPacketCreator(&generator_)),
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        packet_(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL),
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        packet2_(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL),
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        packet3_(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL),
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        packet4_(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL),
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        packet5_(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL),
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        packet6_(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL),
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        packet7_(0, PACKET_1BYTE_SEQUENCE_NUMBER, NULL, 0, NULL) {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~QuicPacketGeneratorTest() OVERRIDE {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet_.packet;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet_.retransmittable_frames;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet2_.packet;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet2_.retransmittable_frames;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet3_.packet;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet3_.retransmittable_frames;
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet4_.packet;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet4_.retransmittable_frames;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet5_.packet;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete packet5_.retransmittable_frames;
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    delete packet6_.packet;
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    delete packet6_.retransmittable_frames;
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    delete packet7_.packet;
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    delete packet7_.retransmittable_frames;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicAckFrame* CreateAckFrame() {
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(rch): Initialize this so it can be verified later.
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return new QuicAckFrame(MakeAckFrame(0));
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicCongestionFeedbackFrame* CreateFeedbackFrame() {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    QuicCongestionFeedbackFrame* frame = new QuicCongestionFeedbackFrame;
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    frame->type = kTCP;
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    frame->tcp.receive_window = 0x4030;
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return frame;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  QuicStopWaitingFrame* CreateStopWaitingFrame() {
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    QuicStopWaitingFrame* frame = new QuicStopWaitingFrame();
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    frame->entropy_hash = 0;
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    frame->least_unacked = 0;
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return frame;
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicRstStreamFrame* CreateRstStreamFrame() {
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return new QuicRstStreamFrame(1, QUIC_STREAM_NO_ERROR, 0);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicGoAwayFrame* CreateGoAwayFrame() {
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return new QuicGoAwayFrame(QUIC_NO_ERROR, 1, string());
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckPacketContains(const PacketContents& contents,
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const SerializedPacket& packet) {
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t num_retransmittable_frames = contents.num_connection_close_frames +
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        contents.num_goaway_frames + contents.num_rst_stream_frames +
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        contents.num_stream_frames;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t num_frames = contents.num_feedback_frames + contents.num_ack_frames +
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        contents.num_stop_waiting_frames + num_retransmittable_frames;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (num_retransmittable_frames == 0) {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(packet.retransmittable_frames == NULL);
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ASSERT_TRUE(packet.retransmittable_frames != NULL);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXPECT_EQ(num_retransmittable_frames,
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                packet.retransmittable_frames->frames().size());
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.packet != NULL);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(num_frames, simple_framer_.num_frames());
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_ack_frames, simple_framer_.ack_frames().size());
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_connection_close_frames,
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.connection_close_frames().size());
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_feedback_frames,
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.feedback_frames().size());
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_goaway_frames,
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.goaway_frames().size());
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_rst_stream_frames,
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.rst_stream_frames().size());
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.num_stream_frames,
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              simple_framer_.stream_frames().size());
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    EXPECT_EQ(contents.num_stop_waiting_frames,
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)              simple_framer_.stop_waiting_frames().size());
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(contents.fec_group, simple_framer_.header().fec_group);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckPacketHasSingleStreamFrame(const SerializedPacket& packet) {
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.retransmittable_frames != NULL);
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, packet.retransmittable_frames->frames().size());
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.packet != NULL);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, simple_framer_.num_frames());
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(1u, simple_framer_.stream_frames().size());
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void CheckPacketIsFec(const SerializedPacket& packet,
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        QuicPacketSequenceNumber fec_group) {
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.retransmittable_frames == NULL);
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(packet.packet != NULL);
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(simple_framer_.ProcessPacket(*packet.packet));
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_TRUE(simple_framer_.header().fec_flag);
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(fec_group, simple_framer_.fec_data().fec_group);
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  IOVector CreateData(size_t len) {
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_array_.reset(new char[len]);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    memset(data_array_.get(), '?', len);
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    IOVector data;
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    data.Append(data_array_.get(), len);
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return data;
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicFramer framer_;
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MockRandom random_;
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StrictMock<MockDelegate> delegate_;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicPacketGenerator generator_;
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicPacketCreator* creator_;
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SimpleQuicFramer simple_framer_;
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet_;
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet2_;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet3_;
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet4_;
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SerializedPacket packet5_;
236f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SerializedPacket packet6_;
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  SerializedPacket packet7_;
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<char[]> data_array_;
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class MockDebugDelegate : public QuicPacketGenerator::DebugDelegate {
2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) public:
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MOCK_METHOD1(OnFrameAddedToPacket,
2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)               void(const QuicFrame&));
2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)};
2483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ShouldSendAck_NotWritable) {
250558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanNotWrite();
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  generator_.SetShouldSendAck(false, false);
253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldNotFlush) {
2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  StrictMock<MockDebugDelegate> debug_delegate;
2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  generator_.set_debug_delegate(&debug_delegate);
260558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteOnlyNonRetransmittable();
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXPECT_CALL(debug_delegate, OnFrameAddedToPacket(_)).Times(1);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  generator_.SetShouldSendAck(false, false);
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ShouldSendAck_WritableAndShouldFlush) {
271558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteOnlyNonRetransmittable();
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_));
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  generator_.SetShouldSendAck(false, false);
277868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest,
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ShouldSendAckWithFeedback_WritableAndShouldNotFlush) {
286558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteOnlyNonRetransmittable();
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  generator_.SetShouldSendAck(true, false);
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest,
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ShouldSendAckWithFeedback_WritableAndShouldFlush) {
299558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteOnlyNonRetransmittable();
3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_CALL(delegate_, CreateStopWaitingFrame()).WillOnce(
305a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      Return(CreateStopWaitingFrame()));
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_));
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
309a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  generator_.SetShouldSendAck(true, true);
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_feedback_frames = 1;
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  contents.num_stop_waiting_frames = 1;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritable) {
320558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanNotWrite();
321558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
322558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
323558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  EXPECT_TRUE(generator_.HasQueuedFrames());
324558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
325558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
326558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochTEST_F(QuicPacketGeneratorTest, AddControlFrame_OnlyAckWritable) {
327558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteOnlyNonRetransmittable();
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
330868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldNotFlush) {
334558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, AddControlFrame_NotWritableBatchThenFlush) {
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  delegate_.SetCanNotWrite();
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  generator_.StartBatchOperations();
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  generator_.FinishBatchOperations();
3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_));
3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  generator_.FlushAllQueuedFrames();
3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  PacketContents contents;
3554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  contents.num_rst_stream_frames = 1;
3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CheckPacketContains(contents, packet_);
3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, AddControlFrame_WritableAndShouldFlush) {
360558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_));
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
365868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_rst_stream_frames = 1;
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_NotWritable) {
373558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanNotWrite();
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(
3766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, NULL);
3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0u, consumed.bytes_consumed);
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(consumed.fin_consumed);
379868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldNotFlush) {
383558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
386f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(
3876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, NULL);
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3u, consumed.bytes_consumed);
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_WritableAndShouldFlush) {
394558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_));
397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(
3986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kHeadersStreamId, MakeIOVector("foo"), 2, true, MAY_FEC_PROTECT, NULL);
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3u, consumed.bytes_consumed);
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 1;
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest,
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ConsumeDataMultipleTimes_WritableAndShouldNotFlush) {
410558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  generator_.ConsumeData(kHeadersStreamId, MakeIOVector("foo"), 2, true,
4146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         MAY_FEC_PROTECT, NULL);
415f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(
416f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      3, MakeIOVector("quux"), 7, false, MAY_FEC_PROTECT, NULL);
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4u, consumed.bytes_consumed);
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(consumed.fin_consumed);
419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_BatchOperations) {
423558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  generator_.ConsumeData(kHeadersStreamId, MakeIOVector("foo"), 2, true,
4276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         MAY_FEC_PROTECT, NULL);
428f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(
429f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      3, MakeIOVector("quux"), 7, false, MAY_FEC_PROTECT, NULL);
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(4u, consumed.bytes_consumed);
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(consumed.fin_consumed);
432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Now both frames will be flushed out.
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_));
4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.FinishBatchOperations();
437868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 2;
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeDataFEC) {
445558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send FEC every two packets.
448f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  creator_->set_max_packets_per_fec_group(2);
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InSequence dummy;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet_));
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet2_));
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet3_));
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet4_));
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet5_));
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
464f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Send enough data to create 3 packets: two full and one partial. Send
465f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // with MUST_FEC_PROTECT flag.
4660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  size_t data_len = 2 * kDefaultMaxPacketSize + 100;
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed =
468f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      generator_.ConsumeData(3, CreateData(data_len), 0, true,
469f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             MUST_FEC_PROTECT, NULL);
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet_);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet2_);
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketIsFec(packet3_, 1);
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet4_);
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketIsFec(packet5_, 4);
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeDataSendsFecAtEnd) {
483558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
485f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Enable FEC.
486f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  creator_->set_max_packets_per_fec_group(6);
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InSequence dummy;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet_));
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet2_));
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet3_));
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
497f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Send enough data to create 2 packets: one full and one partial. Send
498f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // with MUST_FEC_PROTECT flag.
4990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  size_t data_len = 1 * kDefaultMaxPacketSize + 100;
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed =
501f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      generator_.ConsumeData(3, CreateData(data_len), 0, true,
502f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             MUST_FEC_PROTECT, NULL);
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
505868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet_);
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet2_);
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketIsFec(packet3_, 1);
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, ConsumeData_FramesPreviouslyQueued) {
513d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Set the packet size be enough for two stream frames with 0 stream offset,
514d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // but not enough for a stream frame of 0 offset and one with non-zero offset.
51546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  size_t length =
516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NullEncrypter().GetCiphertextSize(0) +
517f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      GetPacketHeaderSize(creator_->connection_id_length(),
518d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          true,
519f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                          creator_->next_sequence_number_length(),
520d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          NOT_IN_FEC_GROUP) +
521d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // Add an extra 3 bytes for the payload and 1 byte so BytesFree is larger
522d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      // than the GetMinStreamFrameSize.
5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      QuicFramer::GetMinStreamFrameSize(1, 0, false, NOT_IN_FEC_GROUP) + 3 +
5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      QuicFramer::GetMinStreamFrameSize(1, 0, true, NOT_IN_FEC_GROUP) + 1;
525f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  creator_->set_max_packet_length(length);
526d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  delegate_.SetCanWriteAnything();
527d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  {
528d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)     InSequence dummy;
529d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)     EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         SaveArg<0>(&packet_));
531d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)     EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci         SaveArg<0>(&packet2_));
533d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
534d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  generator_.StartBatchOperations();
535d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Queue enough data to prevent a stream frame with a non-zero offset from
536d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // fitting.
537f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(
5386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kHeadersStreamId, MakeIOVector("foo"), 0, false, MAY_FEC_PROTECT, NULL);
539d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(3u, consumed.bytes_consumed);
540d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(consumed.fin_consumed);
541d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
542d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
543d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // This frame will not fit with the existing frame, causing the queued frame
544d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // to be serialized, and it will not fit with another frame like it, so it is
545d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // serialized by itself.
5466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  consumed = generator_.ConsumeData(kHeadersStreamId, MakeIOVector("bar"), 3,
5476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                    true, MAY_FEC_PROTECT, NULL);
548d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(3u, consumed.bytes_consumed);
549d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
550d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
551d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
552d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  PacketContents contents;
553d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  contents.num_stream_frames = 1;
554d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  CheckPacketContains(contents, packet_);
555d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  CheckPacketContains(contents, packet2_);
556d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
557d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, FecGroupSizeOnCongestionWindowChange) {
5595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  delegate_.SetCanWriteAnything();
5605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  creator_->set_max_packets_per_fec_group(50);
5615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(50u, creator_->max_packets_per_fec_group());
5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(creator_->IsFecGroupOpen());
5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // On reduced cwnd.
5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  generator_.OnCongestionWindowChange(7 * kDefaultTCPMSS);
5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(3u, creator_->max_packets_per_fec_group());
5675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // On increased cwnd.
5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  generator_.OnCongestionWindowChange(100 * kDefaultTCPMSS);
5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(50u, creator_->max_packets_per_fec_group());
5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // On collapsed cwnd.
5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  generator_.OnCongestionWindowChange(1 * kDefaultTCPMSS);
5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(2u, creator_->max_packets_per_fec_group());
5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, FecGroupSizeChangeWithOpenGroup) {
5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  delegate_.SetCanWriteAnything();
5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(jri): This starting of batch mode should not be required when
5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // FEC sending is separated from batching operations.
5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  generator_.StartBatchOperations();
5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  creator_->set_max_packets_per_fec_group(50);
5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(50u, creator_->max_packets_per_fec_group());
5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(creator_->IsFecGroupOpen());
5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Send enough data to create 4 packets with MUST_FEC_PROTECT flag.
5875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // 3 packets are sent, one is queued in the creator.
5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  {
5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    InSequence dummy;
5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet_));
5925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet2_));
5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
5951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet3_));
5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  size_t data_len = 3 * kDefaultMaxPacketSize + 1;
5985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(
5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      7, CreateData(data_len), 0, true, MUST_FEC_PROTECT, NULL);
6005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
6015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(creator_->IsFecGroupOpen());
6025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Change FEC groupsize.
6045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  generator_.OnCongestionWindowChange(2 * kDefaultTCPMSS);
6055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(2u, creator_->max_packets_per_fec_group());
6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Send enough data to trigger one unprotected data packet,
6085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // causing the FEC packet to also be sent.
6095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  {
6105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    InSequence dummy;
6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet4_));
6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet5_));
6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
6165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  consumed = generator_.ConsumeData(7, CreateData(kDefaultMaxPacketSize), 0,
6175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                    true, MAY_FEC_PROTECT, NULL);
6185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(kDefaultMaxPacketSize, consumed.bytes_consumed);
6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Verify that one FEC packet was sent.
6205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CheckPacketIsFec(packet5_, /*fec_group=*/1u);
6215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(creator_->IsFecGroupOpen());
6225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(creator_->IsFecProtected());
6235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
6245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
625f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(QuicPacketGeneratorTest, SwitchFecOnOff) {
626f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  delegate_.SetCanWriteAnything();
627f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  creator_->set_max_packets_per_fec_group(2);
628f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(creator_->IsFecProtected());
629f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
630f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Send one unprotected data packet.
631f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
6321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet_));
633f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed =
634f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      generator_.ConsumeData(5, CreateData(1u), 0, true, MAY_FEC_PROTECT,
635f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             NULL);
636f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, consumed.bytes_consumed);
637f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
638f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(creator_->IsFecProtected());
639f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Verify that one data packet was sent.
640f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PacketContents contents;
641f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.num_stream_frames = 1;
642f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketContains(contents, packet_);
643f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
644f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  {
645f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    InSequence dummy;
646f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet2_));
648f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet3_));
650f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
6511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet4_));
652f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
6531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet5_));
654f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
6551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet6_));
656f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
657f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Send enough data to create 3 packets with MUST_FEC_PROTECT flag.
658f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  size_t data_len = 2 * kDefaultMaxPacketSize + 100;
659f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  consumed = generator_.ConsumeData(7, CreateData(data_len), 0, true,
660f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    MUST_FEC_PROTECT, NULL);
661f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
662f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
663f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
664f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Verify that two FEC packets were sent.
665f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet2_);
666f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet3_);
667f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketIsFec(packet4_, /*fec_group=*/2u);
668f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketHasSingleStreamFrame(packet5_);
669f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketIsFec(packet6_, /*fec_group=*/5u);  // Sent at the end of stream.
670f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
671f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Send one unprotected data packet.
672f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
6731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet7_));
674f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  consumed = generator_.ConsumeData(7, CreateData(1u), 0, true,
675f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    MAY_FEC_PROTECT, NULL);
676f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, consumed.bytes_consumed);
677f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
678f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(creator_->IsFecProtected());
679f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Verify that one unprotected data packet was sent.
680f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketContains(contents, packet7_);
681f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
682f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
683f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(QuicPacketGeneratorTest, SwitchFecOnWithPendingFrameInCreator) {
684f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  delegate_.SetCanWriteAnything();
685f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Enable FEC.
686f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  creator_->set_max_packets_per_fec_group(2);
687f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
688f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  generator_.StartBatchOperations();
689f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Queue enough data to prevent a stream frame with a non-zero offset from
690f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // fitting.
691f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(
692f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      7, CreateData(1u), 0, true, MAY_FEC_PROTECT, NULL);
693f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, consumed.bytes_consumed);
694f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->HasPendingFrames());
695f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
696f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Queue protected data for sending. Should cause queued frames to be flushed.
697f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
6981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SaveArg<0>(&packet_));
699f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(creator_->IsFecProtected());
700f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  consumed = generator_.ConsumeData(7, CreateData(1u), 0, true,
701f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    MUST_FEC_PROTECT, NULL);
702f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, consumed.bytes_consumed);
703f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PacketContents contents;
704f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.num_stream_frames = 1;
705f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Transmitted packet was not FEC protected.
706f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketContains(contents, packet_);
707f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->IsFecProtected());
708f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->HasPendingFrames());
709f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
710f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
711f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(QuicPacketGeneratorTest, SwitchFecOnWithPendingFramesInGenerator) {
712f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Enable FEC.
713f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  creator_->set_max_packets_per_fec_group(2);
714f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
715f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Queue control frames in generator.
716f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  delegate_.SetCanNotWrite();
717f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  generator_.SetShouldSendAck(true, true);
718f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  delegate_.SetCanWriteAnything();
719f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  generator_.StartBatchOperations();
720f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
721f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set up frames to write into the creator when control frames are written.
722f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
723f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
724f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      Return(CreateFeedbackFrame()));
725f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(delegate_, CreateStopWaitingFrame()).WillOnce(
726f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      Return(CreateStopWaitingFrame()));
727f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
728f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Generator should have queued control frames, and creator should be empty.
729f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
730f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(creator_->HasPendingFrames());
731f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(creator_->IsFecProtected());
732f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
733f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Queue protected data for sending. Should cause queued frames to be flushed.
734f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
7351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SaveArg<0>(&packet_));
736f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(7, CreateData(1u), 0, true,
737f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                     MUST_FEC_PROTECT, NULL);
738f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, consumed.bytes_consumed);
739f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PacketContents contents;
740f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.num_ack_frames = 1;
741f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.num_feedback_frames = 1;
742f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.num_stop_waiting_frames = 1;
743f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketContains(contents, packet_);
744f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
745f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // FEC protection should be on in creator.
746f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->IsFecProtected());
747f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
748f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
749f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentFramesProtected) {
750f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  delegate_.SetCanWriteAnything();
751f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
752f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Enable FEC.
753f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  creator_->set_max_packets_per_fec_group(2);
754f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(creator_->IsFecProtected());
755f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
756f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Queue stream frame to be protected in creator.
757f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  generator_.StartBatchOperations();
758f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
759f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                     MUST_FEC_PROTECT, NULL);
760f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(1u, consumed.bytes_consumed);
761f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Creator has a pending protected frame.
762f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->HasPendingFrames());
763f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->IsFecProtected());
764f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
765f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Add enough unprotected data to exceed size of current packet, so that
766f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // current packet is sent. Both frames will be sent out in a single packet.
7671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_));
768f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  size_t data_len = kDefaultMaxPacketSize;
769f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true,
770f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    MAY_FEC_PROTECT, NULL);
771f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
772f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PacketContents contents;
773f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.num_stream_frames = 2u;
774f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.fec_group = 1u;
775f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketContains(contents, packet_);
776f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // FEC protection should still be on in creator.
777f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->IsFecProtected());
778f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
779f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
780f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(QuicPacketGeneratorTest, SwitchFecOnOffWithSubsequentPacketsProtected) {
781f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  delegate_.SetCanWriteAnything();
782f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
783f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Enable FEC.
784f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  creator_->set_max_packets_per_fec_group(2);
785f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(creator_->IsFecProtected());
786f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
787f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  generator_.StartBatchOperations();
788f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Send first packet, FEC protected.
7891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_));
790f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Write enough data to cause a packet to be emitted.
791f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  size_t data_len = kDefaultMaxPacketSize;
792f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(
793f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      5, CreateData(data_len), 0, true, MUST_FEC_PROTECT, NULL);
794f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
795f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PacketContents contents;
796f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.num_stream_frames = 1u;
797f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.fec_group = 1u;
798f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketContains(contents, packet_);
799f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
800f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // FEC should still be on in creator.
801f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->IsFecProtected());
802f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
803f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Send enough unprotected data to cause second packet to be sent, which gets
804f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // protected because it happens to fall within an open FEC group. Data packet
805f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // will be followed by FEC packet.
806f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  {
807f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    InSequence dummy;
808f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
8091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet2_));
810f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
8111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet3_));
812f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
813f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true,
814f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    MAY_FEC_PROTECT, NULL);
815f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
816f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.num_stream_frames = 2u;
817f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketContains(contents, packet2_);
818f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketIsFec(packet3_, /*fec_group=*/1u);
819f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
820f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // FEC protection should be off in creator.
821f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(creator_->IsFecProtected());
822f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
823f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
824f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)TEST_F(QuicPacketGeneratorTest, SwitchFecOnOffThenOnWithCreatorProtectionOn) {
825f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  delegate_.SetCanWriteAnything();
826f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  generator_.StartBatchOperations();
827f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
828f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Enable FEC.
829f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  creator_->set_max_packets_per_fec_group(2);
830f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_FALSE(creator_->IsFecProtected());
831f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
832f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Queue one byte of FEC protected data.
833f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  QuicConsumedData consumed = generator_.ConsumeData(5, CreateData(1u), 0, true,
834f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                                     MUST_FEC_PROTECT, NULL);
835f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->HasPendingFrames());
836f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
837f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Add more unprotected data causing first packet to be sent, FEC protected.
838f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
8391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SaveArg<0>(&packet_));
840f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  size_t data_len = kDefaultMaxPacketSize;
841f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true,
842f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    MAY_FEC_PROTECT, NULL);
843f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
844f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PacketContents contents;
845f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.num_stream_frames = 2u;
846f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  contents.fec_group = 1u;
847f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketContains(contents, packet_);
848f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
849f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // FEC group is still open in creator.
850f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->IsFecProtected());
851f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
852f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Add data that should be protected, large enough to cause second packet to
853f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // be sent. Data packet should be followed by FEC packet.
854f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  {
855f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    InSequence dummy;
856f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
8571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet2_));
858f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
8591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet3_));
860f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
861f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  consumed = generator_.ConsumeData(5, CreateData(data_len), 0, true,
862f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                    MUST_FEC_PROTECT, NULL);
863f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
864f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketContains(contents, packet2_);
865f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CheckPacketIsFec(packet3_, /*fec_group=*/1u);
866f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
867f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // FEC protection should remain on in creator.
868f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_TRUE(creator_->IsFecProtected());
869f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
870f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
8712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations) {
872558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanNotWrite();
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
874a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  generator_.SetShouldSendAck(true, false);
8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
876868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
878558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // When the first write operation is invoked, the ack and feedback
8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frames will be returned.
8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send some data and a control frame
889f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  generator_.ConsumeData(3, MakeIOVector("quux"), 7, false,
890f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                         MAY_FEC_PROTECT, NULL);
8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));
8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // All five frames will be flushed out in a single packet.
8941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(SaveArg<0>(&packet_));
8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.FinishBatchOperations();
896868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_goaway_frames = 1;
9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_feedback_frames = 1;
9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_rst_stream_frames = 1;
9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 1;
9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(QuicPacketGeneratorTest, NotWritableThenBatchOperations2) {
908558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanNotWrite();
9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
910a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  generator_.SetShouldSendAck(true, false);
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateRstStreamFrame()));
912868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_TRUE(generator_.HasQueuedFrames());
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
914558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  delegate_.SetCanWriteAnything();
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.StartBatchOperations();
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // When the first write operation is invoked, the ack and feedback
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frames will be returned.
9202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateAckFrame()).WillOnce(Return(CreateAckFrame()));
9212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_CALL(delegate_, CreateFeedbackFrame()).WillOnce(
9222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Return(CreateFeedbackFrame()));
9232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  {
9252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InSequence dummy;
9261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // All five frames will be flushed out in a single packet
9271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
9281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet_));
9291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_CALL(delegate_, OnSerializedPacket(_)).WillOnce(
9301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        SaveArg<0>(&packet2_));
9312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
9322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Send enough data to exceed one packet
9340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  size_t data_len = kDefaultMaxPacketSize + 100;
9352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  QuicConsumedData consumed =
936f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      generator_.ConsumeData(3, CreateData(data_len), 0, true,
937f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                             MAY_FEC_PROTECT, NULL);
9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(data_len, consumed.bytes_consumed);
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(consumed.fin_consumed);
9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.AddControlFrame(QuicFrame(CreateGoAwayFrame()));
9412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  generator_.FinishBatchOperations();
943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EXPECT_FALSE(generator_.HasQueuedFrames());
9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The first packet should have the queued data and part of the stream data.
9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents;
9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_ack_frames = 1;
9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_feedback_frames = 1;
9492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_rst_stream_frames = 1;
9502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents.num_stream_frames = 1;
9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents, packet_);
9522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The second should have the remainder of the stream data.
9542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PacketContents contents2;
9552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents2.num_goaway_frames = 1;
9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  contents2.num_stream_frames = 1;
9572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CheckPacketContains(contents2, packet2_);
9582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace test
9612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace net
962