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)); }