// Copyright (c) 2017 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/quartc/quartc_endpoint.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/quartc/quartc_crypto_helpers.h"
#include "net/third_party/quiche/src/quic/quartc/quartc_fakes.h"
#include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h"
#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h"
#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"

namespace quic {
namespace {

class QuartcEndpointTest : public QuicTest {
 protected:
  QuartcEndpointTest()
      : client_transport_(&simulator_,
                          "client_transport",
                          "server_transport",
                          10 * kDefaultMaxPacketSize),
        server_transport_(&simulator_,
                          "server_transport",
                          "client_transport",
                          10 * kDefaultMaxPacketSize),
        client_server_link_(&client_transport_,
                            &server_transport_,
                            QuicBandwidth::FromKBitsPerSecond(10000),
                            QuicTime::Delta::FromMilliseconds(1)),
        server_endpoint_delegate_(&server_stream_delegate_,
                                  simulator_.GetClock()),
        server_endpoint_(std::make_unique<QuartcServerEndpoint>(
            simulator_.GetAlarmFactory(),
            simulator_.GetClock(),
            simulator_.GetRandomGenerator(),
            &server_endpoint_delegate_,
            QuartcSessionConfig())),
        client_endpoint_delegate_(&client_stream_delegate_,
                                  simulator_.GetClock()),
        client_endpoint_(std::make_unique<QuartcClientEndpoint>(
            simulator_.GetAlarmFactory(),
            simulator_.GetClock(),
            simulator_.GetRandomGenerator(),
            &client_endpoint_delegate_,
            QuartcSessionConfig(),
            /*serialized_server_config=*/"")) {}

  simulator::Simulator simulator_;

  simulator::SimulatedQuartcPacketTransport client_transport_;
  simulator::SimulatedQuartcPacketTransport server_transport_;
  simulator::SymmetricLink client_server_link_;

  FakeQuartcStreamDelegate server_stream_delegate_;
  FakeQuartcEndpointDelegate server_endpoint_delegate_;

  std::unique_ptr<QuartcServerEndpoint> server_endpoint_;

  FakeQuartcStreamDelegate client_stream_delegate_;
  FakeQuartcEndpointDelegate client_endpoint_delegate_;

  std::unique_ptr<QuartcClientEndpoint> client_endpoint_;
};

// After calling Connect, the client endpoint must wait for an async callback.
// The callback occurs after a finite amount of time and produces a session.
TEST_F(QuartcEndpointTest, ClientCreatesSessionAsynchronously) {
  client_endpoint_->Connect(&client_transport_);

  EXPECT_EQ(client_endpoint_delegate_.session(), nullptr);

  EXPECT_TRUE(simulator_.RunUntil(
      [this] { return client_endpoint_delegate_.session() != nullptr; }));
}

// Tests that the server can negotiate for an older QUIC version if the client
// attempts to connect using a newer version.
TEST_F(QuartcEndpointTest,
       QUIC_TEST_DISABLED_IN_CHROME(ServerNegotiatesForOldVersion)) {
  // Reset the client endpoint to prefer version 46 but also be capable of
  // speaking version 43.
  ParsedQuicVersionVector client_versions;
  client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46});
  client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
  client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
      simulator_.GetAlarmFactory(), simulator_.GetClock(),
      simulator_.GetRandomGenerator(), &client_endpoint_delegate_,
      QuartcSessionConfig(),
      /*serialized_server_config=*/"",
      std::make_unique<QuicVersionManager>(client_versions));

  // Reset the server endpoint to only speak version 43.
  ParsedQuicVersionVector server_versions;
  server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
  server_endpoint_ = std::make_unique<QuartcServerEndpoint>(
      simulator_.GetAlarmFactory(), simulator_.GetClock(),
      simulator_.GetRandomGenerator(), &server_endpoint_delegate_,
      QuartcSessionConfig(),
      std::make_unique<QuicVersionManager>(server_versions));

  // The endpoints should be able to establish a connection using version 46.
  server_endpoint_->Connect(&server_transport_);
  client_endpoint_->Connect(&client_transport_);

  ASSERT_TRUE(simulator_.RunUntil([this] {
    return client_endpoint_delegate_.session() != nullptr &&
           client_endpoint_delegate_.session()->IsEncryptionEstablished() &&
           server_endpoint_delegate_.session() != nullptr &&
           server_endpoint_delegate_.session()->IsEncryptionEstablished();
  }));
  EXPECT_EQ(client_endpoint_delegate_.session()->connection()->version(),
            server_versions[0]);
  EXPECT_EQ(server_endpoint_delegate_.session()->connection()->version(),
            server_versions[0]);
}

