xref: /aosp_15_r20/external/cronet/net/quic/quic_session_pool_test_base.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2024 The Chromium Authors
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/quic/quic_session_pool_test_base.h"
6 
7 #include <sys/types.h>
8 
9 #include <memory>
10 #include <ostream>
11 #include <set>
12 #include <string>
13 #include <utility>
14 
15 #include "base/functional/bind.h"
16 #include "base/functional/callback.h"
17 #include "base/logging.h"
18 #include "base/run_loop.h"
19 #include "base/strings/string_util.h"
20 #include "base/test/bind.h"
21 #include "base/test/scoped_feature_list.h"
22 #include "base/test/simple_test_tick_clock.h"
23 #include "base/test/test_mock_time_task_runner.h"
24 #include "base/time/time.h"
25 #include "net/base/features.h"
26 #include "net/base/host_port_pair.h"
27 #include "net/base/http_user_agent_settings.h"
28 #include "net/base/load_flags.h"
29 #include "net/base/mock_network_change_notifier.h"
30 #include "net/base/net_error_details.h"
31 #include "net/base/net_errors.h"
32 #include "net/base/network_anonymization_key.h"
33 #include "net/base/proxy_chain.h"
34 #include "net/base/proxy_server.h"
35 #include "net/base/schemeful_site.h"
36 #include "net/base/session_usage.h"
37 #include "net/base/test_proxy_delegate.h"
38 #include "net/cert/mock_cert_verifier.h"
39 #include "net/dns/mock_host_resolver.h"
40 #include "net/dns/public/dns_query_type.h"
41 #include "net/dns/public/host_resolver_source.h"
42 #include "net/dns/public/secure_dns_policy.h"
43 #include "net/http/http_response_headers.h"
44 #include "net/http/http_response_info.h"
45 #include "net/http/http_server_properties.h"
46 #include "net/http/http_util.h"
47 #include "net/http/transport_security_state.h"
48 #include "net/http/transport_security_state_test_util.h"
49 #include "net/quic/address_utils.h"
50 #include "net/quic/crypto/proof_verifier_chromium.h"
51 #include "net/quic/mock_crypto_client_stream_factory.h"
52 #include "net/quic/mock_quic_context.h"
53 #include "net/quic/mock_quic_data.h"
54 #include "net/quic/properties_based_quic_server_info.h"
55 #include "net/quic/quic_chromium_alarm_factory.h"
56 #include "net/quic/quic_chromium_client_session.h"
57 #include "net/quic/quic_chromium_client_session_peer.h"
58 #include "net/quic/quic_context.h"
59 #include "net/quic/quic_http_stream.h"
60 #include "net/quic/quic_http_utils.h"
61 #include "net/quic/quic_server_info.h"
62 #include "net/quic/quic_session_key.h"
63 #include "net/quic/quic_session_pool_peer.h"
64 #include "net/quic/quic_test_packet_maker.h"
65 #include "net/quic/quic_test_packet_printer.h"
66 #include "net/quic/test_task_runner.h"
67 #include "net/socket/next_proto.h"
68 #include "net/socket/socket_tag.h"
69 #include "net/socket/socket_test_util.h"
70 #include "net/spdy/spdy_session_test_util.h"
71 #include "net/spdy/spdy_test_util_common.h"
72 #include "net/ssl/test_ssl_config_service.h"
73 #include "net/test/cert_test_util.h"
74 #include "net/test/gtest_util.h"
75 #include "net/test/test_data_directory.h"
76 #include "net/test/test_with_task_environment.h"
77 #include "net/third_party/quiche/src/quiche/common/quiche_data_writer.h"
78 #include "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_handshake.h"
79 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_client_config.h"
80 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.h"
81 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.h"
82 #include "net/third_party/quiche/src/quiche/quic/core/quic_constants.h"
83 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
84 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h"
85 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
86 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
87 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_config_peer.h"
88 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h"
89 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_path_validator_peer.h"
90 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_session_peer.h"
91 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
92 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
93 #include "net/third_party/quiche/src/quiche/spdy/test_tools/spdy_test_utils.h"
94 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
95 #include "net/url_request/static_http_user_agent_settings.h"
96 #include "testing/gmock/include/gmock/gmock.h"
97 #include "testing/gtest/include/gtest/gtest.h"
98 #include "url/gurl.h"
99 #include "url/scheme_host_port.h"
100 #include "url/url_constants.h"
101 
102 using std::string;
103 
104 namespace net::test {
105 
RequestBuilder(QuicSessionPoolTestBase * test,QuicSessionPool * pool)106 QuicSessionPoolTestBase::RequestBuilder::RequestBuilder(
107     QuicSessionPoolTestBase* test,
108     QuicSessionPool* pool)
109     : quic_version(test->version_),
110       net_log(test->net_log_),
111       failed_on_default_network_callback(
112           test->failed_on_default_network_callback_),
113       callback(test->callback_.callback()),
114       request(pool) {}
RequestBuilder(QuicSessionPoolTestBase * test)115 QuicSessionPoolTestBase::RequestBuilder::RequestBuilder(
116     QuicSessionPoolTestBase* test)
117     : RequestBuilder(test, test->factory_.get()) {}
118 QuicSessionPoolTestBase::RequestBuilder::~RequestBuilder() = default;
119 
CallRequest()120 int QuicSessionPoolTestBase::RequestBuilder::CallRequest() {
121   return request.Request(
122       std::move(destination), quic_version, proxy_chain,
123       std::move(proxy_annotation_tag), http_user_agent_settings, session_usage,
124       privacy_mode, priority, socket_tag, network_anonymization_key,
125       secure_dns_policy, require_dns_https_alpn, cert_verify_flags, url,
126       net_log, &net_error_details,
127       std::move(failed_on_default_network_callback), std::move(callback));
128 }
QuicSessionPoolTestBase(quic::ParsedQuicVersion version,std::vector<base::test::FeatureRef> enabled_features,std::vector<base::test::FeatureRef> disabled_features)129 QuicSessionPoolTestBase::QuicSessionPoolTestBase(
130     quic::ParsedQuicVersion version,
131     std::vector<base::test::FeatureRef> enabled_features,
132     std::vector<base::test::FeatureRef> disabled_features)
133     : host_resolver_(std::make_unique<MockHostResolver>(
134           /*default_result=*/MockHostResolverBase::RuleResolver::
135               GetLocalhostResult())),
136       socket_factory_(std::make_unique<MockClientSocketFactory>()),
137       version_(version),
138       client_maker_(version_,
139                     quic::QuicUtils::CreateRandomConnectionId(
140                         context_.random_generator()),
141                     context_.clock(),
142                     kDefaultServerHostName,
143                     quic::Perspective::IS_CLIENT,
144                     /*client_priority_uses_incremental=*/true,
145                     /*use_priority_header=*/true),
146       server_maker_(version_,
147                     quic::QuicUtils::CreateRandomConnectionId(
148                         context_.random_generator()),
149                     context_.clock(),
150                     kDefaultServerHostName,
151                     quic::Perspective::IS_SERVER,
152                     /*client_priority_uses_incremental=*/false,
153                     /*use_priority_header=*/false),
154       http_server_properties_(std::make_unique<HttpServerProperties>()),
155       cert_verifier_(std::make_unique<MockCertVerifier>()),
156       failed_on_default_network_callback_(base::BindRepeating(
157           &QuicSessionPoolTestBase::OnFailedOnDefaultNetwork,
158           base::Unretained(this))),
159       quic_params_(context_.params()) {
160   enabled_features.push_back(features::kAsyncQuicSession);
161   scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
162   FLAGS_quic_enable_http3_grease_randomness = false;
163   context_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
164 
165   // It's important that different proxies have different IPs, to avoid
166   // pooling them together.
167   host_resolver_->rules()->AddRule(kProxy1HostName, "127.0.1.1");
168   host_resolver_->rules()->AddRule(kProxy2HostName, "127.0.1.2");
169 }
170 
171 QuicSessionPoolTestBase::~QuicSessionPoolTestBase() = default;
Initialize()172 void QuicSessionPoolTestBase::Initialize() {
173   DCHECK(!factory_);
174   factory_ = std::make_unique<QuicSessionPool>(
175       net_log_.net_log(), host_resolver_.get(), &ssl_config_service_,
176       socket_factory_.get(), http_server_properties_.get(),
177       cert_verifier_.get(), &transport_security_state_, proxy_delegate_.get(),
178       /*sct_auditing_delegate=*/nullptr,
179       /*SocketPerformanceWatcherFactory*/ nullptr,
180       &crypto_client_stream_factory_, &context_);
181 }
182 
MaybeMakeNewConnectionIdAvailableToSession(const quic::QuicConnectionId & new_cid,quic::QuicSession * session,uint64_t sequence_number)183 void QuicSessionPoolTestBase::MaybeMakeNewConnectionIdAvailableToSession(
184     const quic::QuicConnectionId& new_cid,
185     quic::QuicSession* session,
186     uint64_t sequence_number) {
187   quic::QuicNewConnectionIdFrame new_cid_frame;
188   new_cid_frame.connection_id = new_cid;
189   new_cid_frame.sequence_number = sequence_number;
190   new_cid_frame.retire_prior_to = 0u;
191   new_cid_frame.stateless_reset_token =
192       quic::QuicUtils::GenerateStatelessResetToken(new_cid_frame.connection_id);
193   session->connection()->OnNewConnectionIdFrame(new_cid_frame);
194 }
195 
CreateStream(QuicSessionRequest * request)196 std::unique_ptr<HttpStream> QuicSessionPoolTestBase::CreateStream(
197     QuicSessionRequest* request) {
198   std::unique_ptr<QuicChromiumClientSession::Handle> session =
199       request->ReleaseSessionHandle();
200   if (!session || !session->IsConnected()) {
201     return nullptr;
202   }
203 
204   std::set<std::string> dns_aliases =
205       session->GetDnsAliasesForSessionKey(request->session_key());
206   return std::make_unique<QuicHttpStream>(std::move(session),
207                                           std::move(dns_aliases));
208 }
209 
HasActiveSession(const url::SchemeHostPort & scheme_host_port,const NetworkAnonymizationKey & network_anonymization_key,const ProxyChain & proxy_chain,SessionUsage session_usage,bool require_dns_https_alpn)210 bool QuicSessionPoolTestBase::HasActiveSession(
211     const url::SchemeHostPort& scheme_host_port,
212     const NetworkAnonymizationKey& network_anonymization_key,
213     const ProxyChain& proxy_chain,
214     SessionUsage session_usage,
215     bool require_dns_https_alpn) {
216   quic::QuicServerId server_id(scheme_host_port.host(), scheme_host_port.port(),
217                                false);
218   return QuicSessionPoolPeer::HasActiveSession(
219       factory_.get(), server_id, network_anonymization_key, proxy_chain,
220       session_usage, require_dns_https_alpn);
221 }
222 
HasActiveJob(const url::SchemeHostPort & scheme_host_port,const PrivacyMode privacy_mode,bool require_dns_https_alpn)223 bool QuicSessionPoolTestBase::HasActiveJob(
224     const url::SchemeHostPort& scheme_host_port,
225     const PrivacyMode privacy_mode,
226     bool require_dns_https_alpn) {
227   quic::QuicServerId server_id(scheme_host_port.host(), scheme_host_port.port(),
228                                privacy_mode == PRIVACY_MODE_ENABLED);
229   return QuicSessionPoolPeer::HasActiveJob(factory_.get(), server_id,
230                                            require_dns_https_alpn);
231 }
232 
233 // Get the pending, not activated session, if there is only one session alive.
GetPendingSession(const url::SchemeHostPort & scheme_host_port)234 QuicChromiumClientSession* QuicSessionPoolTestBase::GetPendingSession(
235     const url::SchemeHostPort& scheme_host_port) {
236   quic::QuicServerId server_id(scheme_host_port.host(), scheme_host_port.port(),
237                                false);
238   return QuicSessionPoolPeer::GetPendingSession(factory_.get(), server_id,
239                                                 scheme_host_port);
240 }
241 
GetActiveSession(const url::SchemeHostPort & scheme_host_port,const NetworkAnonymizationKey & network_anonymization_key,const ProxyChain & proxy_chain,SessionUsage session_usage,bool require_dns_https_alpn)242 QuicChromiumClientSession* QuicSessionPoolTestBase::GetActiveSession(
243     const url::SchemeHostPort& scheme_host_port,
244     const NetworkAnonymizationKey& network_anonymization_key,
245     const ProxyChain& proxy_chain,
246     SessionUsage session_usage,
247     bool require_dns_https_alpn) {
248   quic::QuicServerId server_id(scheme_host_port.host(), scheme_host_port.port(),
249                                false);
250   return QuicSessionPoolPeer::GetActiveSession(
251       factory_.get(), server_id, network_anonymization_key, proxy_chain,
252       session_usage, require_dns_https_alpn);
253 }
254 
GetSourcePortForNewSessionAndGoAway(const url::SchemeHostPort & destination)255 int QuicSessionPoolTestBase::GetSourcePortForNewSessionAndGoAway(
256     const url::SchemeHostPort& destination) {
257   return GetSourcePortForNewSessionInner(destination, true);
258 }
259 
GetSourcePortForNewSessionInner(const url::SchemeHostPort & destination,bool goaway_received)260 int QuicSessionPoolTestBase::GetSourcePortForNewSessionInner(
261     const url::SchemeHostPort& destination,
262     bool goaway_received) {
263   // Should only be called if there is no active session for this destination.
264   EXPECT_FALSE(HasActiveSession(destination));
265   size_t socket_count = socket_factory_->udp_client_socket_ports().size();
266 
267   MockQuicData socket_data(version_);
268   socket_data.AddReadPauseForever();
269   socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
270   socket_data.AddSocketDataToFactory(socket_factory_.get());
271 
272   GURL url("https://" + destination.host() + "/");
273   RequestBuilder builder(this);
274   builder.destination = destination;
275   builder.url = url;
276 
277   EXPECT_THAT(callback_.WaitForResult(), IsOk());
278   std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
279   EXPECT_TRUE(stream.get());
280   stream.reset();
281 
282   QuicChromiumClientSession* session = GetActiveSession(destination);
283 
284   if (socket_count + 1 != socket_factory_->udp_client_socket_ports().size()) {
285     ADD_FAILURE();
286     return 0;
287   }
288 
289   if (goaway_received) {
290     quic::QuicGoAwayFrame goaway(quic::kInvalidControlFrameId,
291                                  quic::QUIC_NO_ERROR, 1, "");
292     session->connection()->OnGoAwayFrame(goaway);
293   }
294 
295   factory_->OnSessionClosed(session);
296   EXPECT_FALSE(HasActiveSession(destination));
297   socket_data.ExpectAllReadDataConsumed();
298   socket_data.ExpectAllWriteDataConsumed();
299   return socket_factory_->udp_client_socket_ports()[socket_count];
300 }
301 
302 ProofVerifyDetailsChromium
DefaultProofVerifyDetails()303 QuicSessionPoolTestBase::DefaultProofVerifyDetails() {
304   // Load a certificate that is valid for *.example.org
305   scoped_refptr<X509Certificate> test_cert(
306       ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
307   EXPECT_TRUE(test_cert.get());
308   ProofVerifyDetailsChromium verify_details;
309   verify_details.cert_verify_result.verified_cert = test_cert;
310   verify_details.cert_verify_result.is_issued_by_known_root = true;
311   return verify_details;
312 }
313 
NotifyIPAddressChanged()314 void QuicSessionPoolTestBase::NotifyIPAddressChanged() {
315   NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
316   // Spin the message loop so the notification is delivered.
317   base::RunLoop().RunUntilIdle();
318 }
319 
320 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructServerConnectionClosePacket(uint64_t num)321 QuicSessionPoolTestBase::ConstructServerConnectionClosePacket(uint64_t num) {
322   return server_maker_.MakeConnectionClosePacket(
323       num, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
324 }
325 
326 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientRstPacket(uint64_t packet_number,quic::QuicRstStreamErrorCode error_code)327 QuicSessionPoolTestBase::ConstructClientRstPacket(
328     uint64_t packet_number,
329     quic::QuicRstStreamErrorCode error_code) {
330   quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
331   return client_maker_.MakeRstPacket(packet_number, stream_id, error_code);
332 }
333 
334 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructGetRequestPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin)335 QuicSessionPoolTestBase::ConstructGetRequestPacket(uint64_t packet_number,
336                                                    quic::QuicStreamId stream_id,
337                                                    bool fin) {
338   spdy::Http2HeaderBlock headers =
339       client_maker_.GetRequestHeaders("GET", "https", "/");
340   spdy::SpdyPriority priority =
341       ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
342   size_t spdy_headers_frame_len;
343   return client_maker_.MakeRequestHeadersPacket(packet_number, stream_id, fin,
344                                                 priority, std::move(headers),
345                                                 &spdy_headers_frame_len);
346 }
347 
348 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructConnectUdpRequestPacket(uint64_t packet_number,quic::QuicStreamId stream_id,std::string authority,std::string path,bool fin)349 QuicSessionPoolTestBase::ConstructConnectUdpRequestPacket(
350     uint64_t packet_number,
351     quic::QuicStreamId stream_id,
352     std::string authority,
353     std::string path,
354     bool fin) {
355   spdy::Http2HeaderBlock headers;
356   headers[":scheme"] = "https";
357   headers[":path"] = path;
358   headers[":protocol"] = "connect-udp";
359   headers[":method"] = "CONNECT";
360   headers[":authority"] = authority;
361   headers["user-agent"] = "test-ua";
362   headers["capsule-protocol"] = "?1";
363   spdy::SpdyPriority priority =
364       ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
365   size_t spdy_headers_frame_len;
366   auto rv = client_maker_.MakeRequestHeadersPacket(
367       packet_number, stream_id, fin, priority, std::move(headers),
368       &spdy_headers_frame_len, /*should_include_priority_frame=*/false);
369   return rv;
370 }
371 
372 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientH3DatagramPacket(uint64_t packet_number,uint64_t quarter_stream_id,uint64_t context_id,std::unique_ptr<quic::QuicEncryptedPacket> inner)373 QuicSessionPoolTestBase::ConstructClientH3DatagramPacket(
374     uint64_t packet_number,
375     uint64_t quarter_stream_id,
376     uint64_t context_id,
377     std::unique_ptr<quic::QuicEncryptedPacket> inner) {
378   std::string data;
379   // Allow enough space for payload and two varint-62's.
380   data.resize(inner->length() + 2 * 8);
381   quiche::QuicheDataWriter writer(data.capacity(), data.data());
382   CHECK(writer.WriteVarInt62(quarter_stream_id));
383   CHECK(writer.WriteVarInt62(context_id));
384   CHECK(writer.WriteBytes(inner->data(), inner->length()));
385   data.resize(writer.length());
386   return client_maker_.MakeDatagramPacket(packet_number, data);
387 }
388 
389 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructOkResponsePacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin)390 QuicSessionPoolTestBase::ConstructOkResponsePacket(uint64_t packet_number,
391                                                    quic::QuicStreamId stream_id,
392                                                    bool fin) {
393   spdy::Http2HeaderBlock headers = server_maker_.GetResponseHeaders("200");
394   size_t spdy_headers_frame_len;
395   return server_maker_.MakeResponseHeadersPacket(packet_number, stream_id, fin,
396                                                  std::move(headers),
397                                                  &spdy_headers_frame_len);
398 }
399 
400 std::unique_ptr<quic::QuicReceivedPacket>
ConstructInitialSettingsPacket()401 QuicSessionPoolTestBase::ConstructInitialSettingsPacket() {
402   return client_maker_.MakeInitialSettingsPacket(1);
403 }
404 
405 std::unique_ptr<quic::QuicReceivedPacket>
ConstructInitialSettingsPacket(uint64_t packet_number)406 QuicSessionPoolTestBase::ConstructInitialSettingsPacket(
407     uint64_t packet_number) {
408   return client_maker_.MakeInitialSettingsPacket(packet_number);
409 }
410 
411 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructServerSettingsPacket(uint64_t packet_number)412 QuicSessionPoolTestBase::ConstructServerSettingsPacket(uint64_t packet_number) {
413   return server_maker_.MakeInitialSettingsPacket(packet_number);
414 }
415 
ConstructDataHeader(size_t body_len)416 std::string QuicSessionPoolTestBase::ConstructDataHeader(size_t body_len) {
417   quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
418       body_len, quiche::SimpleBufferAllocator::Get());
419   return std::string(buffer.data(), buffer.size());
420 }
421 
422 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructServerDataPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,std::string_view data)423 QuicSessionPoolTestBase::ConstructServerDataPacket(uint64_t packet_number,
424                                                    quic::QuicStreamId stream_id,
425                                                    bool fin,
426                                                    std::string_view data) {
427   return server_maker_.MakeDataPacket(packet_number, stream_id, fin, data);
428 }
429 
430 quic::QuicStreamId
GetNthClientInitiatedBidirectionalStreamId(int n) const431 QuicSessionPoolTestBase::GetNthClientInitiatedBidirectionalStreamId(
432     int n) const {
433   return quic::test::GetNthClientInitiatedBidirectionalStreamId(
434       version_.transport_version, n);
435 }
436 
GetQpackDecoderStreamId() const437 quic::QuicStreamId QuicSessionPoolTestBase::GetQpackDecoderStreamId() const {
438   return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
439       version_.transport_version, 1);
440 }
441 
StreamCancellationQpackDecoderInstruction(int n) const442 std::string QuicSessionPoolTestBase::StreamCancellationQpackDecoderInstruction(
443     int n) const {
444   return StreamCancellationQpackDecoderInstruction(n, true);
445 }
446 
StreamCancellationQpackDecoderInstruction(int n,bool create_stream) const447 std::string QuicSessionPoolTestBase::StreamCancellationQpackDecoderInstruction(
448     int n,
449     bool create_stream) const {
450   const quic::QuicStreamId cancelled_stream_id =
451       GetNthClientInitiatedBidirectionalStreamId(n);
452   EXPECT_LT(cancelled_stream_id, 63u);
453 
454   const char opcode = 0x40;
455   if (create_stream) {
456     return {0x03, static_cast<char>(opcode | cancelled_stream_id)};
457   } else {
458     return {static_cast<char>(opcode | cancelled_stream_id)};
459   }
460 }
461 
462 quic::QuicStreamId
GetNthServerInitiatedUnidirectionalStreamId(int n)463 QuicSessionPoolTestBase::GetNthServerInitiatedUnidirectionalStreamId(int n) {
464   return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
465       version_.transport_version, n);
466 }
467 
OnFailedOnDefaultNetwork(int rv)468 void QuicSessionPoolTestBase::OnFailedOnDefaultNetwork(int rv) {
469   failed_on_default_network_ = true;
470 }
471 
472 }  // namespace net::test
473