Add 0-RTT support to QuicToyClient

I had to mark QuicToyClient and its users as test_only, which should have been done in the first place.

This change is a no-op unless a new command-line flag is passed in so it won't impact any existing uses.

PiperOrigin-RevId: 372616822
diff --git a/quic/tools/quic_epoll_client_factory.cc b/quic/tools/quic_epoll_client_factory.cc
index 8483038..1fff089 100644
--- a/quic/tools/quic_epoll_client_factory.cc
+++ b/quic/tools/quic_epoll_client_factory.cc
@@ -24,7 +24,8 @@
     uint16_t port,
     ParsedQuicVersionVector versions,
     const QuicConfig& config,
-    std::unique_ptr<ProofVerifier> verifier) {
+    std::unique_ptr<ProofVerifier> verifier,
+    std::unique_ptr<SessionCache> session_cache) {
   QuicSocketAddress addr = tools::LookupAddress(
       address_family_for_lookup, host_for_lookup, absl::StrCat(port));
   if (!addr.IsInitialized()) {
@@ -34,7 +35,7 @@
   QuicServerId server_id(host_for_handshake, port, false);
   return std::make_unique<QuicClient>(addr, server_id, versions, config,
                                       &epoll_server_, std::move(verifier),
-                                      nullptr);
+                                      std::move(session_cache));
 }
 
 }  // namespace quic
diff --git a/quic/tools/quic_epoll_client_factory.h b/quic/tools/quic_epoll_client_factory.h
index e23eb63..9e78b47 100644
--- a/quic/tools/quic_epoll_client_factory.h
+++ b/quic/tools/quic_epoll_client_factory.h
@@ -20,7 +20,8 @@
       uint16_t port,
       ParsedQuicVersionVector versions,
       const QuicConfig& config,
-      std::unique_ptr<ProofVerifier> verifier) override;
+      std::unique_ptr<ProofVerifier> verifier,
+      std::unique_ptr<SessionCache> session_cache) override;
 
  private:
   QuicEpollServer epoll_server_;
diff --git a/quic/tools/quic_toy_client.cc b/quic/tools/quic_toy_client.cc
index 2ba9d5d..8d22791 100644
--- a/quic/tools/quic_toy_client.cc
+++ b/quic/tools/quic_toy_client.cc
@@ -59,6 +59,7 @@
 #include "quic/platform/api/quic_ip_address.h"
 #include "quic/platform/api/quic_socket_address.h"
 #include "quic/platform/api/quic_system_event_loop.h"
+#include "quic/test_tools/simple_session_cache.h"
 #include "quic/tools/fake_proof_verifier.h"
 #include "quic/tools/quic_url.h"
 #include "common/quiche_text_utils.h"
@@ -194,6 +195,12 @@
     false,
     "If true, do not change local port after each request.");
 
+DEFINE_QUIC_COMMAND_LINE_FLAG(bool,
+                              one_connection_per_request,
+                              false,
+                              "If true, close the connection after each "
+                              "request. This allows testing 0-RTT.");
+
 DEFINE_QUIC_COMMAND_LINE_FLAG(int32_t,
                               server_connection_id_length,
                               -1,
@@ -260,6 +267,10 @@
   } else {
     proof_verifier = quic::CreateDefaultProofVerifier(url.host());
   }
+  std::unique_ptr<quic::SessionCache> session_cache;
+  if (num_requests > 1 && GetQuicFlag(FLAGS_one_connection_per_request)) {
+    session_cache = std::make_unique<test::SimpleSessionCache>();
+  }
 
   QuicConfig config;
   std::string connection_options_string = GetQuicFlag(FLAGS_connection_options);
@@ -293,7 +304,7 @@
   // Build the client, and try to connect.
   std::unique_ptr<QuicSpdyClientBase> client = client_factory_->CreateClient(
       url.host(), host, address_family_for_lookup, port, versions, config,
-      std::move(proof_verifier));
+      std::move(proof_verifier), std::move(session_cache));
 
   if (client == nullptr) {
     std::cerr << "Failed to create client." << std::endl;
@@ -430,11 +441,26 @@
       return 1;
     }
 
-    // Change the ephemeral port if there are more requests to do.
-    if (!GetQuicFlag(FLAGS_disable_port_changes) && i + 1 < num_requests) {
-      if (!client->ChangeEphemeralPort()) {
-        std::cerr << "Failed to change ephemeral port." << std::endl;
-        return 1;
+    if (i + 1 < num_requests) {  // There are more requests to perform.
+      if (GetQuicFlag(FLAGS_one_connection_per_request)) {
+        std::cout << "Disconnecting client between requests." << std::endl;
+        client->Disconnect();
+        if (!client->Initialize()) {
+          std::cerr << "Failed to reinitialize client between requests."
+                    << std::endl;
+          return 1;
+        }
+        if (!client->Connect()) {
+          std::cerr << "Failed to reconnect client between requests."
+                    << std::endl;
+          return 1;
+        }
+      } else if (!GetQuicFlag(FLAGS_disable_port_changes)) {
+        // Change the ephemeral port.
+        if (!client->ChangeEphemeralPort()) {
+          std::cerr << "Failed to change ephemeral port." << std::endl;
+          return 1;
+        }
       }
     }
   }
diff --git a/quic/tools/quic_toy_client.h b/quic/tools/quic_toy_client.h
index 085e749..81b3733 100644
--- a/quic/tools/quic_toy_client.h
+++ b/quic/tools/quic_toy_client.h
@@ -29,7 +29,8 @@
         uint16_t port,
         ParsedQuicVersionVector versions,
         const QuicConfig& config,
-        std::unique_ptr<ProofVerifier> verifier) = 0;
+        std::unique_ptr<ProofVerifier> verifier,
+        std::unique_ptr<SessionCache> session_cache) = 0;
   };
 
   // Constructs a new toy client that will use |client_factory| to create the