Drop SCONE packet specifically in QUIC end-to-end packet loss test.

In EndToEndTest.SconeProtocolServerToClientAsynchronousWithPacketLoss, when asynchronous handshake processing takes longer than the ACK delay (such as on slower or emulated architectures like riscv64), the server may emit an intermediate ACK-only packet before the ServerHello containing the SCONE report.

Previously, the test writer dropped the first server packet indiscriminately via set_fake_drop_first_n_packets(1). In the delayed handshake scenario, this dropped the intermediate ACK rather than the SCONE packet, allowing the SCONE packet to reach the client and failing the zero-bandwidth assertion.

Update SconePacketWriter to track and drop SCONE packets specifically so that the test reliably verifies SCONE packet loss handling regardless of handshake execution timing.

PiperOrigin-RevId: 1002091548
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
index 88a0fea..740ffc9 100644
--- a/quiche/quic/core/http/end_to_end_test.cc
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -4880,18 +4880,28 @@
     char new_buffer[kMaxOutgoingPacketSize];
     int next_scone_index =
         (last_report_index_.value_or(-1) + 1) % kMaxSconeReports;
-    if (!MaybeUpdateSconePacket(buffer, new_buffer, buf_len,
-                                kReportedValues[next_scone_index].first)) {
+    bool is_scone = MaybeUpdateSconePacket(
+        buffer, new_buffer, buf_len, kReportedValues[next_scone_index].first);
+    if (!is_scone) {
       return PacketDroppingTestWriter::WritePacket(
           buffer, buf_len, self_address, peer_address, options, params);
     }
     last_report_index_ = next_scone_index;
+    if (fake_drop_first_n_scone_packets_ > 0) {
+      --fake_drop_first_n_scone_packets_;
+      return WriteResult(WRITE_STATUS_OK, buf_len);
+    }
     // We have observed the SCONE indicator for this flow, so we can write
     // bandwidth values into it.
     return PacketDroppingTestWriter::WritePacket(
         new_buffer, buf_len, self_address, peer_address, options, params);
   }
 
+  void set_fake_drop_first_n_scone_packets(
+      int32_t fake_drop_first_n_scone_packets) {
+    fake_drop_first_n_scone_packets_ = fake_drop_first_n_scone_packets;
+  }
+
   std::optional<QuicBandwidth> last_bandwidth_report() const {
     if (!last_report_index_.has_value()) {
       return std::nullopt;
@@ -4916,6 +4926,7 @@
 
   // If nullopt, no packet has been processed by the writer.
   std::optional<bool> saw_scone_indicator_;
+  int32_t fake_drop_first_n_scone_packets_ = 0;
 };
 
 class SconeServerTrackingSession : public QuicSimpleServerSession {
@@ -5117,9 +5128,9 @@
   server_writer_ = new SconePacketWriter();
   delete client_writer_;
   client_writer_ = new SconePacketWriter();
-  // Drop the first server packet.
+  // Drop the first server SCONE packet.
   absl::down_cast<SconePacketWriter*>(server_writer_)
-      ->set_fake_drop_first_n_packets(1);
+      ->set_fake_drop_first_n_scone_packets(1);
 
   ASSERT_TRUE(Initialize());
   EXPECT_TRUE(client_->client()->WaitForOneRttKeysAvailable());