// Tests that the server can accept connections from clients that use older
// QUIC versions.
TEST_F(QuartcEndpointTest,
       QUIC_TEST_DISABLED_IN_CHROME(ServerAcceptsOldVersion)) {
  // Reset the client endpoint to only speak version 43.
  ParsedQuicVersionVector client_versions;
  client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
  client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
      simulator_.GetAlarmFactory(), simulator_.GetClock(),
      simulator_.GetRandomGenerator(), &client_endpoint_delegate_,
      QuartcSessionConfig(),
      /*serialized_server_config=*/"",
      std::make_unique<QuicVersionManager>(client_versions));

  // Reset the server endpoint to prefer version 46 but also be capable of
  // speaking version 43.
  ParsedQuicVersionVector server_versions;
  server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46});
  server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
  server_endpoint_ = std::make_unique<QuartcServerEndpoint>(
      simulator_.GetAlarmFactory(), simulator_.GetClock(),
      simulator_.GetRandomGenerator(), &server_endpoint_delegate_,
      QuartcSessionConfig(),
      std::make_unique<QuicVersionManager>(server_versions));

  // The endpoints should be able to establish a connection using version 46.
  server_endpoint_->Connect(&server_transport_);
  client_endpoint_->Connect(&client_transport_);

  ASSERT_TRUE(simulator_.RunUntil([this] {
    return client_endpoint_delegate_.session() != nullptr &&
           client_endpoint_delegate_.session()->IsEncryptionEstablished() &&
           server_endpoint_delegate_.session() != nullptr &&
           server_endpoint_delegate_.session()->IsEncryptionEstablished();
  }));
  EXPECT_EQ(client_endpoint_delegate_.session()->connection()->version(),
            client_versions[0]);
  EXPECT_EQ(server_endpoint_delegate_.session()->connection()->version(),
            client_versions[0]);
}

// Tests that version negotiation fails when the client and server support
// completely disjoint sets of versions.
TEST_F(QuartcEndpointTest,
       QUIC_TEST_DISABLED_IN_CHROME(VersionNegotiationWithDisjointVersions)) {
  // Reset the client endpoint to only speak version 43.
  ParsedQuicVersionVector client_versions;
  client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
  client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
      simulator_.GetAlarmFactory(), simulator_.GetClock(),
      simulator_.GetRandomGenerator(), &client_endpoint_delegate_,
      QuartcSessionConfig(),
      /*serialized_server_config=*/"",
      std::make_unique<QuicVersionManager>(client_versions));

  // Reset the server endpoint to only speak version 46.
  ParsedQuicVersionVector server_versions;
  server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46});
  server_endpoint_ = std::make_unique<QuartcServerEndpoint>(
      simulator_.GetAlarmFactory(), simulator_.GetClock(),
      simulator_.GetRandomGenerator(), &server_endpoint_delegate_,
      QuartcSessionConfig(),
      std::make_unique<QuicVersionManager>(server_versions));

  // The endpoints should be unable to establish a connection.
  server_endpoint_->Connect(&server_transport_);
  client_endpoint_->Connect(&client_transport_);

  // Note that the error is reported from the client and *not* the server.  The
  // server sees an invalid version, sends a version negotiation packet, and
  // never gets a response, because the client stops sending when it can't find
  // a mutually supported versions.
  ASSERT_TRUE(simulator_.RunUntil([this] {
    return client_endpoint_delegate_.session() != nullptr &&
           client_endpoint_delegate_.session()->error() != QUIC_NO_ERROR;
  }));
  EXPECT_EQ(client_endpoint_delegate_.session()->error(), QUIC_INVALID_VERSION);
}

// Tests that the client endpoint can create a new session in order to continue
// version negotiation.
TEST_F(QuartcEndpointTest,
       QUIC_TEST_DISABLED_IN_CHROME(CreatesNewSessionWhenRequired)) {
  // Reset the client endpoint to prefer version 46 but also be capable of
  // speaking version 43.
  ParsedQuicVersionVector client_versions;
  client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46});
  client_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
  client_endpoint_ = std::make_unique<QuartcClientEndpoint>(
      simulator_.GetAlarmFactory(), simulator_.GetClock(),
      simulator_.GetRandomGenerator(), &client_endpoint_delegate_,
      QuartcSessionConfig(),
      /*serialized_server_config=*/"",
      std::make_unique<QuicVersionManager>(client_versions));

  // Reset the server endpoint to only speak version 43.
  ParsedQuicVersionVector server_versions;
  server_versions.push_back({PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_43});
  server_endpoint_ = std::make_unique<QuartcServerEndpoint>(
      simulator_.GetAlarmFactory(), simulator_.GetClock(),
      simulator_.GetRandomGenerator(), &server_endpoint_delegate_,
      QuartcSessionConfig(),
      std::make_unique<QuicVersionManager>(server_versions));

  // The endpoints should be able to establish a connection using version 46.
  server_endpoint_->Connect(&server_transport_);
  client_endpoint_->Connect(&client_transport_);

  ASSERT_TRUE(simulator_.RunUntil([this] {
    return client_endpoint_delegate_.session() != nullptr &&
           client_endpoint_delegate_.session()->IsEncryptionEstablished() &&
           server_endpoint_delegate_.session() != nullptr &&
           server_endpoint_delegate_.session()->IsEncryptionEstablished();
  }));
  EXPECT_EQ(client_endpoint_delegate_.session()->connection()->version(),
            server_versions[0]);
  EXPECT_EQ(server_endpoint_delegate_.session()->connection()->version(),
            server_versions[0]);

  EXPECT_EQ(2, client_endpoint_delegate_.num_sessions_created());
}

}  // namespace
}  // namespace quic
