Project import generated by Copybara.

PiperOrigin-RevId: 237361882
Change-Id: I109a68f44db867b20f8c6a7732b0ce657133e52a
diff --git a/quic/core/quic_config_test.cc b/quic/core/quic_config_test.cc
new file mode 100644
index 0000000..59ad0ef
--- /dev/null
+++ b/quic/core/quic_config_test.cc
@@ -0,0 +1,287 @@
+// Copyright (c) 2013 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/core/quic_config.h"
+
+#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
+#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
+#include "net/third_party/quiche/src/quic/core/quic_packets.h"
+#include "net/third_party/quiche/src/quic/core/quic_time.h"
+#include "net/third_party/quiche/src/quic/core/quic_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_string.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
+#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
+
+namespace quic {
+namespace test {
+namespace {
+
+class QuicConfigTest : public QuicTest {
+ protected:
+  QuicConfig config_;
+};
+
+TEST_F(QuicConfigTest, ToHandshakeMessage) {
+  config_.SetInitialStreamFlowControlWindowToSend(
+      kInitialStreamFlowControlWindowForTest);
+  config_.SetInitialSessionFlowControlWindowToSend(
+      kInitialSessionFlowControlWindowForTest);
+  config_.SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(5),
+                                QuicTime::Delta::FromSeconds(2));
+  CryptoHandshakeMessage msg;
+  config_.ToHandshakeMessage(&msg);
+
+  uint32_t value;
+  QuicErrorCode error = msg.GetUint32(kICSL, &value);
+  EXPECT_EQ(QUIC_NO_ERROR, error);
+  EXPECT_EQ(5u, value);
+
+  error = msg.GetUint32(kSFCW, &value);
+  EXPECT_EQ(QUIC_NO_ERROR, error);
+  EXPECT_EQ(kInitialStreamFlowControlWindowForTest, value);
+
+  error = msg.GetUint32(kCFCW, &value);
+  EXPECT_EQ(QUIC_NO_ERROR, error);
+  EXPECT_EQ(kInitialSessionFlowControlWindowForTest, value);
+}
+
+TEST_F(QuicConfigTest, ProcessClientHello) {
+  QuicConfig client_config;
+  QuicTagVector cgst;
+  cgst.push_back(kQBIC);
+  client_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
+  client_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
+  client_config.SetInitialStreamFlowControlWindowToSend(
+      2 * kInitialStreamFlowControlWindowForTest);
+  client_config.SetInitialSessionFlowControlWindowToSend(
+      2 * kInitialSessionFlowControlWindowForTest);
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetConnectionOptionsToSend(copt);
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg);
+
+  QuicString error_details;
+  QuicTagVector initial_received_options;
+  initial_received_options.push_back(kIW50);
+  EXPECT_TRUE(
+      config_.SetInitialReceivedConnectionOptions(initial_received_options));
+  EXPECT_FALSE(
+      config_.SetInitialReceivedConnectionOptions(initial_received_options))
+      << "You can only set initial options once.";
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_FALSE(
+      config_.SetInitialReceivedConnectionOptions(initial_received_options))
+      << "You cannot set initial options after the hello.";
+  EXPECT_EQ(QUIC_NO_ERROR, error);
+  EXPECT_TRUE(config_.negotiated());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs),
+            config_.IdleNetworkTimeout());
+  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
+  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+  EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size());
+  EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kIW50);
+  EXPECT_EQ(config_.ReceivedConnectionOptions()[1], kTBBR);
+  EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
+            2 * kInitialStreamFlowControlWindowForTest);
+  EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
+            2 * kInitialSessionFlowControlWindowForTest);
+}
+
+TEST_F(QuicConfigTest, ProcessServerHello) {
+  QuicIpAddress host;
+  host.FromString("127.0.3.1");
+  const QuicSocketAddress kTestServerAddress = QuicSocketAddress(host, 1234);
+  const QuicUint128 kTestResetToken = MakeQuicUint128(0, 10111100001);
+  QuicConfig server_config;
+  QuicTagVector cgst;
+  cgst.push_back(kQBIC);
+  server_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
+      QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2));
+  server_config.SetInitialRoundTripTimeUsToSend(10 * kNumMicrosPerMilli);
+  server_config.SetInitialStreamFlowControlWindowToSend(
+      2 * kInitialStreamFlowControlWindowForTest);
+  server_config.SetInitialSessionFlowControlWindowToSend(
+      2 * kInitialSessionFlowControlWindowForTest);
+  server_config.SetAlternateServerAddressToSend(kTestServerAddress);
+  server_config.SetStatelessResetTokenToSend(kTestResetToken);
+  CryptoHandshakeMessage msg;
+  server_config.ToHandshakeMessage(&msg);
+  QuicString error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_EQ(QUIC_NO_ERROR, error);
+  EXPECT_TRUE(config_.negotiated());
+  EXPECT_EQ(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs / 2),
+            config_.IdleNetworkTimeout());
+  EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs());
+  EXPECT_EQ(config_.ReceivedInitialStreamFlowControlWindowBytes(),
+            2 * kInitialStreamFlowControlWindowForTest);
+  EXPECT_EQ(config_.ReceivedInitialSessionFlowControlWindowBytes(),
+            2 * kInitialSessionFlowControlWindowForTest);
+  EXPECT_TRUE(config_.HasReceivedAlternateServerAddress());
+  EXPECT_EQ(kTestServerAddress, config_.ReceivedAlternateServerAddress());
+  EXPECT_TRUE(config_.HasReceivedStatelessResetToken());
+  EXPECT_EQ(kTestResetToken, config_.ReceivedStatelessResetToken());
+}
+
+TEST_F(QuicConfigTest, MissingOptionalValuesInCHLO) {
+  CryptoHandshakeMessage msg;
+  msg.SetValue(kICSL, 1);
+
+  // Set all REQUIRED tags.
+  msg.SetValue(kICSL, 1);
+  msg.SetValue(kMIDS, 1);
+
+  // No error, as rest are optional.
+  QuicString error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_EQ(QUIC_NO_ERROR, error);
+  EXPECT_TRUE(config_.negotiated());
+}
+
+TEST_F(QuicConfigTest, MissingOptionalValuesInSHLO) {
+  CryptoHandshakeMessage msg;
+
+  // Set all REQUIRED tags.
+  msg.SetValue(kICSL, 1);
+  msg.SetValue(kMIDS, 1);
+
+  // No error, as rest are optional.
+  QuicString error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_EQ(QUIC_NO_ERROR, error);
+  EXPECT_TRUE(config_.negotiated());
+}
+
+TEST_F(QuicConfigTest, MissingValueInCHLO) {
+  // Server receives CHLO with missing kICSL.
+  CryptoHandshakeMessage msg;
+  QuicString error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
+}
+
+TEST_F(QuicConfigTest, MissingValueInSHLO) {
+  // Client receives SHLO with missing kICSL.
+  CryptoHandshakeMessage msg;
+  QuicString error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, error);
+}
+
+TEST_F(QuicConfigTest, OutOfBoundSHLO) {
+  QuicConfig server_config;
+  server_config.SetIdleNetworkTimeout(
+      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs),
+      QuicTime::Delta::FromSeconds(2 * kMaximumIdleTimeoutSecs));
+
+  CryptoHandshakeMessage msg;
+  server_config.ToHandshakeMessage(&msg);
+  QuicString error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, SERVER, &error_details);
+  EXPECT_EQ(QUIC_INVALID_NEGOTIATED_VALUE, error);
+}
+
+TEST_F(QuicConfigTest, InvalidFlowControlWindow) {
+  // QuicConfig should not accept an invalid flow control window to send to the
+  // peer: the receive window must be at least the default of 16 Kb.
+  QuicConfig config;
+  const uint64_t kInvalidWindow = kMinimumFlowControlSendWindow - 1;
+  EXPECT_QUIC_BUG(
+      config.SetInitialStreamFlowControlWindowToSend(kInvalidWindow),
+      "Initial stream flow control receive window");
+
+  EXPECT_EQ(kMinimumFlowControlSendWindow,
+            config.GetInitialStreamFlowControlWindowToSend());
+}
+
+TEST_F(QuicConfigTest, HasClientSentConnectionOption) {
+  QuicConfig client_config;
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetConnectionOptionsToSend(copt);
+  EXPECT_TRUE(client_config.HasClientSentConnectionOption(
+      kTBBR, Perspective::IS_CLIENT));
+
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg);
+
+  QuicString error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_EQ(QUIC_NO_ERROR, error);
+  EXPECT_TRUE(config_.negotiated());
+
+  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+  EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
+  EXPECT_TRUE(
+      config_.HasClientSentConnectionOption(kTBBR, Perspective::IS_SERVER));
+}
+
+TEST_F(QuicConfigTest, DontSendClientConnectionOptions) {
+  QuicConfig client_config;
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetClientConnectionOptions(copt);
+
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg);
+
+  QuicString error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_EQ(QUIC_NO_ERROR, error);
+  EXPECT_TRUE(config_.negotiated());
+
+  EXPECT_FALSE(config_.HasReceivedConnectionOptions());
+}
+
+TEST_F(QuicConfigTest, HasClientRequestedIndependentOption) {
+  QuicConfig client_config;
+  QuicTagVector client_opt;
+  client_opt.push_back(kRENO);
+  QuicTagVector copt;
+  copt.push_back(kTBBR);
+  client_config.SetClientConnectionOptions(client_opt);
+  client_config.SetConnectionOptionsToSend(copt);
+  EXPECT_TRUE(client_config.HasClientSentConnectionOption(
+      kTBBR, Perspective::IS_CLIENT));
+  EXPECT_TRUE(client_config.HasClientRequestedIndependentOption(
+      kRENO, Perspective::IS_CLIENT));
+  EXPECT_FALSE(client_config.HasClientRequestedIndependentOption(
+      kTBBR, Perspective::IS_CLIENT));
+
+  CryptoHandshakeMessage msg;
+  client_config.ToHandshakeMessage(&msg);
+
+  QuicString error_details;
+  const QuicErrorCode error =
+      config_.ProcessPeerHello(msg, CLIENT, &error_details);
+  EXPECT_EQ(QUIC_NO_ERROR, error);
+  EXPECT_TRUE(config_.negotiated());
+
+  EXPECT_TRUE(config_.HasReceivedConnectionOptions());
+  EXPECT_EQ(1u, config_.ReceivedConnectionOptions().size());
+  EXPECT_FALSE(config_.HasClientRequestedIndependentOption(
+      kRENO, Perspective::IS_SERVER));
+  EXPECT_TRUE(config_.HasClientRequestedIndependentOption(
+      kTBBR, Perspective::IS_SERVER));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace quic