After receiving a packet in QuicConnection, do not schedule a send alarm unless
- There is data to send immediately, or
- There is data to send after a delay specified by the pacer.

Protected by quic_reloadable_flag_quic_no_send_alarm_unless_necessary.

PiperOrigin-RevId: 556886175
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index e394d5c..daa49b3 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -689,7 +689,9 @@
     EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber());
     EXPECT_CALL(*send_algorithm_, GetCongestionControlType())
         .Times(AnyNumber());
-    EXPECT_CALL(visitor_, WillingAndAbleToWrite()).Times(AnyNumber());
+    EXPECT_CALL(visitor_, WillingAndAbleToWrite())
+        .WillRepeatedly(
+            Invoke(&notifier_, &SimpleSessionNotifier::WillingToWrite));
     EXPECT_CALL(visitor_, OnPacketDecrypted(_)).Times(AnyNumber());
     EXPECT_CALL(visitor_, OnCanWrite())
         .WillRepeatedly(Invoke(&notifier_, &SimpleSessionNotifier::OnCanWrite));
@@ -1520,6 +1522,18 @@
         QuicConnectionPeer::GetReceivedServerPreferredAddress(&connection_));
   }
 
+  // If defer sending is enabled, tell |visitor_| to return true on the next
+  // call to WillingAndAbleToWrite().
+  // This function can be used before a call to ProcessXxxPacket, to allow the
+  // process function to schedule and fire the send alarm at the end.
+  void ForceWillingAndAbleToWriteOnceForDeferSending() {
+    if (GetParam().ack_response == AckResponse::kDefer) {
+      EXPECT_CALL(visitor_, WillingAndAbleToWrite())
+          .WillOnce(Return(true))
+          .RetiresOnSaturation();
+    }
+  }
+
   void TestClientRetryHandling(bool invalid_retry_tag,
                                bool missing_original_id_in_config,
                                bool wrong_original_id_in_config,
@@ -1849,7 +1863,7 @@
               OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
       .Times(0);
   // Do not propagate OnCanWrite() to session notifier.
-  EXPECT_CALL(visitor_, OnCanWrite()).Times(AtLeast(1u));
+  EXPECT_CALL(visitor_, OnCanWrite()).Times(AnyNumber());
 
   QuicFrames frames2;
   frames2.push_back(QuicFrame(frame2_));
@@ -1981,7 +1995,7 @@
   peer_creator_.SetServerConnectionId(server_cid1);
   EXPECT_CALL(visitor_, OnConnectionMigration(IPV6_TO_IPV4_CHANGE)).Times(1);
   // Do not propagate OnCanWrite() to session notifier.
-  EXPECT_CALL(visitor_, OnCanWrite()).Times(testing::AtMost(1u));
+  EXPECT_CALL(visitor_, OnCanWrite()).Times(AnyNumber());
 
   QuicFrames frames2;
   frames2.push_back(QuicFrame(frame2_));
@@ -3657,7 +3671,7 @@
   QuicAckFrame frame2 = InitAckFrame(2);
   ProcessAckPacket(&frame2);
 
-  EXPECT_CALL(visitor_, OnCanWrite());
+  EXPECT_CALL(visitor_, OnCanWrite()).Times(AnyNumber());
   ProcessAckPacket(&frame1);
 }
 
@@ -3951,6 +3965,7 @@
   SetDecrypter(
       ENCRYPTION_FORWARD_SECURE,
       std::make_unique<StrictTaggingDecrypter>(ENCRYPTION_FORWARD_SECURE));
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessDataPacket(2);
 
   EXPECT_EQ(0u, connection_.NumQueuedPackets());
@@ -4529,6 +4544,7 @@
   size_t encrypted_length =
       peer_framer_.EncryptPayload(level, QuicPacketNumber(received_packet_num),
                                   *packet, buffer, kMaxOutgoingPacketSize);
+  EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true));
   connection_.ProcessUdpPacket(
       kSelfAddress, kPeerAddress,
       QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
@@ -6501,6 +6517,7 @@
   } else {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
   }
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
   // Check that ack is sent and that delayed ack alarm is reset.
   EXPECT_EQ(3u, writer_->frame_count());
@@ -6539,6 +6556,7 @@
           .WillOnce(IgnoreResult(InvokeWithoutArgs(
               &connection_, &TestConnection::SendCryptoStreamData)));
     }
+    ForceWillingAndAbleToWriteOnceForDeferSending();
     ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
   }
   // Check that ack is sent and that delayed ack alarm is reset.
@@ -6596,6 +6614,7 @@
   EXPECT_CALL(visitor_, OnCanWrite())
       .WillOnce(IgnoreResult(InvokeWithoutArgs(
           &connection_, &TestConnection::EnsureWritableAndSendStreamData5)));
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessAckPacket(&ack);
 
   // Check that ack is bundled with outgoing data and the delayed ack
@@ -9625,6 +9644,7 @@
 
   // Receives packet 1.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
 
   const size_t anti_amplification_factor =
@@ -9644,6 +9664,7 @@
 
   // Receives packet 2.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
   // Verify more packets can be sent.
   for (size_t i = anti_amplification_factor + 1;
@@ -9657,6 +9678,7 @@
                                        2 * anti_amplification_factor * 3);
 
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessPacket(3);
   // Verify anti-amplification limit is gone after address validation.
   for (size_t i = 0; i < 100; ++i) {
@@ -9695,6 +9717,7 @@
 
   // Receives packet 1.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
 
   const size_t anti_amplification_factor = 3;
@@ -9713,6 +9736,7 @@
 
   // Receives packet 2.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
   // Verify more packets can be sent.
   for (size_t i = anti_amplification_factor + 1;
@@ -9726,6 +9750,7 @@
                                        2 * anti_amplification_factor * 3);
 
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessPacket(3);
   // Verify anti-amplification limit is gone after address validation.
   for (size_t i = 0; i < 100; ++i) {
@@ -9764,6 +9789,7 @@
 
   // Receives packet 1.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
 
   const size_t anti_amplification_factor = 10;
@@ -9782,6 +9808,7 @@
 
   // Receives packet 2.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
   // Verify more packets can be sent.
   for (size_t i = anti_amplification_factor + 1;
@@ -9795,6 +9822,7 @@
                                        2 * anti_amplification_factor * 3);
 
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessPacket(3);
   // Verify anti-amplification limit is gone after address validation.
   for (size_t i = 0; i < 100; ++i) {
@@ -16039,6 +16067,7 @@
   EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(1);
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
       .Times(anti_amplification_factor);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
   ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
   connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
                            std::make_unique<TaggingEncrypter>(0x02));