Speed up the slow e2e test TestInvalidAckBeforeHandshakeClosesConnection

It turns out that this test was trying to make a connection after setting packet loss to 100%, which meant we waited the full 30-second timeout.

Now, we just let it create a dummy connection so we can steal its writer, which we use to write the invalid ACK frame. The test succeeds in 5 seconds on my machine instead of >30.

PiperOrigin-RevId: 843859547
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
index 51ef42f..eac0da8 100644
--- a/quiche/quic/core/http/end_to_end_test.cc
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -18,6 +18,7 @@
 #include <utility>
 #include <vector>
 
+
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
 #include "absl/synchronization/notification.h"
@@ -35,6 +36,8 @@
 #include "quiche/quic/core/crypto/transport_parameters.h"
 #include "quiche/quic/core/frames/quic_blocked_frame.h"
 #include "quiche/quic/core/frames/quic_crypto_frame.h"
+#include "quiche/quic/core/frames/quic_frame.h"
+#include "quiche/quic/core/frames/quic_padding_frame.h"
 #include "quiche/quic/core/frames/quic_ping_frame.h"
 #include "quiche/quic/core/frames/quic_window_update_frame.h"
 #include "quiche/quic/core/http/http_constants.h"
@@ -66,6 +69,7 @@
 #include "quiche/quic/core/quic_packet_writer.h"
 #include "quiche/quic/core/quic_packet_writer_wrapper.h"
 #include "quiche/quic/core/quic_packets.h"
+#include "quiche/quic/core/quic_path_validator.h"
 #include "quiche/quic/core/quic_session.h"
 #include "quiche/quic/core/quic_stream.h"
 #include "quiche/quic/core/quic_tag.h"
@@ -1576,34 +1580,24 @@
 }
 
 TEST_P(EndToEndTest, TestInvalidAckBeforeHandshakeClosesConnection) {
+  ASSERT_TRUE(Initialize());
   if (!version_.IsIetfQuic()) {
-    ASSERT_TRUE(Initialize());
-    return;
-  }
-  if (!version_.IsIetfQuic()) {
-    ASSERT_TRUE(Initialize());
     return;
   }
   SetQuicRestartFlag(quic_dispatcher_close_connection_on_invalid_ack, true);
-  connect_to_server_on_initialize_ = false;
-  ASSERT_TRUE(Initialize());
 
-  // Create client without connecting.
-  client_writer_->set_fake_packet_loss_percentage(100);
-  client_.reset(CreateQuicClient(client_writer_));
-  client_->client()->Initialize();
+  // We've created this dummy connection for the sole purpose of borrowing its
+  // packet writer.
+  QuicConnection* dummy_client_connection = GetClientConnection();
+  ASSERT_TRUE(dummy_client_connection);
 
-  QuicConnection* client_connection = GetClientConnection();
-  ASSERT_TRUE(client_connection);
-  client_writer_->Initialize(
-      QuicConnectionPeer::GetHelper(client_connection),
-      QuicConnectionPeer::GetAlarmFactory(client_connection),
-      std::make_unique<ClientDelegate>(client_->client()));
-
-  // Generate connection IDs for the crafted packet. Since the client hasn't
-  // connected yet, these are effectively new, random IDs.
-  QuicConnectionId server_connection_id = TestConnectionId(1);
-  QuicConnectionId client_connection_id = TestConnectionId(2);
+  // When we send an invalid ACK frame, it should be associated with a fresh
+  // connection ID, not the dummy connection's ID.
+  QuicConnectionId server_connection_id(
+      dummy_client_connection->connection_id());
+  EXPECT_GT(server_connection_id.length(), 0u);
+  server_connection_id.mutable_data()[0] ^= 1;
+  ASSERT_NE(server_connection_id, dummy_client_connection->connection_id());
 
   // Manually craft and send an INITIAL packet with an invalid ACK frame.
   QuicFrames frames;
@@ -1617,18 +1611,23 @@
   DeleteFrames(&frames);
   ASSERT_TRUE(packet);
 
-  client_writer_->writer()->WritePacket(
+  // The server should see this as an invalid ACK and add the connection ID to a
+  // time-wait list.
+  const WriteResult write_result = client_writer_->writer()->WritePacket(
       packet->data(), packet->length(),
       client_->client()->network_helper()->GetLatestClientAddress().host(),
       server_address_, nullptr, packet_writer_params_);
+  EXPECT_EQ(write_result.status, WRITE_STATUS_OK);
 
-  // The server should see this as an invalid ACK and add the connection ID to a
-  // time-wait list. Subsequent connection attempts with the same connection ID
-  // should fail.
-  client_->UseConnectionId(server_connection_id);
-  client_->Connect();
-  EXPECT_FALSE(client_->connected());
-  EXPECT_THAT(client_->connection_error(),
+  // Subsequent connection attempts with the same connection ID should fail.
+  std::unique_ptr<QuicTestClient> client2(
+      CreateQuicClient(nullptr, /*connect=*/false));
+  client2->UseConnectionId(server_connection_id);
+  client2->Connect();
+  client2->WaitForWriteToFlush();
+  client2->WaitForResponse();
+  EXPECT_FALSE(client2->connected());
+  EXPECT_THAT(client2->connection_error(),
               IsError(IETF_QUIC_PROTOCOL_VIOLATION));
 }