• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/quic_versions.h"
6 
7 #include <cstddef>
8 #include <sstream>
9 
10 #include "absl/algorithm/container.h"
11 #include "absl/base/macros.h"
12 #include "quiche/quic/platform/api/quic_expect_bug.h"
13 #include "quiche/quic/platform/api/quic_flags.h"
14 #include "quiche/quic/platform/api/quic_test.h"
15 
16 namespace quic {
17 namespace test {
18 namespace {
19 
20 using ::testing::ElementsAre;
21 using ::testing::IsEmpty;
22 
TEST(QuicVersionsTest,CreateQuicVersionLabelUnsupported)23 TEST(QuicVersionsTest, CreateQuicVersionLabelUnsupported) {
24   EXPECT_QUIC_BUG(
25       CreateQuicVersionLabel(UnsupportedQuicVersion()),
26       "Unsupported version QUIC_VERSION_UNSUPPORTED PROTOCOL_UNSUPPORTED");
27 }
28 
TEST(QuicVersionsTest,KnownAndValid)29 TEST(QuicVersionsTest, KnownAndValid) {
30   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
31     EXPECT_TRUE(version.IsKnown());
32     EXPECT_TRUE(ParsedQuicVersionIsValid(version.handshake_protocol,
33                                          version.transport_version));
34   }
35   ParsedQuicVersion unsupported = UnsupportedQuicVersion();
36   EXPECT_FALSE(unsupported.IsKnown());
37   EXPECT_TRUE(ParsedQuicVersionIsValid(unsupported.handshake_protocol,
38                                        unsupported.transport_version));
39   ParsedQuicVersion reserved = QuicVersionReservedForNegotiation();
40   EXPECT_TRUE(reserved.IsKnown());
41   EXPECT_TRUE(ParsedQuicVersionIsValid(reserved.handshake_protocol,
42                                        reserved.transport_version));
43   // Check that invalid combinations are not valid.
44   EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3, QUIC_VERSION_46));
45   EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
46                                         QUIC_VERSION_IETF_DRAFT_29));
47   // Check that deprecated versions are not valid.
48   EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
49                                         static_cast<QuicTransportVersion>(33)));
50   EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
51                                         static_cast<QuicTransportVersion>(99)));
52   EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3,
53                                         static_cast<QuicTransportVersion>(99)));
54 }
55 
TEST(QuicVersionsTest,Features)56 TEST(QuicVersionsTest, Features) {
57   ParsedQuicVersion parsed_version_q046 = ParsedQuicVersion::Q046();
58   ParsedQuicVersion parsed_version_draft_29 = ParsedQuicVersion::Draft29();
59 
60   EXPECT_TRUE(parsed_version_q046.IsKnown());
61   EXPECT_FALSE(parsed_version_q046.KnowsWhichDecrypterToUse());
62   EXPECT_FALSE(parsed_version_q046.UsesInitialObfuscators());
63   EXPECT_FALSE(parsed_version_q046.AllowsLowFlowControlLimits());
64   EXPECT_FALSE(parsed_version_q046.HasHeaderProtection());
65   EXPECT_FALSE(parsed_version_q046.SupportsRetry());
66   EXPECT_FALSE(
67       parsed_version_q046.SendsVariableLengthPacketNumberInLongHeader());
68   EXPECT_FALSE(parsed_version_q046.AllowsVariableLengthConnectionIds());
69   EXPECT_FALSE(parsed_version_q046.SupportsClientConnectionIds());
70   EXPECT_FALSE(parsed_version_q046.HasLengthPrefixedConnectionIds());
71   EXPECT_FALSE(parsed_version_q046.SupportsAntiAmplificationLimit());
72   EXPECT_FALSE(parsed_version_q046.CanSendCoalescedPackets());
73   EXPECT_TRUE(parsed_version_q046.SupportsGoogleAltSvcFormat());
74   EXPECT_FALSE(parsed_version_q046.UsesHttp3());
75   EXPECT_FALSE(parsed_version_q046.HasLongHeaderLengths());
76   EXPECT_FALSE(parsed_version_q046.UsesCryptoFrames());
77   EXPECT_FALSE(parsed_version_q046.HasIetfQuicFrames());
78   EXPECT_FALSE(parsed_version_q046.UsesTls());
79   EXPECT_TRUE(parsed_version_q046.UsesQuicCrypto());
80 
81   EXPECT_TRUE(parsed_version_draft_29.IsKnown());
82   EXPECT_TRUE(parsed_version_draft_29.KnowsWhichDecrypterToUse());
83   EXPECT_TRUE(parsed_version_draft_29.UsesInitialObfuscators());
84   EXPECT_TRUE(parsed_version_draft_29.AllowsLowFlowControlLimits());
85   EXPECT_TRUE(parsed_version_draft_29.HasHeaderProtection());
86   EXPECT_TRUE(parsed_version_draft_29.SupportsRetry());
87   EXPECT_TRUE(
88       parsed_version_draft_29.SendsVariableLengthPacketNumberInLongHeader());
89   EXPECT_TRUE(parsed_version_draft_29.AllowsVariableLengthConnectionIds());
90   EXPECT_TRUE(parsed_version_draft_29.SupportsClientConnectionIds());
91   EXPECT_TRUE(parsed_version_draft_29.HasLengthPrefixedConnectionIds());
92   EXPECT_TRUE(parsed_version_draft_29.SupportsAntiAmplificationLimit());
93   EXPECT_TRUE(parsed_version_draft_29.CanSendCoalescedPackets());
94   EXPECT_FALSE(parsed_version_draft_29.SupportsGoogleAltSvcFormat());
95   EXPECT_TRUE(parsed_version_draft_29.UsesHttp3());
96   EXPECT_TRUE(parsed_version_draft_29.HasLongHeaderLengths());
97   EXPECT_TRUE(parsed_version_draft_29.UsesCryptoFrames());
98   EXPECT_TRUE(parsed_version_draft_29.HasIetfQuicFrames());
99   EXPECT_TRUE(parsed_version_draft_29.UsesTls());
100   EXPECT_FALSE(parsed_version_draft_29.UsesQuicCrypto());
101 }
102 
TEST(QuicVersionsTest,ParseQuicVersionLabel)103 TEST(QuicVersionsTest, ParseQuicVersionLabel) {
104   static_assert(SupportedVersions().size() == 5u,
105                 "Supported versions out of sync");
106   EXPECT_EQ(ParsedQuicVersion::Q046(),
107             ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '6')));
108   EXPECT_EQ(ParsedQuicVersion::Q050(),
109             ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '5', '0')));
110   EXPECT_EQ(ParsedQuicVersion::Draft29(),
111             ParseQuicVersionLabel(MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)));
112   EXPECT_EQ(ParsedQuicVersion::RFCv1(),
113             ParseQuicVersionLabel(MakeVersionLabel(0x00, 0x00, 0x00, 0x01)));
114   EXPECT_EQ(ParsedQuicVersion::RFCv2(),
115             ParseQuicVersionLabel(MakeVersionLabel(0x6b, 0x33, 0x43, 0xcf)));
116   EXPECT_EQ((ParsedQuicVersionVector{ParsedQuicVersion::RFCv2(),
117                                      ParsedQuicVersion::RFCv1(),
118                                      ParsedQuicVersion::Draft29()}),
119             ParseQuicVersionLabelVector(QuicVersionLabelVector{
120                 MakeVersionLabel(0x6b, 0x33, 0x43, 0xcf),
121                 MakeVersionLabel(0x00, 0x00, 0x00, 0x01),
122                 MakeVersionLabel(0xaa, 0xaa, 0xaa, 0xaa),
123                 MakeVersionLabel(0xff, 0x00, 0x00, 0x1d)}));
124 
125   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
126     EXPECT_EQ(version, ParseQuicVersionLabel(CreateQuicVersionLabel(version)));
127   }
128 }
129 
TEST(QuicVersionsTest,ParseQuicVersionString)130 TEST(QuicVersionsTest, ParseQuicVersionString) {
131   static_assert(SupportedVersions().size() == 5u,
132                 "Supported versions out of sync");
133   EXPECT_EQ(ParsedQuicVersion::Q046(),
134             ParseQuicVersionString("QUIC_VERSION_46"));
135   EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("46"));
136   EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("Q046"));
137   EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("Q050"));
138   EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("50"));
139   EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("h3-Q050"));
140 
141   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString(""));
142   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q 46"));
143   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q046 "));
144   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("99"));
145   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("70"));
146 
147   EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("ff00001d"));
148   EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("draft29"));
149   EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));
150 
151   EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("00000001"));
152   EXPECT_EQ(ParsedQuicVersion::RFCv1(), ParseQuicVersionString("h3"));
153 
154   // QUICv2 will never be the result for "h3".
155 
156   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
157     EXPECT_EQ(version,
158               ParseQuicVersionString(ParsedQuicVersionToString(version)));
159     EXPECT_EQ(version, ParseQuicVersionString(QuicVersionLabelToString(
160                            CreateQuicVersionLabel(version))));
161     if (!version.AlpnDeferToRFCv1()) {
162       EXPECT_EQ(version, ParseQuicVersionString(AlpnForVersion(version)));
163     }
164   }
165 }
166 
TEST(QuicVersionsTest,ParseQuicVersionVectorString)167 TEST(QuicVersionsTest, ParseQuicVersionVectorString) {
168   ParsedQuicVersion version_q046 = ParsedQuicVersion::Q046();
169   ParsedQuicVersion version_q050 = ParsedQuicVersion::Q050();
170   ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();
171 
172   EXPECT_THAT(ParseQuicVersionVectorString(""), IsEmpty());
173 
174   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50"),
175               ElementsAre(version_q050));
176   EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050"),
177               ElementsAre(version_q050));
178   EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-29"),
179               ElementsAre(version_q050, version_draft_29));
180   EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050,h3-29"),
181               ElementsAre(version_draft_29, version_q050));
182   EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-Q050, h3-29"),
183               ElementsAre(version_draft_29, version_q050));
184   EXPECT_THAT(ParseQuicVersionVectorString("h3-29, h3-Q050"),
185               ElementsAre(version_draft_29, version_q050));
186   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,h3-29"),
187               ElementsAre(version_q050, version_draft_29));
188   EXPECT_THAT(ParseQuicVersionVectorString("h3-29,QUIC_VERSION_50"),
189               ElementsAre(version_draft_29, version_q050));
190   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29"),
191               ElementsAre(version_q050, version_draft_29));
192   EXPECT_THAT(ParseQuicVersionVectorString("h3-29, QUIC_VERSION_50"),
193               ElementsAre(version_draft_29, version_q050));
194   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,QUIC_VERSION_46"),
195               ElementsAre(version_q050, version_q046));
196   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_46,QUIC_VERSION_50"),
197               ElementsAre(version_q046, version_q050));
198 
199   // Regression test for https://crbug.com/1044952.
200   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, QUIC_VERSION_50"),
201               ElementsAre(version_q050));
202   EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-Q050"),
203               ElementsAre(version_q050));
204   EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, QUIC_VERSION_50"),
205               ElementsAre(version_q050));
206   EXPECT_THAT(ParseQuicVersionVectorString(
207                   "QUIC_VERSION_50, h3-Q050, QUIC_VERSION_50, h3-Q050"),
208               ElementsAre(version_q050));
209   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-29, h3-Q050"),
210               ElementsAre(version_q050, version_draft_29));
211 
212   EXPECT_THAT(ParseQuicVersionVectorString("99"), IsEmpty());
213   EXPECT_THAT(ParseQuicVersionVectorString("70"), IsEmpty());
214   EXPECT_THAT(ParseQuicVersionVectorString("h3-01"), IsEmpty());
215   EXPECT_THAT(ParseQuicVersionVectorString("h3-01,h3-29"),
216               ElementsAre(version_draft_29));
217 }
218 
219 // Do not use MakeVersionLabel() to generate expectations, because
220 // CreateQuicVersionLabel() uses MakeVersionLabel() internally,
221 // in case it has a bug.
TEST(QuicVersionsTest,CreateQuicVersionLabel)222 TEST(QuicVersionsTest, CreateQuicVersionLabel) {
223   static_assert(SupportedVersions().size() == 5u,
224                 "Supported versions out of sync");
225   EXPECT_EQ(0x51303436u, CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
226   EXPECT_EQ(0x51303530u, CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
227   EXPECT_EQ(0xff00001du, CreateQuicVersionLabel(ParsedQuicVersion::Draft29()));
228   EXPECT_EQ(0x00000001u, CreateQuicVersionLabel(ParsedQuicVersion::RFCv1()));
229   EXPECT_EQ(0x6b3343cfu, CreateQuicVersionLabel(ParsedQuicVersion::RFCv2()));
230 
231   // Make sure the negotiation reserved version is in the IETF reserved space.
232   EXPECT_EQ(
233       0xda5a3a3au & 0x0f0f0f0f,
234       CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()) &
235           0x0f0f0f0f);
236 
237   // Make sure that disabling randomness works.
238   SetQuicFlag(quic_disable_version_negotiation_grease_randomness, true);
239   EXPECT_EQ(0xda5a3a3au, CreateQuicVersionLabel(
240                              ParsedQuicVersion::ReservedForNegotiation()));
241 }
242 
TEST(QuicVersionsTest,QuicVersionLabelToString)243 TEST(QuicVersionsTest, QuicVersionLabelToString) {
244   static_assert(SupportedVersions().size() == 5u,
245                 "Supported versions out of sync");
246   EXPECT_EQ("Q046", QuicVersionLabelToString(
247                         CreateQuicVersionLabel(ParsedQuicVersion::Q046())));
248   EXPECT_EQ("Q050", QuicVersionLabelToString(
249                         CreateQuicVersionLabel(ParsedQuicVersion::Q050())));
250   EXPECT_EQ("ff00001d", QuicVersionLabelToString(CreateQuicVersionLabel(
251                             ParsedQuicVersion::Draft29())));
252   EXPECT_EQ("00000001", QuicVersionLabelToString(CreateQuicVersionLabel(
253                             ParsedQuicVersion::RFCv1())));
254   EXPECT_EQ("6b3343cf", QuicVersionLabelToString(CreateQuicVersionLabel(
255                             ParsedQuicVersion::RFCv2())));
256 
257   QuicVersionLabelVector version_labels = {
258       MakeVersionLabel('Q', '0', '3', '5'),
259       MakeVersionLabel('T', '0', '3', '8'),
260       MakeVersionLabel(0xff, 0, 0, 7),
261   };
262 
263   EXPECT_EQ("Q035", QuicVersionLabelToString(version_labels[0]));
264   EXPECT_EQ("T038", QuicVersionLabelToString(version_labels[1]));
265   EXPECT_EQ("ff000007", QuicVersionLabelToString(version_labels[2]));
266 
267   EXPECT_EQ("Q035,T038,ff000007",
268             QuicVersionLabelVectorToString(version_labels));
269   EXPECT_EQ("Q035:T038:ff000007",
270             QuicVersionLabelVectorToString(version_labels, ":", 2));
271   EXPECT_EQ("Q035|T038|...",
272             QuicVersionLabelVectorToString(version_labels, "|", 1));
273 
274   std::ostringstream os;
275   os << version_labels;
276   EXPECT_EQ("Q035,T038,ff000007", os.str());
277 }
278 
TEST(QuicVersionsTest,ParseQuicVersionLabelString)279 TEST(QuicVersionsTest, ParseQuicVersionLabelString) {
280   static_assert(SupportedVersions().size() == 5u,
281                 "Supported versions out of sync");
282   // Explicitly test known QUIC version label strings.
283   EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionLabelString("Q046"));
284   EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionLabelString("Q050"));
285   EXPECT_EQ(ParsedQuicVersion::Draft29(),
286             ParseQuicVersionLabelString("ff00001d"));
287   EXPECT_EQ(ParsedQuicVersion::RFCv1(),
288             ParseQuicVersionLabelString("00000001"));
289   EXPECT_EQ(ParsedQuicVersion::RFCv2(),
290             ParseQuicVersionLabelString("6b3343cf"));
291 
292   // Sanity check that a variety of other serialization formats are ignored.
293   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("1"));
294   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("46"));
295   EXPECT_EQ(UnsupportedQuicVersion(),
296             ParseQuicVersionLabelString("QUIC_VERSION_46"));
297   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3"));
298   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionLabelString("h3-29"));
299 
300   // Test round-trips between QuicVersionLabelToString and
301   // ParseQuicVersionLabelString.
302   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
303     EXPECT_EQ(version, ParseQuicVersionLabelString(QuicVersionLabelToString(
304                            CreateQuicVersionLabel(version))));
305   }
306 }
307 
TEST(QuicVersionsTest,QuicVersionToString)308 TEST(QuicVersionsTest, QuicVersionToString) {
309   EXPECT_EQ("QUIC_VERSION_UNSUPPORTED",
310             QuicVersionToString(QUIC_VERSION_UNSUPPORTED));
311 
312   QuicTransportVersion single_version[] = {QUIC_VERSION_46};
313   QuicTransportVersionVector versions_vector;
314   for (size_t i = 0; i < ABSL_ARRAYSIZE(single_version); ++i) {
315     versions_vector.push_back(single_version[i]);
316   }
317   EXPECT_EQ("QUIC_VERSION_46",
318             QuicTransportVersionVectorToString(versions_vector));
319 
320   QuicTransportVersion multiple_versions[] = {QUIC_VERSION_UNSUPPORTED,
321                                               QUIC_VERSION_46};
322   versions_vector.clear();
323   for (size_t i = 0; i < ABSL_ARRAYSIZE(multiple_versions); ++i) {
324     versions_vector.push_back(multiple_versions[i]);
325   }
326   EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_46",
327             QuicTransportVersionVectorToString(versions_vector));
328 
329   // Make sure that all supported versions are present in QuicVersionToString.
330   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
331     EXPECT_NE("QUIC_VERSION_UNSUPPORTED",
332               QuicVersionToString(version.transport_version));
333   }
334 
335   std::ostringstream os;
336   os << versions_vector;
337   EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_46", os.str());
338 }
339 
TEST(QuicVersionsTest,ParsedQuicVersionToString)340 TEST(QuicVersionsTest, ParsedQuicVersionToString) {
341   EXPECT_EQ("0", ParsedQuicVersionToString(ParsedQuicVersion::Unsupported()));
342   EXPECT_EQ("Q046", ParsedQuicVersionToString(ParsedQuicVersion::Q046()));
343   EXPECT_EQ("Q050", ParsedQuicVersionToString(ParsedQuicVersion::Q050()));
344   EXPECT_EQ("draft29", ParsedQuicVersionToString(ParsedQuicVersion::Draft29()));
345   EXPECT_EQ("RFCv1", ParsedQuicVersionToString(ParsedQuicVersion::RFCv1()));
346   EXPECT_EQ("RFCv2", ParsedQuicVersionToString(ParsedQuicVersion::RFCv2()));
347 
348   ParsedQuicVersionVector versions_vector = {ParsedQuicVersion::Q046()};
349   EXPECT_EQ("Q046", ParsedQuicVersionVectorToString(versions_vector));
350 
351   versions_vector = {ParsedQuicVersion::Unsupported(),
352                      ParsedQuicVersion::Q046()};
353   EXPECT_EQ("0,Q046", ParsedQuicVersionVectorToString(versions_vector));
354   EXPECT_EQ("0:Q046", ParsedQuicVersionVectorToString(versions_vector, ":",
355                                                       versions_vector.size()));
356   EXPECT_EQ("0|...", ParsedQuicVersionVectorToString(versions_vector, "|", 0));
357 
358   // Make sure that all supported versions are present in
359   // ParsedQuicVersionToString.
360   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
361     EXPECT_NE("0", ParsedQuicVersionToString(version));
362   }
363 
364   std::ostringstream os;
365   os << versions_vector;
366   EXPECT_EQ("0,Q046", os.str());
367 }
368 
TEST(QuicVersionsTest,FilterSupportedVersionsAllVersions)369 TEST(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
370   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
371     QuicEnableVersion(version);
372   }
373   ParsedQuicVersionVector expected_parsed_versions;
374   for (const ParsedQuicVersion& version : SupportedVersions()) {
375     expected_parsed_versions.push_back(version);
376   }
377   EXPECT_EQ(expected_parsed_versions,
378             FilterSupportedVersions(AllSupportedVersions()));
379   EXPECT_EQ(expected_parsed_versions, AllSupportedVersions());
380 }
381 
TEST(QuicVersionsTest,FilterSupportedVersionsWithoutFirstVersion)382 TEST(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
383   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
384     QuicEnableVersion(version);
385   }
386   QuicDisableVersion(AllSupportedVersions().front());
387   ParsedQuicVersionVector expected_parsed_versions;
388   for (const ParsedQuicVersion& version : SupportedVersions()) {
389     expected_parsed_versions.push_back(version);
390   }
391   expected_parsed_versions.erase(expected_parsed_versions.begin());
392   EXPECT_EQ(expected_parsed_versions,
393             FilterSupportedVersions(AllSupportedVersions()));
394 }
395 
TEST(QuicVersionsTest,LookUpParsedVersionByIndex)396 TEST(QuicVersionsTest, LookUpParsedVersionByIndex) {
397   ParsedQuicVersionVector all_versions = AllSupportedVersions();
398   int version_count = all_versions.size();
399   for (int i = -5; i <= version_count + 1; ++i) {
400     ParsedQuicVersionVector index = ParsedVersionOfIndex(all_versions, i);
401     if (i >= 0 && i < version_count) {
402       EXPECT_EQ(all_versions[i], index[0]);
403     } else {
404       EXPECT_EQ(UnsupportedQuicVersion(), index[0]);
405     }
406   }
407 }
408 
409 // This test may appear to be so simplistic as to be unnecessary,
410 // yet a typo was made in doing the #defines and it was caught
411 // only in some test far removed from here... Better safe than sorry.
TEST(QuicVersionsTest,CheckTransportVersionNumbersForTypos)412 TEST(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
413   static_assert(SupportedVersions().size() == 5u,
414                 "Supported versions out of sync");
415   EXPECT_EQ(QUIC_VERSION_46, 46);
416   EXPECT_EQ(QUIC_VERSION_50, 50);
417   EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
418   EXPECT_EQ(QUIC_VERSION_IETF_RFC_V1, 80);
419   EXPECT_EQ(QUIC_VERSION_IETF_RFC_V2, 82);
420 }
421 
TEST(QuicVersionsTest,AlpnForVersion)422 TEST(QuicVersionsTest, AlpnForVersion) {
423   static_assert(SupportedVersions().size() == 5u,
424                 "Supported versions out of sync");
425   EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
426   EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
427   EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
428   EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv1()));
429   EXPECT_EQ("h3", AlpnForVersion(ParsedQuicVersion::RFCv2()));
430 }
431 
TEST(QuicVersionsTest,QuicVersionEnabling)432 TEST(QuicVersionsTest, QuicVersionEnabling) {
433   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
434     QuicFlagSaver flag_saver;
435     QuicDisableVersion(version);
436     EXPECT_FALSE(QuicVersionIsEnabled(version));
437     QuicEnableVersion(version);
438     EXPECT_TRUE(QuicVersionIsEnabled(version));
439   }
440 }
441 
TEST(QuicVersionsTest,ReservedForNegotiation)442 TEST(QuicVersionsTest, ReservedForNegotiation) {
443   EXPECT_EQ(QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
444             QuicVersionReservedForNegotiation().transport_version);
445   // QUIC_VERSION_RESERVED_FOR_NEGOTIATION MUST NOT be supported.
446   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
447     EXPECT_NE(QUIC_VERSION_RESERVED_FOR_NEGOTIATION, version.transport_version);
448   }
449 }
450 
TEST(QuicVersionsTest,SupportedVersionsHasCorrectList)451 TEST(QuicVersionsTest, SupportedVersionsHasCorrectList) {
452   size_t index = 0;
453   for (HandshakeProtocol handshake_protocol : SupportedHandshakeProtocols()) {
454     for (int trans_vers = 255; trans_vers > 0; trans_vers--) {
455       QuicTransportVersion transport_version =
456           static_cast<QuicTransportVersion>(trans_vers);
457       SCOPED_TRACE(index);
458       if (ParsedQuicVersionIsValid(handshake_protocol, transport_version)) {
459         ParsedQuicVersion version = SupportedVersions()[index];
460         EXPECT_EQ(version,
461                   ParsedQuicVersion(handshake_protocol, transport_version));
462         index++;
463       }
464     }
465   }
466   EXPECT_EQ(SupportedVersions().size(), index);
467 }
468 
TEST(QuicVersionsTest,SupportedVersionsAllDistinct)469 TEST(QuicVersionsTest, SupportedVersionsAllDistinct) {
470   for (size_t index1 = 0; index1 < SupportedVersions().size(); ++index1) {
471     ParsedQuicVersion version1 = SupportedVersions()[index1];
472     for (size_t index2 = index1 + 1; index2 < SupportedVersions().size();
473          ++index2) {
474       ParsedQuicVersion version2 = SupportedVersions()[index2];
475       EXPECT_NE(version1, version2) << version1 << " " << version2;
476       EXPECT_NE(CreateQuicVersionLabel(version1),
477                 CreateQuicVersionLabel(version2))
478           << version1 << " " << version2;
479       // The one pair where ALPNs are the same.
480       if ((version1 != ParsedQuicVersion::RFCv2()) &&
481           (version2 != ParsedQuicVersion::RFCv1())) {
482         EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
483             << version1 << " " << version2;
484       }
485     }
486   }
487 }
488 
TEST(QuicVersionsTest,CurrentSupportedHttp3Versions)489 TEST(QuicVersionsTest, CurrentSupportedHttp3Versions) {
490   ParsedQuicVersionVector h3_versions = CurrentSupportedHttp3Versions();
491   ParsedQuicVersionVector all_current_supported_versions =
492       CurrentSupportedVersions();
493   for (auto& version : all_current_supported_versions) {
494     bool version_is_h3 = false;
495     for (auto& h3_version : h3_versions) {
496       if (version == h3_version) {
497         EXPECT_TRUE(version.UsesHttp3());
498         version_is_h3 = true;
499         break;
500       }
501     }
502     if (!version_is_h3) {
503       EXPECT_FALSE(version.UsesHttp3());
504     }
505   }
506 }
507 
TEST(QuicVersionsTest,ObsoleteSupportedVersions)508 TEST(QuicVersionsTest, ObsoleteSupportedVersions) {
509   ParsedQuicVersionVector obsolete_versions = ObsoleteSupportedVersions();
510   EXPECT_EQ(quic::ParsedQuicVersion::Q046(), obsolete_versions[0]);
511   EXPECT_EQ(quic::ParsedQuicVersion::Q050(), obsolete_versions[1]);
512   EXPECT_EQ(quic::ParsedQuicVersion::Draft29(), obsolete_versions[2]);
513 }
514 
TEST(QuicVersionsTest,IsObsoleteSupportedVersion)515 TEST(QuicVersionsTest, IsObsoleteSupportedVersion) {
516   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
517     bool is_obsolete = version.handshake_protocol != PROTOCOL_TLS1_3 ||
518                        version.transport_version < QUIC_VERSION_IETF_RFC_V1;
519     EXPECT_EQ(is_obsolete, IsObsoleteSupportedVersion(version));
520   }
521 }
522 
TEST(QuicVersionsTest,CurrentSupportedVersionsForClients)523 TEST(QuicVersionsTest, CurrentSupportedVersionsForClients) {
524   ParsedQuicVersionVector supported_versions = CurrentSupportedVersions();
525   ParsedQuicVersionVector client_versions =
526       CurrentSupportedVersionsForClients();
527   for (auto& version : supported_versions) {
528     const bool is_obsolete = IsObsoleteSupportedVersion(version);
529     const bool is_supported =
530         absl::c_find(client_versions, version) != client_versions.end();
531     // Every supported version which is not obsolete should be a supported
532     // client version.
533     EXPECT_EQ(!is_obsolete, is_supported);
534   }
535   // Every client version should be a supported version, of course.
536   for (auto& version : client_versions) {
537     EXPECT_TRUE(absl::c_find(supported_versions, version) !=
538                 supported_versions.end());
539   }
540 }
541 
542 }  // namespace
543 }  // namespace test
544 }  // namespace quic
545