// Copyright (c) 2012 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 "quiche/quic/core/quic_versions.h"

#include "absl/base/macros.h"
#include "quiche/quic/platform/api/quic_expect_bug.h"
#include "quiche/quic/platform/api/quic_flags.h"
#include "quiche/quic/platform/api/quic_logging.h"
#include "quiche/quic/platform/api/quic_test.h"

namespace quic {
namespace test {
namespace {

using ::testing::ElementsAre;
using ::testing::IsEmpty;

TEST(QuicVersionsTest, CreateQuicVersionLabelUnsupported) {
  EXPECT_QUIC_BUG(
      CreateQuicVersionLabel(UnsupportedQuicVersion()),
      "Unsupported version QUIC_VERSION_UNSUPPORTED PROTOCOL_UNSUPPORTED");
}

TEST(QuicVersionsTest, KnownAndValid) {
  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    EXPECT_TRUE(version.IsKnown());
    EXPECT_TRUE(ParsedQuicVersionIsValid(version.handshake_protocol,
                                         version.transport_version));
  }
  ParsedQuicVersion unsupported = UnsupportedQuicVersion();
  EXPECT_FALSE(unsupported.IsKnown());
  EXPECT_TRUE(ParsedQuicVersionIsValid(unsupported.handshake_protocol,
                                       unsupported.transport_version));
  ParsedQuicVersion reserved = QuicVersionReservedForNegotiation();
  EXPECT_TRUE(reserved.IsKnown());
  EXPECT_TRUE(ParsedQuicVersionIsValid(reserved.handshake_protocol,
                                       reserved.transport_version));
  // Check that invalid combinations are not valid.
  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3, QUIC_VERSION_43));
  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
                                        QUIC_VERSION_IETF_DRAFT_29));
  // Check that deprecated versions are not valid.
  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
                                        static_cast<QuicTransportVersion>(33)));
  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
                                        static_cast<QuicTransportVersion>(99)));
  EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3,
                                        static_cast<QuicTransportVersion>(99)));
}

