Add a simple integration test for QuicTransport.
gfe-relnote: n/a (not used in production)
PiperOrigin-RevId: 276340873
Change-Id: Ie2caa7e6d5389f9170d79f0b2e471c36dbfbcbc2
diff --git a/quic/quic_transport/quic_transport_integration_test.cc b/quic/quic_transport/quic_transport_integration_test.cc
new file mode 100644
index 0000000..f4c6a2a
--- /dev/null
+++ b/quic/quic_transport/quic_transport_integration_test.cc
@@ -0,0 +1,227 @@
+// Copyright (c) 2019 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.
+
+// An integration test that covers interactions between QuicTransport client and
+// server sessions.
+
+#include <memory>
+
+#include "url/gurl.h"
+#include "url/origin.h"
+#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
+#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
+#include "net/third_party/quiche/src/quic/core/quic_connection.h"
+#include "net/third_party/quiche/src/quic/core/quic_error_codes.h"
+#include "net/third_party/quiche/src/quic/core/quic_types.h"
+#include "net/third_party/quiche/src/quic/core/quic_versions.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_client_session.h"
+#include "net/third_party/quiche/src/quic/quic_transport/quic_transport_server_session.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"
+#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h"
+#include "net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint_base.h"
+#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"
+#include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+using simulator::QuicEndpointBase;
+using simulator::Simulator;
+using testing::_;
+using testing::Return;
+
+url::Origin GetTestOrigin() {
+ constexpr char kTestOrigin[] = "https://test-origin.test";
+ GURL origin_url(kTestOrigin);
+ return url::Origin::Create(origin_url);
+}
+
+ParsedQuicVersionVector GetVersions() {
+ return {ParsedQuicVersion{PROTOCOL_TLS1_3, QUIC_VERSION_99}};
+}
+
+class QuicTransportEndpointBase : public QuicEndpointBase {
+ public:
+ QuicTransportEndpointBase(Simulator* simulator,
+ const std::string& name,
+ const std::string& peer_name,
+ Perspective perspective)
+ : QuicEndpointBase(simulator, name, peer_name) {
+ connection_ = std::make_unique<QuicConnection>(
+ TestConnectionId(0x10), simulator::GetAddressFromName(peer_name),
+ simulator, simulator->GetAlarmFactory(), &writer_,
+ /*owns_writer=*/false, perspective, GetVersions());
+ connection_->SetSelfAddress(simulator::GetAddressFromName(name));
+
+ SetQuicReloadableFlag(quic_supports_tls_handshake, true);
+ }
+};
+
+class QuicTransportClientEndpoint : public QuicTransportEndpointBase {
+ public:
+ QuicTransportClientEndpoint(Simulator* simulator,
+ const std::string& name,
+ const std::string& peer_name,
+ url::Origin origin)
+ : QuicTransportEndpointBase(simulator,
+ name,
+ peer_name,
+ Perspective::IS_CLIENT),
+ crypto_config_(crypto_test_utils::ProofVerifierForTesting()),
+ session_(connection_.get(),
+ nullptr,
+ DefaultQuicConfig(),
+ GetVersions(),
+ QuicServerId("test.example.com", 443),
+ &crypto_config_,
+ origin) {
+ session_.Initialize();
+ }
+
+ QuicTransportClientSession* session() { return &session_; }
+
+ private:
+ QuicCryptoClientConfig crypto_config_;
+ QuicTransportClientSession session_;
+};
+
+class MockServerVisitor : public QuicTransportServerSession::ServerVisitor {
+ public:
+ MOCK_METHOD1(CheckOrigin, bool(url::Origin));
+};
+
+class QuicTransportServerEndpoint : public QuicTransportEndpointBase {
+ public:
+ QuicTransportServerEndpoint(Simulator* simulator,
+ const std::string& name,
+ const std::string& peer_name)
+ : QuicTransportEndpointBase(simulator,
+ name,
+ peer_name,
+ Perspective::IS_SERVER),
+ crypto_config_(QuicCryptoServerConfig::TESTING,
+ QuicRandom::GetInstance(),
+ crypto_test_utils::ProofSourceForTesting(),
+ KeyExchangeSource::Default()),
+ compressed_certs_cache_(
+ QuicCompressedCertsCache::kQuicCompressedCertsCacheSize),
+ session_(connection_.get(),
+ nullptr,
+ DefaultQuicConfig(),
+ GetVersions(),
+ &crypto_config_,
+ &compressed_certs_cache_,
+ &visitor_) {
+ session_.Initialize();
+ }
+
+ QuicTransportServerSession* session() { return &session_; }
+ MockServerVisitor* visitor() { return &visitor_; }
+
+ private:
+ QuicCryptoServerConfig crypto_config_;
+ QuicCompressedCertsCache compressed_certs_cache_;
+ QuicTransportServerSession session_;
+ MockServerVisitor visitor_;
+};
+
+constexpr QuicBandwidth kClientBandwidth =
+ QuicBandwidth::FromKBitsPerSecond(10000);
+constexpr QuicTime::Delta kClientPropagationDelay =
+ QuicTime::Delta::FromMilliseconds(2);
+constexpr QuicBandwidth kServerBandwidth =
+ QuicBandwidth::FromKBitsPerSecond(4000);
+constexpr QuicTime::Delta kServerPropagationDelay =
+ QuicTime::Delta::FromMilliseconds(50);
+const QuicTime::Delta kTransferTime =
+ kClientBandwidth.TransferTime(kMaxOutgoingPacketSize) +
+ kServerBandwidth.TransferTime(kMaxOutgoingPacketSize);
+const QuicTime::Delta kRtt =
+ (kClientPropagationDelay + kServerPropagationDelay + kTransferTime) * 2;
+const QuicByteCount kBdp = kRtt * kServerBandwidth;
+
+constexpr QuicTime::Delta kHandshakeTimeout = QuicTime::Delta::FromSeconds(3);
+
+class QuicTransportIntegrationTest : public QuicTest {
+ public:
+ QuicTransportIntegrationTest()
+ : switch_(&simulator_, "Switch", 8, 2 * kBdp) {}
+
+ void CreateDefaultEndpoints() {
+ client_ = std::make_unique<QuicTransportClientEndpoint>(
+ &simulator_, "Client", "Server", GetTestOrigin());
+ server_ = std::make_unique<QuicTransportServerEndpoint>(&simulator_,
+ "Server", "Client");
+ ON_CALL(*server_->visitor(), CheckOrigin(_)).WillByDefault(Return(true));
+ }
+
+ void WireUpEndpoints() {
+ client_link_ = std::make_unique<simulator::SymmetricLink>(
+ client_.get(), switch_.port(1), kClientBandwidth,
+ kClientPropagationDelay);
+ server_link_ = std::make_unique<simulator::SymmetricLink>(
+ server_.get(), switch_.port(2), kServerBandwidth,
+ kServerPropagationDelay);
+ }
+
+ void RunHandshake() {
+ client_->session()->CryptoConnect();
+ bool result = simulator_.RunUntilOrTimeout(
+ [this]() {
+ return IsHandshakeDone(client_->session()) &&
+ IsHandshakeDone(server_->session());
+ },
+ kHandshakeTimeout);
+ EXPECT_TRUE(result);
+ }
+
+ protected:
+ template <class Session>
+ static bool IsHandshakeDone(const Session* session) {
+ return session->IsSessionReady() || session->error() != QUIC_NO_ERROR;
+ }
+
+ Simulator simulator_;
+ simulator::Switch switch_;
+ std::unique_ptr<simulator::SymmetricLink> client_link_;
+ std::unique_ptr<simulator::SymmetricLink> server_link_;
+
+ std::unique_ptr<QuicTransportClientEndpoint> client_;
+ std::unique_ptr<QuicTransportServerEndpoint> server_;
+};
+
+TEST_F(QuicTransportIntegrationTest, SuccessfulHandshake) {
+ CreateDefaultEndpoints();
+ WireUpEndpoints();
+ RunHandshake();
+ EXPECT_TRUE(client_->session()->IsSessionReady());
+ EXPECT_TRUE(server_->session()->IsSessionReady());
+}
+
+TEST_F(QuicTransportIntegrationTest, OriginMismatch) {
+ CreateDefaultEndpoints();
+ WireUpEndpoints();
+ EXPECT_CALL(*server_->visitor(), CheckOrigin(_))
+ .WillRepeatedly(Return(false));
+ RunHandshake();
+ // Wait until the client receives CONNECTION_CLOSE.
+ simulator_.RunUntilOrTimeout(
+ [this]() { return !client_->session()->connection()->connected(); },
+ kHandshakeTimeout);
+ EXPECT_TRUE(client_->session()->IsSessionReady());
+ EXPECT_FALSE(server_->session()->IsSessionReady());
+ EXPECT_FALSE(client_->session()->connection()->connected());
+ EXPECT_FALSE(server_->session()->connection()->connected());
+ EXPECT_EQ(client_->session()->error(),
+ QUIC_TRANSPORT_INVALID_CLIENT_INDICATION);
+ EXPECT_EQ(server_->session()->error(),
+ QUIC_TRANSPORT_INVALID_CLIENT_INDICATION);
+}
+
+} // namespace
+} // namespace test
+} // namespace quic