Prevent infinite loops in QUIC e2e test In some failure cases, our e2e test could get itself into an infinite loop, causing it to wait 5 minutes for the overall test timeout. That makes debugging incredibly painful. This CL tweaks our code to fail earlier allowing us to avoid more timeouts. Test-only change PiperOrigin-RevId: 319314922 Change-Id: Ibe90e26500db95201818c6a40c5b819d3c44cae8
diff --git a/quic/core/http/end_to_end_test.cc b/quic/core/http/end_to_end_test.cc index 02e1c66..0888a0e 100644 --- a/quic/core/http/end_to_end_test.cc +++ b/quic/core/http/end_to_end_test.cc
@@ -1239,7 +1239,7 @@ while (kNumRequests > client_->num_responses()) { client_->ClearPerRequestState(); - WaitForFooResponseAndCheckIt(); + ASSERT_TRUE(WaitForFooResponseAndCheckIt()); } } @@ -2171,7 +2171,8 @@ // WaitForEvents waits 50ms and returns true if there are outstanding // requests. - while (client_->client()->WaitForEvents() == true) { + while (client_->client()->WaitForEvents()) { + ASSERT_TRUE(client_->connected()); } } @@ -2196,7 +2197,8 @@ // WaitForEvents waits 50ms and returns true if there are outstanding // requests. - while (client_->client()->WaitForEvents() == true) { + while (client_->client()->WaitForEvents()) { + ASSERT_TRUE(client_->connected()); } // It should be completely fine to RST a stream before any data has been // received for that stream. @@ -2509,6 +2511,7 @@ // is sent in the first packet on the control stream. while (!QuicSpdySessionPeer::GetReceiveControlStream(client_session)) { client_->client()->WaitForEvents(); + ASSERT_TRUE(client_->connected()); } } @@ -2516,6 +2519,7 @@ // (and the ack received by the client). while (client_session->HasUnackedStreamData()) { client_->client()->WaitForEvents(); + ASSERT_TRUE(client_->connected()); } server_thread_->Pause(); @@ -2675,21 +2679,22 @@ while (true) { // Waits for up to 50 ms. client_->client()->WaitForEvents(); + ASSERT_TRUE(client_->connected()); QuicSpdyClientSession* client_session = GetClientSession(); if (client_session == nullptr) { ADD_FAILURE() << "Missing client session"; - break; + return; } QpackEncoder* qpack_encoder = client_session->qpack_encoder(); if (qpack_encoder == nullptr) { ADD_FAILURE() << "Missing QPACK encoder"; - break; + return; } QpackHeaderTable* header_table = QpackEncoderPeer::header_table(qpack_encoder); if (header_table == nullptr) { ADD_FAILURE() << "Missing header table"; - break; + return; } if (QpackHeaderTablePeer::dynamic_table_capacity(header_table) > 0) { break; @@ -2749,6 +2754,7 @@ while (ack_listener->total_bytes_acked() < expected_bytes_acked) { // Waits for up to 50 ms. client_->client()->WaitForEvents(); + ASSERT_TRUE(client_->connected()); } EXPECT_EQ(ack_listener->total_bytes_acked(), expected_bytes_acked) << " header_size " << header_size << " request length " @@ -3584,6 +3590,7 @@ // Because of priority, the first response arrived should be to original // request. client_->WaitForResponse(); + ASSERT_TRUE(client_->connected()); } // Check server session to see if it has max number of outgoing streams opened
diff --git a/quic/test_tools/quic_test_client.cc b/quic/test_tools/quic_test_client.cc index f876532..c25bd8e 100644 --- a/quic/test_tools/quic_test_client.cc +++ b/quic/test_tools/quic_test_client.cc
@@ -636,7 +636,10 @@ } void QuicTestClient::Connect() { - DCHECK(!connected()); + if (connected()) { + QUIC_BUG << "Cannot connect already-connected client"; + return; + } if (!connect_attempted_) { client_->Initialize(); }
diff --git a/quic/test_tools/quic_test_client.h b/quic/test_tools/quic_test_client.h index 41e30b1..a7c9d6a 100644 --- a/quic/test_tools/quic_test_client.h +++ b/quic/test_tools/quic_test_client.h
@@ -332,7 +332,9 @@ protected: QuicTestClient(); QuicTestClient(const QuicTestClient&) = delete; + QuicTestClient(const QuicTestClient&&) = delete; QuicTestClient& operator=(const QuicTestClient&) = delete; + QuicTestClient& operator=(const QuicTestClient&&) = delete; private: class TestClientDataToResend : public QuicClient::QuicDataToResend {
diff --git a/quic/tools/quic_client_base.cc b/quic/tools/quic_client_base.cc index 82b549f..efd668f 100644 --- a/quic/tools/quic_client_base.cc +++ b/quic/tools/quic_client_base.cc
@@ -89,6 +89,10 @@ } num_attempts++; } + if (session() == nullptr) { + QUIC_BUG << "Missing session after Connect"; + return false; + } return session()->connection()->connected(); } @@ -165,7 +169,10 @@ } bool QuicClientBase::WaitForEvents() { - DCHECK(connected()); + if (!connected()) { + QUIC_BUG << "Cannot call WaitForEvents on non-connected client"; + return false; + } network_helper_->RunEventLoop(); @@ -228,7 +235,10 @@ } void QuicClientBase::WaitForStreamToClose(QuicStreamId id) { - DCHECK(connected()); + if (!connected()) { + QUIC_BUG << "Cannot WaitForStreamToClose on non-connected client"; + return; + } while (connected() && !session_->IsClosedStream(id)) { WaitForEvents(); @@ -236,7 +246,10 @@ } bool QuicClientBase::WaitForOneRttKeysAvailable() { - DCHECK(connected()); + if (!connected()) { + QUIC_BUG << "Cannot WaitForOneRttKeysAvailable on non-connected client"; + return false; + } while (connected() && !session_->OneRttKeysAvailable()) { WaitForEvents();