TEST(QuicVersionsTest, Features) {
  ParsedQuicVersion parsed_version_q043 = ParsedQuicVersion::Q043();
  ParsedQuicVersion parsed_version_draft_29 = ParsedQuicVersion::Draft29();

  EXPECT_TRUE(parsed_version_q043.IsKnown());
  EXPECT_FALSE(parsed_version_q043.KnowsWhichDecrypterToUse());
  EXPECT_FALSE(parsed_version_q043.UsesInitialObfuscators());
  EXPECT_FALSE(parsed_version_q043.AllowsLowFlowControlLimits());
  EXPECT_FALSE(parsed_version_q043.HasHeaderProtection());
  EXPECT_FALSE(parsed_version_q043.SupportsRetry());
  EXPECT_FALSE(
      parsed_version_q043.SendsVariableLengthPacketNumberInLongHeader());
  EXPECT_FALSE(parsed_version_q043.AllowsVariableLengthConnectionIds());
  EXPECT_FALSE(parsed_version_q043.SupportsClientConnectionIds());
  EXPECT_FALSE(parsed_version_q043.HasLengthPrefixedConnectionIds());
  EXPECT_FALSE(parsed_version_q043.SupportsAntiAmplificationLimit());
  EXPECT_FALSE(parsed_version_q043.CanSendCoalescedPackets());
  EXPECT_TRUE(parsed_version_q043.SupportsGoogleAltSvcFormat());
  EXPECT_FALSE(parsed_version_q043.HasIetfInvariantHeader());
  EXPECT_FALSE(parsed_version_q043.SupportsMessageFrames());
  EXPECT_FALSE(parsed_version_q043.UsesHttp3());
  EXPECT_FALSE(parsed_version_q043.HasLongHeaderLengths());
  EXPECT_FALSE(parsed_version_q043.UsesCryptoFrames());
  EXPECT_FALSE(parsed_version_q043.HasIetfQuicFrames());
  EXPECT_FALSE(parsed_version_q043.UsesTls());
  EXPECT_TRUE(parsed_version_q043.UsesQuicCrypto());

  EXPECT_TRUE(parsed_version_draft_29.IsKnown());
  EXPECT_TRUE(parsed_version_draft_29.KnowsWhichDecrypterToUse());
  EXPECT_TRUE(parsed_version_draft_29.UsesInitialObfuscators());
  EXPECT_TRUE(parsed_version_draft_29.AllowsLowFlowControlLimits());
  EXPECT_TRUE(parsed_version_draft_29.HasHeaderProtection());
  EXPECT_TRUE(parsed_version_draft_29.SupportsRetry());
  EXPECT_TRUE(
      parsed_version_draft_29.SendsVariableLengthPacketNumberInLongHeader());
  EXPECT_TRUE(parsed_version_draft_29.AllowsVariableLengthConnectionIds());
  EXPECT_TRUE(parsed_version_draft_29.SupportsClientConnectionIds());
  EXPECT_TRUE(parsed_version_draft_29.HasLengthPrefixedConnectionIds());
  EXPECT_TRUE(parsed_version_draft_29.SupportsAntiAmplificationLimit());
  EXPECT_TRUE(parsed_version_draft_29.CanSendCoalescedPackets());
  EXPECT_FALSE(parsed_version_draft_29.SupportsGoogleAltSvcFormat());
  EXPECT_TRUE(parsed_version_draft_29.HasIetfInvariantHeader());
  EXPECT_TRUE(parsed_version_draft_29.SupportsMessageFrames());
  EXPECT_TRUE(parsed_version_draft_29.UsesHttp3());
  EXPECT_TRUE(parsed_version_draft_29.HasLongHeaderLengths());
  EXPECT_TRUE(parsed_version_draft_29.UsesCryptoFrames());
  EXPECT_TRUE(parsed_version_draft_29.HasIetfQuicFrames());
  EXPECT_TRUE(parsed_version_draft_29.UsesTls());
  EXPECT_FALSE(parsed_version_draft_29.UsesQuicCrypto());
}

TEST(QuicVersionsTest, ParseQuicVersionLabel) {
  static_assert(SupportedVersions().size() == 6u,
                "Supported versions out of sync");
  EXPECT_EQ(ParsedQuicVersion::Q043(),
            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '3')));
  EXPECT_EQ(ParsedQuicVersion::Q046(),
            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '6')));
  EXPECT_EQ(ParsedQuicVersion::Q050(),
            ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '5', '0')));
  EXPECT_EQ(ParsedQuicVersion::Draft29(),
            ParseQuicVersionLabel(MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)));
  EXPECT_EQ(ParsedQuicVersion::RFCv1(),
            ParseQuicVersionLabel(MakeVersionLabel(0x00, 0x00, 0x00, 0x01)));
  EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
            ParseQuicVersionLabel(MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4)));
  EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::V2Draft01(),
                                     ParsedQuicVersion::RFCv1(),
                                     ParsedQuicVersion::Draft29()}),
            ParseQuicVersionLabelVector(QuicVersionLabelVector{
                MakeVersionLabel(0x70, 0x9a, 0x50, 0xc4),
                MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
                MakeVersionLabel(0xaa, 0xaa, 0xaa, 0xaa),
                MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)}));

  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    EXPECT_EQ(version, ParseQuicVersionLabel(CreateQuicVersionLabel(version)));
  }
}

TEST(QuicVersionsTest, ParseQuicVersionString) {
  static_assert(SupportedVersions().size() == 6u,
                "Supported versions out of sync");
  EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionString("Q043"));
  EXPECT_EQ(ParsedQuicVersion::Q046(),
            ParseQuicVersionString("QUIC_VERSION_46"));
  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("46"));
  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("Q046"));
  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("Q050"));
  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("50"));
  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("h3-Q050"));

  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString(""));
  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q 46"));
  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q046 "));
  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("99"));
  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("70"));

  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("ff00001d"));
  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("draft29"));
  EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));

  EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("00000001"));
  EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("h3"));

  // QUICv2 will never be the result for "h3".

  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    EXPECT_EQ(version,
              ParseQuicVersionString(ParsedQuicVersionToString(version)));
    EXPECT_EQ(version, ParseQuicVersionString(QuicVersionLabelToString(
                           CreateQuicVersionLabel(version))));
    if (!version.AlpnDeferToRFCv1()) {
      EXPECT_EQ(version, ParseQuicVersionString(AlpnForVersion(version)));
    }
  }
}

