Verify receipt of connection_close in quic_client_interop
This CL also changes QuicFramer::MaybeExtractQuicErrorCode to map NO_IETF_QUIC_ERROR to QUIC_NO_ERROR.
gfe-relnote: change mapping of NO_IETF_QUIC_ERROR, not flag-protected
PiperOrigin-RevId: 274704993
Change-Id: If3e7f98dd6a2435a477ee318b44fce78e6ab6e30
diff --git a/quic/tools/quic_client_interop_test_bin.cc b/quic/tools/quic_client_interop_test_bin.cc
index 20a4699..2511141 100644
--- a/quic/tools/quic_client_interop_test_bin.cc
+++ b/quic/tools/quic_client_interop_test_bin.cc
@@ -11,6 +11,7 @@
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_system_event_loop.h"
+#include "net/quic/platform/impl/quic_epoll_clock.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_connection_peer.h"
#include "net/third_party/quiche/src/quic/tools/fake_proof_verifier.h"
#include "net/third_party/quiche/src/quic/tools/quic_client.h"
@@ -34,10 +35,10 @@
kStreamData,
// The connection close procedcure completes with a zero error code.
kConnectionClose,
- // An H3 transaction succeeded.
- kHttp3,
// A RETRY packet was successfully processed.
kRetry,
+ // An H3 transaction succeeded.
+ kHttp3,
};
char MatrixLetter(Feature f) {
@@ -64,6 +65,7 @@
std::set<Feature> features;
auto proof_verifier = std::make_unique<FakeProofVerifier>();
QuicEpollServer epoll_server;
+ QuicEpollClock epoll_clock(&epoll_server);
auto client = std::make_unique<QuicClient>(
addr, server_id, versions, &epoll_server, std::move(proof_verifier));
if (!client->Initialize()) {
@@ -95,9 +97,13 @@
client->set_store_response(true);
client->SendRequest(header_block, "", /*fin=*/true);
- // TODO(nharper): After some period of time, time out and don't report
- // success.
+ const QuicTime request_start_time = epoll_clock.Now();
+ static const auto request_timeout = QuicTime::Delta::FromSeconds(20);
while (client->WaitForEvents()) {
+ if (epoll_clock.Now() - request_start_time >= request_timeout) {
+ QUIC_LOG(ERROR) << "Timed out waiting for HTTP response";
+ return features;
+ }
}
QuicConnection* connection = client->session()->connection();
@@ -125,9 +131,28 @@
features.insert(Feature::kHttp3);
}
- // TODO(nharper): Check that we sent/received (which one?) a CONNECTION_CLOSE
- // with error code 0.
- features.insert(Feature::kConnectionClose);
+ if (connection != nullptr && connection->connected()) {
+ test::QuicConnectionPeer::SendConnectionClosePacket(
+ connection, QUIC_NO_ERROR, "Graceful close");
+ const QuicTime close_start_time = epoll_clock.Now();
+ static const auto close_timeout = QuicTime::Delta::FromSeconds(10);
+ while (client->connected()) {
+ client->epoll_network_helper()->RunEventLoop();
+ if (epoll_clock.Now() - close_start_time >= close_timeout) {
+ QUIC_LOG(ERROR) << "Timed out waiting for connection close";
+ return features;
+ }
+ }
+ const QuicErrorCode received_error = client->session()->error();
+ if (received_error == QUIC_NO_ERROR ||
+ received_error == QUIC_PUBLIC_RESET) {
+ features.insert(Feature::kConnectionClose);
+ } else {
+ QUIC_LOG(ERROR) << "Received error " << client->session()->error() << " "
+ << client->session()->error_details();
+ }
+ }
+
return features;
}