| Index: net/quic/quic_connection_test.cc
|
| diff --git a/net/quic/quic_connection_test.cc b/net/quic/quic_connection_test.cc
|
| index 4e58dfdefee0bdd3a08cd2ca5256325d53d503e6..ede61c8a98dc8aaec975c0470b680bef2bad7826 100644
|
| --- a/net/quic/quic_connection_test.cc
|
| +++ b/net/quic/quic_connection_test.cc
|
| @@ -67,7 +67,7 @@ class TestReceiveAlgorithm : public ReceiveAlgorithmInterface {
|
| }
|
|
|
| bool GenerateCongestionFeedback(
|
| - QuicCongestionFeedbackFrame* congestion_feedback) {
|
| + QuicCongestionFeedbackFrame* congestion_feedback) override {
|
| if (feedback_ == nullptr) {
|
| return false;
|
| }
|
| @@ -95,6 +95,7 @@ class TaggingEncrypter : public QuicEncrypter {
|
|
|
| // QuicEncrypter interface.
|
| bool SetKey(StringPiece key) override { return true; }
|
| +
|
| bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; }
|
|
|
| bool Encrypt(StringPiece nonce,
|
| @@ -149,6 +150,7 @@ class TaggingDecrypter : public QuicDecrypter {
|
|
|
| // QuicDecrypter interface
|
| bool SetKey(StringPiece key) override { return true; }
|
| +
|
| bool SetNoncePrefix(StringPiece nonce_prefix) override { return true; }
|
|
|
| bool Decrypt(StringPiece nonce,
|
| @@ -258,7 +260,7 @@ class TestConnectionHelper : public QuicConnectionHelperInterface {
|
|
|
| class TestPacketWriter : public QuicPacketWriter {
|
| public:
|
| - explicit TestPacketWriter(QuicVersion version)
|
| + TestPacketWriter(QuicVersion version, MockClock *clock)
|
| : version_(version),
|
| framer_(SupportedVersions(version_)),
|
| last_packet_size_(0),
|
| @@ -268,7 +270,9 @@ class TestPacketWriter : public QuicPacketWriter {
|
| final_bytes_of_last_packet_(0),
|
| final_bytes_of_previous_packet_(0),
|
| use_tagging_decrypter_(false),
|
| - packets_write_attempts_(0) {
|
| + packets_write_attempts_(0),
|
| + clock_(clock),
|
| + write_pause_time_delta_(QuicTime::Delta::Zero()) {
|
| }
|
|
|
| // QuicPacketWriter interface
|
| @@ -297,6 +301,10 @@ class TestPacketWriter : public QuicPacketWriter {
|
| return WriteResult(WRITE_STATUS_BLOCKED, -1);
|
| }
|
| last_packet_size_ = packet.length();
|
| +
|
| + if (!write_pause_time_delta_.IsZero()) {
|
| + clock_->AdvanceTime(write_pause_time_delta_);
|
| + }
|
| return WriteResult(WRITE_STATUS_OK, last_packet_size_);
|
| }
|
|
|
| @@ -310,6 +318,11 @@ class TestPacketWriter : public QuicPacketWriter {
|
|
|
| void BlockOnNextWrite() { block_on_next_write_ = true; }
|
|
|
| + // Sets the amount of time that the writer should before the actual write.
|
| + void SetWritePauseTimeDelta(QuicTime::Delta delta) {
|
| + write_pause_time_delta_ = delta;
|
| + }
|
| +
|
| const QuicPacketHeader& header() { return framer_.header(); }
|
|
|
| size_t frame_count() const { return framer_.num_frames(); }
|
| @@ -390,6 +403,10 @@ class TestPacketWriter : public QuicPacketWriter {
|
| uint32 final_bytes_of_previous_packet_;
|
| bool use_tagging_decrypter_;
|
| uint32 packets_write_attempts_;
|
| + MockClock *clock_;
|
| + // If non-zero, the clock will pause during WritePacket for this amount of
|
| + // time.
|
| + QuicTime::Delta write_pause_time_delta_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(TestPacketWriter);
|
| };
|
| @@ -597,7 +614,7 @@ class MockPacketWriterFactory : public QuicConnection::PacketWriterFactory {
|
| MockPacketWriterFactory(QuicPacketWriter* writer) {
|
| ON_CALL(*this, Create(_)).WillByDefault(Return(writer));
|
| }
|
| - virtual ~MockPacketWriterFactory() {}
|
| + ~MockPacketWriterFactory() override {}
|
|
|
| MOCK_CONST_METHOD1(Create, QuicPacketWriter*(QuicConnection* connection));
|
| };
|
| @@ -611,7 +628,7 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
|
| send_algorithm_(new StrictMock<MockSendAlgorithm>),
|
| loss_algorithm_(new MockLossAlgorithm()),
|
| helper_(new TestConnectionHelper(&clock_, &random_generator_)),
|
| - writer_(new TestPacketWriter(version())),
|
| + writer_(new TestPacketWriter(version(), &clock_)),
|
| factory_(writer_.get()),
|
| connection_(connection_id_, IPEndPoint(), helper_.get(),
|
| factory_, false, version()),
|
| @@ -974,6 +991,10 @@ class QuicConnectionTest : public ::testing::TestWithParam<QuicVersion> {
|
| EXPECT_CALL(visitor_, OnWriteBlocked()).Times(AtLeast(1));
|
| }
|
|
|
| + void SetWritePauseTimeDelta(QuicTime::Delta delta) {
|
| + writer_->SetWritePauseTimeDelta(delta);
|
| + }
|
| +
|
| void CongestionBlockWrites() {
|
| EXPECT_CALL(*send_algorithm_,
|
| TimeUntilSend(_, _, _)).WillRepeatedly(
|
| @@ -1548,6 +1569,74 @@ TEST_P(QuicConnectionTest, BasicSending) {
|
| EXPECT_EQ(7u, least_unacked());
|
| }
|
|
|
| +// If FLAGS_quic_record_send_time_before_write is disabled, QuicConnection
|
| +// should record the packet sen-tdime after the packet is sent.
|
| +TEST_P(QuicConnectionTest, RecordSentTimeAfterPacketSent) {
|
| + ValueRestore<bool> old_flag(&FLAGS_quic_record_send_time_before_write, false);
|
| + // We're using a MockClock for the tests, so we have complete control over the
|
| + // time.
|
| + // Our recorded timestamp for the last packet sent time will be passed in to
|
| + // the send_algorithm. Make sure that it is set to the correct value.
|
| + QuicTime actual_recorded_send_time = QuicTime::Zero();
|
| + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
|
| + .WillOnce(DoAll(SaveArg<0>(&actual_recorded_send_time), Return(true)));
|
| +
|
| + // First send without any pause and check the result.
|
| + QuicTime expected_recorded_send_time = clock_.Now();
|
| + connection_.SendStreamDataWithString(1, "foo", 0, !kFin, nullptr);
|
| + EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
|
| + << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
|
| + << ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
|
| +
|
| + // Now pause during the write, and check the results.
|
| + actual_recorded_send_time = QuicTime::Zero();
|
| + const QuicTime::Delta kWritePauseTimeDelta =
|
| + QuicTime::Delta::FromMilliseconds(5000);
|
| + SetWritePauseTimeDelta(kWritePauseTimeDelta);
|
| + expected_recorded_send_time = clock_.Now().Add(kWritePauseTimeDelta);
|
| +
|
| + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
|
| + .WillOnce(DoAll(SaveArg<0>(&actual_recorded_send_time), Return(true)));
|
| + connection_.SendStreamDataWithString(2, "baz", 0, !kFin, nullptr);
|
| + EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
|
| + << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
|
| + << ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
|
| +}
|
| +
|
| +// If FLAGS_quic_record_send_time_before_write is enabled, QuicConnection should
|
| +// record the the packet sent-time prior to sending the packet.
|
| +TEST_P(QuicConnectionTest, RecordSentTimeBeforePacketSent) {
|
| + ValueRestore<bool> old_flag(&FLAGS_quic_record_send_time_before_write, true);
|
| + // We're using a MockClock for the tests, so we have complete control over the
|
| + // time.
|
| + // Our recorded timestamp for the last packet sent time will be passed in to
|
| + // the send_algorithm. Make sure that it is set to the correct value.
|
| + QuicTime actual_recorded_send_time = QuicTime::Zero();
|
| + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
|
| + .WillOnce(DoAll(SaveArg<0>(&actual_recorded_send_time), Return(true)));
|
| +
|
| + // First send without any pause and check the result.
|
| + QuicTime expected_recorded_send_time = clock_.Now();
|
| + connection_.SendStreamDataWithString(1, "foo", 0, !kFin, nullptr);
|
| + EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
|
| + << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
|
| + << ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
|
| +
|
| + // Now pause during the write, and check the results.
|
| + actual_recorded_send_time = QuicTime::Zero();
|
| + const QuicTime::Delta kWritePauseTimeDelta =
|
| + QuicTime::Delta::FromMilliseconds(5000);
|
| + SetWritePauseTimeDelta(kWritePauseTimeDelta);
|
| + expected_recorded_send_time = clock_.Now();
|
| +
|
| + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
|
| + .WillOnce(DoAll(SaveArg<0>(&actual_recorded_send_time), Return(true)));
|
| + connection_.SendStreamDataWithString(2, "baz", 0, !kFin, nullptr);
|
| + EXPECT_EQ(expected_recorded_send_time, actual_recorded_send_time)
|
| + << "Expected time = " << expected_recorded_send_time.ToDebuggingValue()
|
| + << ". Actual time = " << actual_recorded_send_time.ToDebuggingValue();
|
| +}
|
| +
|
| TEST_P(QuicConnectionTest, FECSending) {
|
| // All packets carry version info till version is negotiated.
|
| QuicPacketCreator* creator =
|
| @@ -1565,7 +1654,8 @@ TEST_P(QuicConnectionTest, FECSending) {
|
| creator->set_max_packet_length(length);
|
|
|
| // Send 4 protected data packets, which should also trigger 1 FEC packet.
|
| - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(5);
|
| + EXPECT_CALL(*send_algorithm_,
|
| + OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(5);
|
| // The first stream frame will have 2 fewer overhead bytes than the other 3.
|
| const string payload(payload_length * 4 + 2, 'a');
|
| connection_.SendStreamDataWithStringWithFec(1, payload, 0, !kFin, nullptr);
|
| @@ -1601,7 +1691,8 @@ TEST_P(QuicConnectionTest, AbandonFECFromCongestionWindow) {
|
| &connection_)->IsFecEnabled());
|
|
|
| // 1 Data and 1 FEC packet.
|
| - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(2);
|
| + EXPECT_CALL(*send_algorithm_,
|
| + OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(2);
|
| connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
|
|
|
| const QuicTime::Delta retransmission_time =
|
| @@ -1620,8 +1711,9 @@ TEST_P(QuicConnectionTest, DontAbandonAckedFEC) {
|
| EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
|
| &connection_)->IsFecEnabled());
|
|
|
| - // 1 Data and 1 FEC packet.
|
| - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
|
| + // 3 Data and 3 FEC packets.
|
| + EXPECT_CALL(*send_algorithm_,
|
| + OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(6);
|
| connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
|
| // Send some more data afterwards to ensure early retransmit doesn't trigger.
|
| connection_.SendStreamDataWithStringWithFec(3, "foo", 3, !kFin, nullptr);
|
| @@ -1648,8 +1740,9 @@ TEST_P(QuicConnectionTest, AbandonAllFEC) {
|
| EXPECT_TRUE(QuicConnectionPeer::GetPacketCreator(
|
| &connection_)->IsFecEnabled());
|
|
|
| - // 1 Data and 1 FEC packet.
|
| - EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(6);
|
| + // 3 Data and 3 FEC packet.
|
| + EXPECT_CALL(*send_algorithm_,
|
| + OnPacketSent(_, _, _, _, HAS_RETRANSMITTABLE_DATA)).Times(6);
|
| connection_.SendStreamDataWithStringWithFec(3, "foo", 0, !kFin, nullptr);
|
| // Send some more data afterwards to ensure early retransmit doesn't trigger.
|
| connection_.SendStreamDataWithStringWithFec(3, "foo", 3, !kFin, nullptr);
|
| @@ -3070,22 +3163,25 @@ TEST_P(QuicConnectionTest, SendDelayedAck) {
|
| EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
|
| }
|
|
|
| -TEST_P(QuicConnectionTest, SendEarlyDelayedAckForCrypto) {
|
| - QuicTime ack_time = clock_.ApproximateNow();
|
| +TEST_P(QuicConnectionTest, SendDelayedAckOnHandshakeConfirmed) {
|
| EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
|
| - EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
|
| - // Process a packet from the crypto stream, which is frame1_'s default.
|
| ProcessPacket(1);
|
| - // Check if delayed ack timer is running for the expected interval.
|
| + // Check that ack is sent and that delayed ack alarm is set.
|
| + EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
|
| + QuicTime ack_time = clock_.ApproximateNow().Add(DefaultDelayedAckTime());
|
| + EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
|
| +
|
| + // Completing the handshake as the server does nothing.
|
| + QuicConnectionPeer::SetIsServer(&connection_, true);
|
| + connection_.OnHandshakeComplete();
|
| EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
|
| EXPECT_EQ(ack_time, connection_.GetAckAlarm()->deadline());
|
| - // Simulate delayed ack alarm firing.
|
| - connection_.GetAckAlarm()->Fire();
|
| - // Check that ack is sent and that delayed ack alarm is reset.
|
| - EXPECT_EQ(2u, writer_->frame_count());
|
| - EXPECT_FALSE(writer_->stop_waiting_frames().empty());
|
| - EXPECT_FALSE(writer_->ack_frames().empty());
|
| - EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
|
| +
|
| + // Complete the handshake as the client decreases the delayed ack time to 0ms.
|
| + QuicConnectionPeer::SetIsServer(&connection_, false);
|
| + connection_.OnHandshakeComplete();
|
| + EXPECT_TRUE(connection_.GetAckAlarm()->IsSet());
|
| + EXPECT_EQ(clock_.ApproximateNow(), connection_.GetAckAlarm()->deadline());
|
| }
|
|
|
| TEST_P(QuicConnectionTest, SendDelayedAckOnSecondPacket) {
|
|
|