TEST(QuicVersionsTest, ParseQuicVersionVectorString) {
  ParsedQuicVersion version_q046 = ParsedQuicVersion::Q046();
  ParsedQuicVersion version_q050 = ParsedQuicVersion::Q050();
  ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();

  EXPECT_THAT(ParseQuicVersionVectorString(""), IsEmpty());

  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50"),
              ElementsAre(version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050"),
              ElementsAre(version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-29"),
              ElementsAre(version_q050, version_draft_29));
  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050,h3-29"),
              ElementsAre(version_draft_29, version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050, h3-29"),
              ElementsAre(version_draft_29, version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString("h3-29, h3-Q050"),
              ElementsAre(version_draft_29, version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,h3-29"),
              ElementsAre(version_q050, version_draft_29));
  EXPECT_THAT(ParseQuicVersionVectorString("h3-29,QUIC_VERSION_50"),
              ElementsAre(version_draft_29, version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29"),
              ElementsAre(version_q050, version_draft_29));
  EXPECT_THAT(ParseQuicVersionVectorString("h3-29, QUIC_VERSION_50"),
              ElementsAre(version_draft_29, version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,QUIC_VERSION_46"),
              ElementsAre(version_q050, version_q046));
  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_46,QUIC_VERSION_50"),
              ElementsAre(version_q046, version_q050));

  // Regression test for https://crbug.com/1044952.
  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, QUIC_VERSION_50"),
              ElementsAre(version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-Q050"),
              ElementsAre(version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, QUIC_VERSION_50"),
              ElementsAre(version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString(
                  "QUIC_VERSION_50, h3-Q050, QUIC_VERSION_50, h3-Q050"),
              ElementsAre(version_q050));
  EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29, h3-Q050"),
              ElementsAre(version_q050, version_draft_29));

  EXPECT_THAT(ParseQuicVersionVectorString("99"), IsEmpty());
  EXPECT_THAT(ParseQuicVersionVectorString("70"), IsEmpty());
  EXPECT_THAT(ParseQuicVersionVectorString("h3-01"), IsEmpty());
  EXPECT_THAT(ParseQuicVersionVectorString("h3-01,h3-29"),
              ElementsAre(version_draft_29));
}

// Do not use MakeVersionLabel() to generate expectations, because
// CreateQuicVersionLabel() uses MakeVersionLabel() internally,
// in case it has a bug.
TEST(QuicVersionsTest, CreateQuicVersionLabel) {
  static_assert(SupportedVersions().size() == 6u,
                "Supported versions out of sync");
  EXPECT_EQ(0x51303433u, CreateQuicVersionLabel(ParsedQuicVersion::Q043()));
  EXPECT_EQ(0x51303436u, CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
  EXPECT_EQ(0x51303530u, CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
  EXPECT_EQ(0xff00001du, CreateQuicVersionLabel(ParsedQuicVersion::Draft29()));
  EXPECT_EQ(0x00000001u, CreateQuicVersionLabel(ParsedQuicVersion::RFCv1()));
  EXPECT_EQ(0x709a50c4u,
            CreateQuicVersionLabel(ParsedQuicVersion::V2Draft01()));

  // Make sure the negotiation reserved version is in the IETF reserved space.
  EXPECT_EQ(
      0xda5a3a3au & 0x0f0f0f0f,
      CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()) &
          0x0f0f0f0f);

  // Make sure that disabling randomness works.
  SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
  EXPECT_EQ(0xda5a3a3au, CreateQuicVersionLabel(
                             ParsedQuicVersion::ReservedForNegotiation()));
}

TEST(QuicVersionsTest, QuicVersionLabelToString) {
  static_assert(SupportedVersions().size() == 6u,
                "Supported versions out of sync");
  EXPECT_EQ("Q043", QuicVersionLabelToString(
                        CreateQuicVersionLabel(ParsedQuicVersion::Q043())));
  EXPECT_EQ("Q046", QuicVersionLabelToString(
                        CreateQuicVersionLabel(ParsedQuicVersion::Q046())));
  EXPECT_EQ("Q050", QuicVersionLabelToString(
                        CreateQuicVersionLabel(ParsedQuicVersion::Q050())));
  EXPECT_EQ("ff00001d", QuicVersionLabelToString(CreateQuicVersionLabel(
                            ParsedQuicVersion::Draft29())));
  EXPECT_EQ("00000001", QuicVersionLabelToString(CreateQuicVersionLabel(
                            ParsedQuicVersion::RFCv1())));
  EXPECT_EQ("709a50c4", QuicVersionLabelToString(CreateQuicVersionLabel(
                            ParsedQuicVersion::V2Draft01())));

  QuicVersionLabelVector version_labels = {
      MakeVersionLabel('Q', '0', '3', '5'),
      MakeVersionLabel('T', '0', '3', '8'),
      MakeVersionLabel(0xff, 0, 0, 7),
  };

  EXPECT_EQ("Q035", QuicVersionLabelToString(version_labels[0]));
  EXPECT_EQ("T038", QuicVersionLabelToString(version_labels[1]));
  EXPECT_EQ("ff000007", QuicVersionLabelToString(version_labels[2]));

  EXPECT_EQ("Q035,T038,ff000007",
            QuicVersionLabelVectorToString(version_labels));
  EXPECT_EQ("Q035:T038:ff000007",
            QuicVersionLabelVectorToString(version_labels, ":", 2));
  EXPECT_EQ("Q035|T038|...",
            QuicVersionLabelVectorToString(version_labels, "|", 1));

  std::ostringstream os;
  os << version_labels;
  EXPECT_EQ("Q035,T038,ff000007", os.str());
}

TEST(QuicVersionsTest, ParseQuicVersionLabelString) {
  static_assert(SupportedVersions().size() == 6u,
                "Supported versions out of sync");
  // Explicitly test known QUIC version label strings.
  EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionLabelString("Q043"));
  EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionLabelString("Q046"));
  EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionLabelString("Q050"));
  EXPECT_EQ(ParsedQuicVersion::Draft29(),
            ParseQuicVersionLabelString("ff00001d"));
  EXPECT_EQ(ParsedQuicVersion::RFCv1(),
            ParseQuicVersionLabelString("00000001"));
  EXPECT_EQ(ParsedQuicVersion::V2Draft01(),
            ParseQuicVersionLabelString("709a50c4"));

  // Sanity check that a variety of other serialization formats are ignored.
  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("1"));
  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("46"));
  EXPECT_EQ(UnsupportedQuicVersion(),
            ParseQuicVersionLabelString("QUIC_VERSION_46"));
  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3"));
  EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3-29"));

  // Test round-trips between QuicVersionLabelToString and
  // ParseQuicVersionLabelString.
  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    EXPECT_EQ(version, ParseQuicVersionLabelString(QuicVersionLabelToString(
                           CreateQuicVersionLabel(version))));
  }
}

