Add quic::test::GetFirstFlightOfPackets()

This CL adds GetFirstFlightOfPackets, a mechanism to extract
the first flight of packets from a QUIC connection. This will be
used to test code that parses the CHLO. This CL also adds various
test classes and methods that are used by GetFirstFlightOfPackets.

gfe-relnote: n/a, test-only
PiperOrigin-RevId: 307703986
Change-Id: Iedd17f41f1120d2be2188694710dcd698d61efc8
diff --git a/quic/test_tools/first_flight.cc b/quic/test_tools/first_flight.cc
new file mode 100644
index 0000000..e4d2816
--- /dev/null
+++ b/quic/test_tools/first_flight.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/test_tools/first_flight.h"
+
+#include <memory>
+#include <vector>
+
+#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h"
+#include "net/third_party/quiche/src/quic/core/http/quic_spdy_client_session.h"
+#include "net/third_party/quiche/src/quic/core/quic_config.h"
+#include "net/third_party/quiche/src/quic/core/quic_connection.h"
+#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
+#include "net/third_party/quiche/src/quic/core/quic_packet_writer.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/quic_versions.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_ip_address.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
+#include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+
+// Utility class that creates a custom HTTP/3 session and QUIC connection in
+// order to extract the first flight of packets it sends. This is meant to only
+// be used by GetFirstFlightOfPackets() below.
+class FirstFlightExtractor : public DelegatedPacketWriter::Delegate {
+ public:
+  FirstFlightExtractor(const ParsedQuicVersion& version,
+                       const QuicConfig& config,
+                       const QuicConnectionId& server_connection_id,
+                       const QuicConnectionId& client_connection_id)
+      : version_(version),
+        server_connection_id_(server_connection_id),
+        client_connection_id_(client_connection_id),
+        writer_(this),
+        config_(config),
+        crypto_config_(crypto_test_utils::ProofVerifierForTesting()) {
+    EXPECT_NE(version_, UnsupportedQuicVersion());
+  }
+
+  void GenerateFirstFlight() {
+    crypto_config_.set_alpn(AlpnForVersion(version_));
+    connection_ =
+        new QuicConnection(server_connection_id_,
+                           QuicSocketAddress(TestPeerIPAddress(), kTestPort),
+                           &connection_helper_, &alarm_factory_, &writer_,
+                           /*owns_writer=*/false, Perspective::IS_CLIENT,
+                           ParsedQuicVersionVector{version_});
+    connection_->set_client_connection_id(client_connection_id_);
+    session_ = std::make_unique<QuicSpdyClientSession>(
+        config_, ParsedQuicVersionVector{version_},
+        connection_,  // session_ takes ownership of connection_ here.
+        TestServerId(), &crypto_config_, &push_promise_index_);
+    session_->Initialize();
+    session_->CryptoConnect();
+  }
+
+  void OnDelegatedPacket(const char* buffer,
+                         size_t buf_len,
+                         const QuicIpAddress& /*self_client_address*/,
+                         const QuicSocketAddress& /*peer_client_address*/,
+                         PerPacketOptions* /*options*/) override {
+    packets_.emplace_back(
+        QuicReceivedPacket(buffer, buf_len,
+                           connection_helper_.GetClock()->ApproximateNow(),
+                           /*owns_buffer=*/false)
+            .Clone());
+  }
+
+  std::vector<std::unique_ptr<QuicReceivedPacket>>&& ConsumePackets() {
+    return std::move(packets_);
+  }
+
+ private:
+  ParsedQuicVersion version_;
+  QuicConnectionId server_connection_id_;
+  QuicConnectionId client_connection_id_;
+  MockQuicConnectionHelper connection_helper_;
+  MockAlarmFactory alarm_factory_;
+  DelegatedPacketWriter writer_;
+  QuicConfig config_;
+  QuicCryptoClientConfig crypto_config_;
+  QuicClientPushPromiseIndex push_promise_index_;
+  QuicConnection* connection_;  // Owned by session_.
+  std::unique_ptr<QuicSpdyClientSession> session_;
+  std::vector<std::unique_ptr<QuicReceivedPacket>> packets_;
+};
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConfig& config,
+    const QuicConnectionId& server_connection_id,
+    const QuicConnectionId& client_connection_id) {
+  FirstFlightExtractor first_flight_extractor(
+      version, config, server_connection_id, client_connection_id);
+  first_flight_extractor.GenerateFirstFlight();
+  return first_flight_extractor.ConsumePackets();
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConfig& config,
+    const QuicConnectionId& server_connection_id) {
+  return GetFirstFlightOfPackets(version, config, server_connection_id,
+                                 EmptyQuicConnectionId());
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConfig& config) {
+  return GetFirstFlightOfPackets(version, config, TestConnectionId());
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConnectionId& server_connection_id,
+    const QuicConnectionId& client_connection_id) {
+  return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
+                                 server_connection_id, client_connection_id);
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version,
+    const QuicConnectionId& server_connection_id) {
+  return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
+                                 server_connection_id, EmptyQuicConnectionId());
+}
+
+std::vector<std::unique_ptr<QuicReceivedPacket>> GetFirstFlightOfPackets(
+    const ParsedQuicVersion& version) {
+  return GetFirstFlightOfPackets(version, DefaultQuicConfig(),
+                                 TestConnectionId());
+}
+
+}  // namespace test
+}  // namespace quic