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 "net/third_party/quiche/src/quic/core/quic_versions.h"
6 
7 #include "absl/base/macros.h"
8 #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h"
9 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
10 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
11 #include "net/third_party/quiche/src/quic/platform/api/quic_mock_log.h"
12 #include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
13 
14 namespace quic {
15 namespace test {
16 namespace {
17 
18 using ::testing::_;
19 using ::testing::ElementsAre;
20 using ::testing::IsEmpty;
21 
22 class QuicVersionsTest : public QuicTest {
23  protected:
MakeVersionLabel(char a,char b,char c,char d)24   QuicVersionLabel MakeVersionLabel(char a, char b, char c, char d) {
25     return MakeQuicTag(d, c, b, a);
26   }
27 };
28 
TEST_F(QuicVersionsTest,QuicVersionToQuicVersionLabel)29 TEST_F(QuicVersionsTest, QuicVersionToQuicVersionLabel) {
30   // If you add a new version to the QuicTransportVersion enum you will need to
31   // add a new case to QuicVersionToQuicVersionLabel, otherwise this test will
32   // fail.
33 
34   // Any logs would indicate an unsupported version which we don't expect.
35   CREATE_QUIC_MOCK_LOG(log);
36   EXPECT_QUIC_LOG_CALL(log).Times(0);
37   log.StartCapturingLogs();
38 
39   // Explicitly test a specific version.
40   EXPECT_EQ(MakeQuicTag('3', '4', '0', 'Q'),
41             QuicVersionToQuicVersionLabel(QUIC_VERSION_43));
42 
43   // Loop over all supported versions and make sure that we never hit the
44   // default case (i.e. all supported versions should be successfully converted
45   // to valid QuicVersionLabels).
46   for (QuicTransportVersion transport_version : SupportedTransportVersions()) {
47     if (!ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO, transport_version)) {
48       continue;
49     }
50     EXPECT_LT(0u, QuicVersionToQuicVersionLabel(transport_version));
51   }
52 }
53 
TEST_F(QuicVersionsTest,QuicVersionToQuicVersionLabelUnsupported)54 TEST_F(QuicVersionsTest, QuicVersionToQuicVersionLabelUnsupported) {
55   EXPECT_QUIC_BUG(
56       CreateQuicVersionLabel(UnsupportedQuicVersion()),
57       "Unsupported version QUIC_VERSION_UNSUPPORTED PROTOCOL_UNSUPPORTED");
58 }
59 
TEST_F(QuicVersionsTest,KnownAndValid)60 TEST_F(QuicVersionsTest, KnownAndValid) {
61   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
62     EXPECT_TRUE(version.IsKnown());
63     EXPECT_TRUE(ParsedQuicVersionIsValid(version.handshake_protocol,
64                                          version.transport_version));
65   }
66   ParsedQuicVersion unsupported = UnsupportedQuicVersion();
67   EXPECT_FALSE(unsupported.IsKnown());
68   EXPECT_TRUE(ParsedQuicVersionIsValid(unsupported.handshake_protocol,
69                                        unsupported.transport_version));
70   ParsedQuicVersion reserved = QuicVersionReservedForNegotiation();
71   EXPECT_TRUE(reserved.IsKnown());
72   EXPECT_TRUE(ParsedQuicVersionIsValid(reserved.handshake_protocol,
73                                        reserved.transport_version));
74   // Check that invalid combinations are not valid.
75   EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3, QUIC_VERSION_43));
76   EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
77                                         QUIC_VERSION_IETF_DRAFT_27));
78   // Check that deprecated versions are not valid.
79   EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
80                                         static_cast<QuicTransportVersion>(33)));
81   EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO,
82                                         static_cast<QuicTransportVersion>(99)));
83   EXPECT_FALSE(ParsedQuicVersionIsValid(PROTOCOL_TLS1_3,
84                                         static_cast<QuicTransportVersion>(99)));
85 }
86 
TEST_F(QuicVersionsTest,Features)87 TEST_F(QuicVersionsTest, Features) {
88   ParsedQuicVersion parsed_version_q043 = ParsedQuicVersion::Q043();
89   ParsedQuicVersion parsed_version_draft_27 = ParsedQuicVersion::Draft27();
90 
91   EXPECT_TRUE(parsed_version_q043.IsKnown());
92   EXPECT_FALSE(parsed_version_q043.KnowsWhichDecrypterToUse());
93   EXPECT_FALSE(parsed_version_q043.UsesInitialObfuscators());
94   EXPECT_FALSE(parsed_version_q043.AllowsLowFlowControlLimits());
95   EXPECT_FALSE(parsed_version_q043.HasHeaderProtection());
96   EXPECT_FALSE(parsed_version_q043.SupportsRetry());
97   EXPECT_FALSE(parsed_version_q043.HasRetryIntegrityTag());
98   EXPECT_FALSE(
99       parsed_version_q043.SendsVariableLengthPacketNumberInLongHeader());
100   EXPECT_FALSE(parsed_version_q043.AllowsVariableLengthConnectionIds());
101   EXPECT_FALSE(parsed_version_q043.SupportsClientConnectionIds());
102   EXPECT_FALSE(parsed_version_q043.HasLengthPrefixedConnectionIds());
103   EXPECT_FALSE(parsed_version_q043.SupportsAntiAmplificationLimit());
104   EXPECT_FALSE(parsed_version_q043.CanSendCoalescedPackets());
105   EXPECT_TRUE(parsed_version_q043.SupportsGoogleAltSvcFormat());
106   EXPECT_FALSE(parsed_version_q043.HasIetfInvariantHeader());
107   EXPECT_FALSE(parsed_version_q043.SupportsMessageFrames());
108   EXPECT_FALSE(parsed_version_q043.UsesHttp3());
109   EXPECT_FALSE(parsed_version_q043.HasLongHeaderLengths());
110   EXPECT_FALSE(parsed_version_q043.UsesCryptoFrames());
111   EXPECT_FALSE(parsed_version_q043.HasIetfQuicFrames());
112   EXPECT_FALSE(parsed_version_q043.HasHandshakeDone());
113   EXPECT_FALSE(parsed_version_q043.HasVarIntTransportParams());
114   EXPECT_FALSE(parsed_version_q043.UsesTls());
115   EXPECT_TRUE(parsed_version_q043.UsesQuicCrypto());
116 
117   EXPECT_TRUE(parsed_version_draft_27.IsKnown());
118   EXPECT_TRUE(parsed_version_draft_27.KnowsWhichDecrypterToUse());
119   EXPECT_TRUE(parsed_version_draft_27.UsesInitialObfuscators());
120   EXPECT_TRUE(parsed_version_draft_27.AllowsLowFlowControlLimits());
121   EXPECT_TRUE(parsed_version_draft_27.HasHeaderProtection());
122   EXPECT_TRUE(parsed_version_draft_27.SupportsRetry());
123   EXPECT_TRUE(parsed_version_draft_27.HasRetryIntegrityTag());
124   EXPECT_TRUE(
125       parsed_version_draft_27.SendsVariableLengthPacketNumberInLongHeader());
126   EXPECT_TRUE(parsed_version_draft_27.AllowsVariableLengthConnectionIds());
127   EXPECT_TRUE(parsed_version_draft_27.SupportsClientConnectionIds());
128   EXPECT_TRUE(parsed_version_draft_27.HasLengthPrefixedConnectionIds());
129   EXPECT_TRUE(parsed_version_draft_27.SupportsAntiAmplificationLimit());
130   EXPECT_TRUE(parsed_version_draft_27.CanSendCoalescedPackets());
131   EXPECT_FALSE(parsed_version_draft_27.SupportsGoogleAltSvcFormat());
132   EXPECT_TRUE(parsed_version_draft_27.HasIetfInvariantHeader());
133   EXPECT_TRUE(parsed_version_draft_27.SupportsMessageFrames());
134   EXPECT_TRUE(parsed_version_draft_27.UsesHttp3());
135   EXPECT_TRUE(parsed_version_draft_27.HasLongHeaderLengths());
136   EXPECT_TRUE(parsed_version_draft_27.UsesCryptoFrames());
137   EXPECT_TRUE(parsed_version_draft_27.HasIetfQuicFrames());
138   EXPECT_TRUE(parsed_version_draft_27.HasHandshakeDone());
139   EXPECT_TRUE(parsed_version_draft_27.HasVarIntTransportParams());
140   EXPECT_TRUE(parsed_version_draft_27.UsesTls());
141   EXPECT_FALSE(parsed_version_draft_27.UsesQuicCrypto());
142 }
143 
TEST_F(QuicVersionsTest,QuicVersionLabelToQuicTransportVersion)144 TEST_F(QuicVersionsTest, QuicVersionLabelToQuicTransportVersion) {
145   // If you add a new version to the QuicTransportVersion enum you will need to
146   // add a new case to QuicVersionLabelToQuicTransportVersion, otherwise this
147   // test will fail.
148 
149   // Any logs would indicate an unsupported version which we don't expect.
150   CREATE_QUIC_MOCK_LOG(log);
151   EXPECT_QUIC_LOG_CALL(log).Times(0);
152   log.StartCapturingLogs();
153 
154   // Explicitly test specific versions.
155   EXPECT_EQ(QUIC_VERSION_43,
156             QuicVersionLabelToQuicVersion(MakeQuicTag('3', '4', '0', 'Q')));
157 
158   for (QuicTransportVersion transport_version : SupportedTransportVersions()) {
159     if (!ParsedQuicVersionIsValid(PROTOCOL_QUIC_CRYPTO, transport_version)) {
160       continue;
161     }
162 
163     // Get the label from the version (we can loop over QuicVersions easily).
164     QuicVersionLabel version_label =
165         QuicVersionToQuicVersionLabel(transport_version);
166     EXPECT_LT(0u, version_label);
167 
168     // Now try converting back.
169     QuicTransportVersion label_to_transport_version =
170         QuicVersionLabelToQuicVersion(version_label);
171     EXPECT_EQ(transport_version, label_to_transport_version);
172     EXPECT_NE(QUIC_VERSION_UNSUPPORTED, label_to_transport_version);
173   }
174 }
175 
TEST_F(QuicVersionsTest,QuicVersionLabelToQuicVersionUnsupported)176 TEST_F(QuicVersionsTest, QuicVersionLabelToQuicVersionUnsupported) {
177   CREATE_QUIC_MOCK_LOG(log);
178   if (QUIC_DLOG_INFO_IS_ON()) {
179     EXPECT_QUIC_LOG_CALL_CONTAINS(log, INFO,
180                                   "Unsupported QuicVersionLabel version: EKAF")
181         .Times(1);
182   }
183   log.StartCapturingLogs();
184 
185   EXPECT_EQ(QUIC_VERSION_UNSUPPORTED,
186             QuicVersionLabelToQuicVersion(MakeQuicTag('F', 'A', 'K', 'E')));
187 }
188 
TEST_F(QuicVersionsTest,QuicVersionLabelToHandshakeProtocol)189 TEST_F(QuicVersionsTest, QuicVersionLabelToHandshakeProtocol) {
190   CREATE_QUIC_MOCK_LOG(log);
191   EXPECT_QUIC_LOG_CALL(log).Times(0);
192   log.StartCapturingLogs();
193 
194   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
195     if (version.handshake_protocol != PROTOCOL_QUIC_CRYPTO) {
196       continue;
197     }
198     QuicVersionLabel version_label =
199         QuicVersionToQuicVersionLabel(version.transport_version);
200     EXPECT_EQ(PROTOCOL_QUIC_CRYPTO,
201               QuicVersionLabelToHandshakeProtocol(version_label));
202   }
203 
204   // Test a TLS version:
205   QuicTag tls_tag = MakeQuicTag('0', '5', '0', 'T');
206   EXPECT_EQ(PROTOCOL_TLS1_3, QuicVersionLabelToHandshakeProtocol(tls_tag));
207 }
208 
TEST_F(QuicVersionsTest,ParseQuicVersionLabel)209 TEST_F(QuicVersionsTest, ParseQuicVersionLabel) {
210   EXPECT_EQ(ParsedQuicVersion::Q043(),
211             ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '3')));
212   EXPECT_EQ(ParsedQuicVersion::Q046(),
213             ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '4', '6')));
214   EXPECT_EQ(ParsedQuicVersion::Q050(),
215             ParseQuicVersionLabel(MakeVersionLabel('Q', '0', '5', '0')));
216   EXPECT_EQ(ParsedQuicVersion::T050(),
217             ParseQuicVersionLabel(MakeVersionLabel('T', '0', '5', '0')));
218 }
219 
TEST_F(QuicVersionsTest,ParseQuicVersionString)220 TEST_F(QuicVersionsTest, ParseQuicVersionString) {
221   EXPECT_EQ(ParsedQuicVersion::Q043(), ParseQuicVersionString("Q043"));
222   EXPECT_EQ(ParsedQuicVersion::Q046(),
223             ParseQuicVersionString("QUIC_VERSION_46"));
224   EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("46"));
225   EXPECT_EQ(ParsedQuicVersion::Q046(), ParseQuicVersionString("Q046"));
226   EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("Q050"));
227   EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("50"));
228   EXPECT_EQ(ParsedQuicVersion::Q050(), ParseQuicVersionString("h3-Q050"));
229 
230   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString(""));
231   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q 46"));
232   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("Q046 "));
233   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("99"));
234   EXPECT_EQ(UnsupportedQuicVersion(), ParseQuicVersionString("70"));
235 
236   EXPECT_EQ(ParsedQuicVersion::T050(), ParseQuicVersionString("T050"));
237   EXPECT_EQ(ParsedQuicVersion::T050(), ParseQuicVersionString("h3-T050"));
238   EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("ff00001d"));
239   EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("draft29"));
240   EXPECT_EQ(ParsedQuicVersion::Draft29(), ParseQuicVersionString("h3-29"));
241   EXPECT_EQ(ParsedQuicVersion::Draft27(), ParseQuicVersionString("ff00001b"));
242   EXPECT_EQ(ParsedQuicVersion::Draft27(), ParseQuicVersionString("draft27"));
243   EXPECT_EQ(ParsedQuicVersion::Draft27(), ParseQuicVersionString("h3-27"));
244 
245   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
246     EXPECT_EQ(version,
247               ParseQuicVersionString(ParsedQuicVersionToString(version)));
248   }
249 }
250 
TEST_F(QuicVersionsTest,ParseQuicVersionVectorString)251 TEST_F(QuicVersionsTest, ParseQuicVersionVectorString) {
252   ParsedQuicVersion version_q046(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_46);
253   ParsedQuicVersion version_q050(PROTOCOL_QUIC_CRYPTO, QUIC_VERSION_50);
254   ParsedQuicVersion version_t050(PROTOCOL_TLS1_3, QUIC_VERSION_50);
255   ParsedQuicVersion version_draft_27(PROTOCOL_TLS1_3,
256                                      QUIC_VERSION_IETF_DRAFT_27);
257   ParsedQuicVersion version_draft_29 = ParsedQuicVersion::Draft29();
258 
259   EXPECT_THAT(ParseQuicVersionVectorString(""), IsEmpty());
260 
261   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50"),
262               ElementsAre(version_q050));
263   EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050"),
264               ElementsAre(version_q050));
265   EXPECT_THAT(ParseQuicVersionVectorString("h3-T050"),
266               ElementsAre(version_t050));
267 
268   EXPECT_THAT(ParseQuicVersionVectorString("h3-27, h3-29"),
269               ElementsAre(version_draft_27, version_draft_29));
270   EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-27,h3-29"),
271               ElementsAre(version_draft_29, version_draft_27));
272   EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-27, h3-29"),
273               ElementsAre(version_draft_29, version_draft_27));
274   EXPECT_THAT(ParseQuicVersionVectorString("h3-27,h3-29"),
275               ElementsAre(version_draft_27, version_draft_29));
276   EXPECT_THAT(ParseQuicVersionVectorString("h3-29,h3-27"),
277               ElementsAre(version_draft_29, version_draft_27));
278 
279   EXPECT_THAT(ParseQuicVersionVectorString("h3-27,50"),
280               ElementsAre(version_draft_27, version_q050));
281 
282   EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-T050"),
283               ElementsAre(version_q050, version_t050));
284   EXPECT_THAT(ParseQuicVersionVectorString("h3-T050, h3-Q050"),
285               ElementsAre(version_t050, version_q050));
286   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,h3-T050"),
287               ElementsAre(version_q050, version_t050));
288   EXPECT_THAT(ParseQuicVersionVectorString("h3-T050,QUIC_VERSION_50"),
289               ElementsAre(version_t050, version_q050));
290   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-T050"),
291               ElementsAre(version_q050, version_t050));
292   EXPECT_THAT(ParseQuicVersionVectorString("h3-T050, QUIC_VERSION_50"),
293               ElementsAre(version_t050, version_q050));
294 
295   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50,QUIC_VERSION_46"),
296               ElementsAre(version_q050, version_q046));
297   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_46,QUIC_VERSION_50"),
298               ElementsAre(version_q046, version_q050));
299 
300   // Regression test for https://crbug.com/1044952.
301   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, QUIC_VERSION_50"),
302               ElementsAre(version_q050));
303   EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, h3-Q050"),
304               ElementsAre(version_q050));
305   EXPECT_THAT(ParseQuicVersionVectorString("h3-T050, h3-T050"),
306               ElementsAre(version_t050));
307   EXPECT_THAT(ParseQuicVersionVectorString("h3-Q050, QUIC_VERSION_50"),
308               ElementsAre(version_q050));
309   EXPECT_THAT(ParseQuicVersionVectorString(
310                   "QUIC_VERSION_50, h3-Q050, QUIC_VERSION_50, h3-Q050"),
311               ElementsAre(version_q050));
312   EXPECT_THAT(ParseQuicVersionVectorString("QUIC_VERSION_50, h3-T050, h3-Q050"),
313               ElementsAre(version_q050, version_t050));
314 
315   EXPECT_THAT(ParseQuicVersionVectorString("99"), IsEmpty());
316   EXPECT_THAT(ParseQuicVersionVectorString("70"), IsEmpty());
317   EXPECT_THAT(ParseQuicVersionVectorString("h3-01"), IsEmpty());
318   EXPECT_THAT(ParseQuicVersionVectorString("h3-01,h3-29"),
319               ElementsAre(version_draft_29));
320 }
321 
TEST_F(QuicVersionsTest,CreateQuicVersionLabel)322 TEST_F(QuicVersionsTest, CreateQuicVersionLabel) {
323   EXPECT_EQ(MakeVersionLabel('Q', '0', '4', '3'),
324             CreateQuicVersionLabel(ParsedQuicVersion::Q043()));
325   EXPECT_EQ(MakeVersionLabel('Q', '0', '4', '6'),
326             CreateQuicVersionLabel(ParsedQuicVersion::Q046()));
327   EXPECT_EQ(MakeVersionLabel('Q', '0', '5', '0'),
328             CreateQuicVersionLabel(ParsedQuicVersion::Q050()));
329 
330   // Test a TLS version:
331   EXPECT_EQ(MakeVersionLabel('T', '0', '5', '0'),
332             CreateQuicVersionLabel(ParsedQuicVersion::T050()));
333 
334   // Make sure the negotiation reserved version is in the IETF reserved space.
335   EXPECT_EQ(
336       MakeVersionLabel(0xda, 0x5a, 0x3a, 0x3a) & 0x0f0f0f0f,
337       CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()) &
338           0x0f0f0f0f);
339 
340   // Make sure that disabling randomness works.
341   SetQuicFlag(FLAGS_quic_disable_version_negotiation_grease_randomness, true);
342   EXPECT_EQ(
343       MakeVersionLabel(0xda, 0x5a, 0x3a, 0x3a),
344       CreateQuicVersionLabel(ParsedQuicVersion::ReservedForNegotiation()));
345 }
346 
TEST_F(QuicVersionsTest,QuicVersionLabelToString)347 TEST_F(QuicVersionsTest, QuicVersionLabelToString) {
348   QuicVersionLabelVector version_labels = {
349       MakeVersionLabel('Q', '0', '3', '5'),
350       MakeVersionLabel('Q', '0', '3', '7'),
351       MakeVersionLabel('T', '0', '3', '8'),
352   };
353 
354   EXPECT_EQ("Q035", QuicVersionLabelToString(version_labels[0]));
355   EXPECT_EQ("T038", QuicVersionLabelToString(version_labels[2]));
356 
357   EXPECT_EQ("Q035,Q037,T038", QuicVersionLabelVectorToString(version_labels));
358   EXPECT_EQ("Q035:Q037:T038",
359             QuicVersionLabelVectorToString(version_labels, ":", 2));
360   EXPECT_EQ("Q035|Q037|...",
361             QuicVersionLabelVectorToString(version_labels, "|", 1));
362 
363   std::ostringstream os;
364   os << version_labels;
365   EXPECT_EQ("Q035,Q037,T038", os.str());
366 }
367 
TEST_F(QuicVersionsTest,QuicVersionToString)368 TEST_F(QuicVersionsTest, QuicVersionToString) {
369   EXPECT_EQ("QUIC_VERSION_UNSUPPORTED",
370             QuicVersionToString(QUIC_VERSION_UNSUPPORTED));
371 
372   QuicTransportVersion single_version[] = {QUIC_VERSION_43};
373   QuicTransportVersionVector versions_vector;
374   for (size_t i = 0; i < ABSL_ARRAYSIZE(single_version); ++i) {
375     versions_vector.push_back(single_version[i]);
376   }
377   EXPECT_EQ("QUIC_VERSION_43",
378             QuicTransportVersionVectorToString(versions_vector));
379 
380   QuicTransportVersion multiple_versions[] = {QUIC_VERSION_UNSUPPORTED,
381                                               QUIC_VERSION_43};
382   versions_vector.clear();
383   for (size_t i = 0; i < ABSL_ARRAYSIZE(multiple_versions); ++i) {
384     versions_vector.push_back(multiple_versions[i]);
385   }
386   EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43",
387             QuicTransportVersionVectorToString(versions_vector));
388 
389   // Make sure that all supported versions are present in QuicVersionToString.
390   for (QuicTransportVersion transport_version : SupportedTransportVersions()) {
391     EXPECT_NE("QUIC_VERSION_UNSUPPORTED",
392               QuicVersionToString(transport_version));
393   }
394 
395   std::ostringstream os;
396   os << versions_vector;
397   EXPECT_EQ("QUIC_VERSION_UNSUPPORTED,QUIC_VERSION_43", os.str());
398 }
399 
TEST_F(QuicVersionsTest,ParsedQuicVersionToString)400 TEST_F(QuicVersionsTest, ParsedQuicVersionToString) {
401   EXPECT_EQ("0", ParsedQuicVersionToString(ParsedQuicVersion::Unsupported()));
402   EXPECT_EQ("Q043", ParsedQuicVersionToString(ParsedQuicVersion::Q043()));
403   EXPECT_EQ("Q046", ParsedQuicVersionToString(ParsedQuicVersion::Q046()));
404   EXPECT_EQ("Q050", ParsedQuicVersionToString(ParsedQuicVersion::Q050()));
405   EXPECT_EQ("T050", ParsedQuicVersionToString(ParsedQuicVersion::T050()));
406   EXPECT_EQ("draft27", ParsedQuicVersionToString(ParsedQuicVersion::Draft27()));
407   EXPECT_EQ("draft29", ParsedQuicVersionToString(ParsedQuicVersion::Draft29()));
408 
409   ParsedQuicVersionVector versions_vector = {ParsedQuicVersion::Q043()};
410   EXPECT_EQ("Q043", ParsedQuicVersionVectorToString(versions_vector));
411 
412   versions_vector = {ParsedQuicVersion::Unsupported(),
413                      ParsedQuicVersion::Q043()};
414   EXPECT_EQ("0,Q043", ParsedQuicVersionVectorToString(versions_vector));
415   EXPECT_EQ("0:Q043", ParsedQuicVersionVectorToString(versions_vector, ":",
416                                                       versions_vector.size()));
417   EXPECT_EQ("0|...", ParsedQuicVersionVectorToString(versions_vector, "|", 0));
418 
419   // Make sure that all supported versions are present in
420   // ParsedQuicVersionToString.
421   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
422     EXPECT_NE("0", ParsedQuicVersionToString(version));
423   }
424 
425   std::ostringstream os;
426   os << versions_vector;
427   EXPECT_EQ("0,Q043", os.str());
428 }
429 
TEST_F(QuicVersionsTest,FilterSupportedVersionsAllVersions)430 TEST_F(QuicVersionsTest, FilterSupportedVersionsAllVersions) {
431   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
432     QuicEnableVersion(version);
433   }
434   ParsedQuicVersionVector expected_parsed_versions;
435   for (const ParsedQuicVersion& version : SupportedVersions()) {
436     expected_parsed_versions.push_back(version);
437   }
438   EXPECT_EQ(expected_parsed_versions,
439             FilterSupportedVersions(AllSupportedVersions()));
440   EXPECT_EQ(expected_parsed_versions, AllSupportedVersions());
441 }
442 
TEST_F(QuicVersionsTest,FilterSupportedVersionsWithoutFirstVersion)443 TEST_F(QuicVersionsTest, FilterSupportedVersionsWithoutFirstVersion) {
444   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
445     QuicEnableVersion(version);
446   }
447   QuicDisableVersion(AllSupportedVersions().front());
448   ParsedQuicVersionVector expected_parsed_versions;
449   for (const ParsedQuicVersion& version : SupportedVersions()) {
450     expected_parsed_versions.push_back(version);
451   }
452   expected_parsed_versions.erase(expected_parsed_versions.begin());
453   EXPECT_EQ(expected_parsed_versions,
454             FilterSupportedVersions(AllSupportedVersions()));
455 }
456 
TEST_F(QuicVersionsTest,LookUpVersionByIndex)457 TEST_F(QuicVersionsTest, LookUpVersionByIndex) {
458   QuicTransportVersionVector all_versions = {QUIC_VERSION_43};
459   int version_count = all_versions.size();
460   for (int i = -5; i <= version_count + 1; ++i) {
461     QuicTransportVersionVector index = VersionOfIndex(all_versions, i);
462     if (i >= 0 && i < version_count) {
463       EXPECT_EQ(all_versions[i], index[0]);
464     } else {
465       EXPECT_EQ(QUIC_VERSION_UNSUPPORTED, index[0]);
466     }
467   }
468 }
469 
TEST_F(QuicVersionsTest,LookUpParsedVersionByIndex)470 TEST_F(QuicVersionsTest, LookUpParsedVersionByIndex) {
471   ParsedQuicVersionVector all_versions = AllSupportedVersions();
472   int version_count = all_versions.size();
473   for (int i = -5; i <= version_count + 1; ++i) {
474     ParsedQuicVersionVector index = ParsedVersionOfIndex(all_versions, i);
475     if (i >= 0 && i < version_count) {
476       EXPECT_EQ(all_versions[i], index[0]);
477     } else {
478       EXPECT_EQ(UnsupportedQuicVersion(), index[0]);
479     }
480   }
481 }
482 
TEST_F(QuicVersionsTest,ParsedVersionsToTransportVersions)483 TEST_F(QuicVersionsTest, ParsedVersionsToTransportVersions) {
484   ParsedQuicVersionVector all_versions = AllSupportedVersions();
485   QuicTransportVersionVector transport_versions =
486       ParsedVersionsToTransportVersions(all_versions);
487   ASSERT_EQ(all_versions.size(), transport_versions.size());
488   for (size_t i = 0; i < all_versions.size(); ++i) {
489     EXPECT_EQ(transport_versions[i], all_versions[i].transport_version);
490   }
491 }
492 
493 // This test may appear to be so simplistic as to be unnecessary,
494 // yet a typo was made in doing the #defines and it was caught
495 // only in some test far removed from here... Better safe than sorry.
TEST_F(QuicVersionsTest,CheckTransportVersionNumbersForTypos)496 TEST_F(QuicVersionsTest, CheckTransportVersionNumbersForTypos) {
497   static_assert(SupportedTransportVersions().size() == 6u,
498                 "Supported versions out of sync");
499   EXPECT_EQ(QUIC_VERSION_43, 43);
500   EXPECT_EQ(QUIC_VERSION_46, 46);
501   EXPECT_EQ(QUIC_VERSION_50, 50);
502   EXPECT_EQ(QUIC_VERSION_51, 51);
503   EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_27, 71);
504   EXPECT_EQ(QUIC_VERSION_IETF_DRAFT_29, 73);
505 }
506 
TEST_F(QuicVersionsTest,AlpnForVersion)507 TEST_F(QuicVersionsTest, AlpnForVersion) {
508   static_assert(SupportedVersions().size() == 7u,
509                 "Supported versions out of sync");
510   EXPECT_EQ("h3-Q043", AlpnForVersion(ParsedQuicVersion::Q043()));
511   EXPECT_EQ("h3-Q046", AlpnForVersion(ParsedQuicVersion::Q046()));
512   EXPECT_EQ("h3-Q050", AlpnForVersion(ParsedQuicVersion::Q050()));
513   EXPECT_EQ("h3-T050", AlpnForVersion(ParsedQuicVersion::T050()));
514   EXPECT_EQ("h3-T051", AlpnForVersion(ParsedQuicVersion::T051()));
515   EXPECT_EQ("h3-27", AlpnForVersion(ParsedQuicVersion::Draft27()));
516   EXPECT_EQ("h3-29", AlpnForVersion(ParsedQuicVersion::Draft29()));
517 }
518 
TEST_F(QuicVersionsTest,QuicVersionEnabling)519 TEST_F(QuicVersionsTest, QuicVersionEnabling) {
520   for (const ParsedQuicVersion& version : AllSupportedVersions()) {
521     QuicFlagSaver flag_saver;
522     QuicDisableVersion(version);
523     EXPECT_FALSE(QuicVersionIsEnabled(version));
524     QuicEnableVersion(version);
525     EXPECT_TRUE(QuicVersionIsEnabled(version));
526   }
527 }
528 
TEST_F(QuicVersionsTest,ReservedForNegotiation)529 TEST_F(QuicVersionsTest, ReservedForNegotiation) {
530   EXPECT_EQ(QUIC_VERSION_RESERVED_FOR_NEGOTIATION,
531             QuicVersionReservedForNegotiation().transport_version);
532   // QUIC_VERSION_RESERVED_FOR_NEGOTIATION MUST NOT be added to
533   // kSupportedTransportVersions.
534   for (QuicTransportVersion transport_version : SupportedTransportVersions()) {
535     EXPECT_NE(QUIC_VERSION_RESERVED_FOR_NEGOTIATION, transport_version);
536   }
537 }
538 
TEST_F(QuicVersionsTest,SupportedVersionsHasCorrectList)539 TEST_F(QuicVersionsTest, SupportedVersionsHasCorrectList) {
540   size_t index = 0;
541   for (HandshakeProtocol handshake_protocol : SupportedHandshakeProtocols()) {
542     for (QuicTransportVersion transport_version :
543          SupportedTransportVersions()) {
544       SCOPED_TRACE(index);
545       if (ParsedQuicVersionIsValid(handshake_protocol, transport_version)) {
546         ParsedQuicVersion version = SupportedVersions()[index];
547         EXPECT_EQ(version,
548                   ParsedQuicVersion(handshake_protocol, transport_version));
549         index++;
550       }
551     }
552   }
553   EXPECT_EQ(SupportedVersions().size(), index);
554 }
555 
TEST_F(QuicVersionsTest,SupportedVersionsAllDistinct)556 TEST_F(QuicVersionsTest, SupportedVersionsAllDistinct) {
557   for (size_t index1 = 0; index1 < SupportedVersions().size(); ++index1) {
558     ParsedQuicVersion version1 = SupportedVersions()[index1];
559     for (size_t index2 = index1 + 1; index2 < SupportedVersions().size();
560          ++index2) {
561       ParsedQuicVersion version2 = SupportedVersions()[index2];
562       EXPECT_NE(version1, version2) << version1 << " " << version2;
563       EXPECT_NE(CreateQuicVersionLabel(version1),
564                 CreateQuicVersionLabel(version2))
565           << version1 << " " << version2;
566       EXPECT_NE(AlpnForVersion(version1), AlpnForVersion(version2))
567           << version1 << " " << version2;
568     }
569   }
570 }
571 
572 }  // namespace
573 }  // namespace test
574 }  // namespace quic
575