TEST(QuicVersionsTest, QuicVersionToString) {
  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED",
            QuicVersionToString(QUIC_VERSION_UNSUPPORTED));

  QuicTransportVersion single_version[] = {QUIC_VERSION_43};
  QuicTransportVersionVector versions_vector;
  for (size_t i = 0; i < ABSL_ARRAYSIZE(single_version); ++i) {
    versions_vector.push_back(single_version[i]);
  }
  EXPECT_EQ("QUIC_VERSION_43",
            QuicTransportVersionVectorToString(versions_vector));

  QuicTransportVersion multiple_versions[] = {QUIC_VERSION_UNSUPPORTED,
                                              QUIC_VERSION_43};
  versions_vector.clear();
  for (size_t i = 0; i < ABSL_ARRAYSIZE(multiple_versions); ++i) {
    versions_vector.push_back(multiple_versions[i]);
  }
  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43",
            QuicTransportVersionVectorToString(versions_vector));

  // Make sure that all supported versions are present in QuicVersionToString.
  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    EXPECT_NE("QUIC_VERSION_UNSUPPORTED",
              QuicVersionToString(version.transport_version));
  }

  std::ostringstream os;
  os << versions_vector;
  EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43", os.str());
}

TEST(QuicVersionsTest, ParsedQuicVersionToString) {
  EXPECT_EQ("0", ParsedQuicVersionToString(ParsedQuicVersion::Unsupported()));
  EXPECT_EQ("Q043", ParsedQuicVersionToString(ParsedQuicVersion::Q043()));
  EXPECT_EQ("Q046", ParsedQuicVersionToString(ParsedQuicVersion::Q046()));
  EXPECT_EQ("Q050", ParsedQuicVersionToString(ParsedQuicVersion::Q050()));
  EXPECT_EQ("draft29", ParsedQuicVersionToString(ParsedQuicVersion::Draft29()));
  EXPECT_EQ("RFCv1", ParsedQuicVersionToString(ParsedQuicVersion::RFCv1()));
  EXPECT_EQ("v2draft01",
            ParsedQuicVersionToString(ParsedQuicVersion::V2Draft01()));

  ParsedQuicVersionVector versions_vector = {ParsedQuicVersion::Q043()};
  EXPECT_EQ("Q043", ParsedQuicVersionVectorToString(versions_vector));

  versions_vector = {ParsedQuicVersion::Unsupported(),
                     ParsedQuicVersion::Q043()};
  EXPECT_EQ("0,Q043", ParsedQuicVersionVectorToString(versions_vector));
  EXPECT_EQ("0:Q043", ParsedQuicVersionVectorToString(versions_vector, ":",
                                                      versions_vector.size()));
  EXPECT_EQ("0|...", ParsedQuicVersionVectorToString(versions_vector, "|", 0));

  // Make sure that all supported versions are present in
  // ParsedQuicVersionToString.
  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    EXPECT_NE("0", ParsedQuicVersionToString(version));
  }

  std::ostringstream os;
  os << versions_vector;
  EXPECT_EQ("0,Q043", os.str());
}

TEST(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    QuicEnableVersion(version);
  }
  ParsedQuicVersionVector expected_parsed_versions;
  for (const ParsedQuicVersion& version : SupportedVersions()) {
    expected_parsed_versions.push_back(version);
  }
  EXPECT_EQ(expected_parsed_versions,
            FilterSupportedVersions(AllSupportedVersions()));
  EXPECT_EQ(expected_parsed_versions, AllSupportedVersions());
}

TEST(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    QuicEnableVersion(version);
  }
  QuicDisableVersion(AllSupportedVersions().front());
  ParsedQuicVersionVector expected_parsed_versions;
  for (const ParsedQuicVersion& version : SupportedVersions()) {
    expected_parsed_versions.push_back(version);
  }
  expected_parsed_versions.erase(expected_parsed_versions.begin());
  EXPECT_EQ(expected_parsed_versions,
            FilterSupportedVersions(AllSupportedVersions()));
}

TEST(QuicVersionsTest, LookUpParsedVersionByIndex) {
  ParsedQuicVersionVector all_versions = AllSupportedVersions();
  int version_count = all_versions.size();
  for (int i = -5; i <= version_count + 1; ++i) {
    ParsedQuicVersionVector index = ParsedVersionOfIndex(all_versions, i);
    if (i >= 0 && i < version_count) {
      EXPECT_EQ(all_versions[i], index[0]);
    } else {
      EXPECT_EQ(UnsupportedQuicVersion(), index[0]);
    }
  }
}

// This test may appear to be so simplistic as to be unnecessary,
// yet a typo was made in doing the #defines and it was caught
// only in some test far removed from here... Better safe than sorry.
TEST(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
  static_assert(SupportedVersions().size() == 6u,
                "Supported versions out of sync");
  EXPECT_EQ(QUIC_VERSION_43, 43);
  EXPECT_EQ(QUIC_VERSION_46, 46);
  EXPECT_EQ(QUIC_VERSION_50, 50);
  EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
  EXPECT_EQ(QUIC_VERSION_IETF_RFC_V1, 80);
  EXPECT_EQ(QUIC_VERSION_IETF_2_DRAFT_01, 81);
}

TEST(QuicVersionsTest, AlpnForVersion) {
  static_assert(SupportedVersions().size() == 6u,
                "Supported versions out of sync");
  EXPECT_EQ("h3-Q043", AlpnForVersion(ParsedQuicVersion::Q043()));
  EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
  EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
  EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
  EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv1()));
  EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::V2Draft01()));
}

TEST(QuicVersionsTest, QuicVersionEnabling) {
  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    QuicFlagSaver flag_saver;
    QuicDisableVersion(version);
    EXPECT_FALSE(QuicVersionIsEnabled(version));
    QuicEnableVersion(version);
    EXPECT_TRUE(QuicVersionIsEnabled(version));
  }
}

TEST(QuicVersionsTest, ReservedForNegotiation) {
  EXPECT_EQ(QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
            QuicVersionReservedForNegotiation().transport_version);
  // QUIC_VERSION_RESERVED_FOR_NEGOTIATION MUST NOT be supported.
  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    EXPECT_NE(QUIC_VERSION_RESERVED_FOR_NEGOTIATION, version.transport_version);
  }
}

TEST(QuicVersionsTest, SupportedVersionsHasCorrectList) {
  size_t index = 0;
  for (HandshakeProtocol handshake_protocol : SupportedHandshakeProtocols()) {
    for (int trans_vers = 255; trans_vers > 0; trans_vers--) {
      QuicTransportVersion transport_version =
          static_cast<QuicTransportVersion>(trans_vers);
      SCOPED_TRACE(index);
      if (ParsedQuicVersionIsValid(handshake_protocol, transport_version)) {
        ParsedQuicVersion version = SupportedVersions()[index];
        EXPECT_EQ(version,
                  ParsedQuicVersion(handshake_protocol, transport_version));
        index++;
      }
    }
  }
  EXPECT_EQ(SupportedVersions().size(), index);
}

TEST(QuicVersionsTest, SupportedVersionsAllDistinct) {
  for (size_t index1 = 0; index1 < SupportedVersions().size(); ++index1) {
    ParsedQuicVersion version1 = SupportedVersions()[index1];
    for (size_t index2 = index1 + 1; index2 < SupportedVersions().size();
         ++index2) {
      ParsedQuicVersion version2 = SupportedVersions()[index2];
      EXPECT_NE(version1, version2) << version1 << " " << version2;
      EXPECT_NE(CreateQuicVersionLabel(version1),
                CreateQuicVersionLabel(version2))
          << version1 << " " << version2;
      // The one pair where ALPNs are the same.
      if ((version1 != ParsedQuicVersion::V2Draft01()) &&
          (version2 != ParsedQuicVersion::RFCv1())) {
        EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
            << version1 << " " << version2;
      }
    }
  }
}

TEST(QuicVersionsTest, CurrentSupportedHttp3Versions) {
  ParsedQuicVersionVector h3_versions = CurrentSupportedHttp3Versions();
  ParsedQuicVersionVector all_current_supported_versions =
      CurrentSupportedVersions();
  for (auto& version : all_current_supported_versions) {
    bool version_is_h3 = false;
    for (auto& h3_version : h3_versions) {
      if (version == h3_version) {
        EXPECT_TRUE(version.UsesHttp3());
        version_is_h3 = true;
        break;
      }
    }
    if (!version_is_h3) {
      EXPECT_FALSE(version.UsesHttp3());
    }
  }
}

}  // namespace
}  // namespace test
}  // namespace quic
