Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(581)

Side by Side Diff: net/http/http_stream_factory_impl_job_controller_unittest.cc

Issue 2910463004: Revert "Revert CLs landed in HttpStreamFactoryImpl to track down a crasher" (Closed)
Patch Set: rebased Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_stream_factory_impl_job_controller.h" 5 #include "net/http/http_stream_factory_impl_job_controller.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/memory/ptr_util.h" 11 #include "base/memory/ptr_util.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h"
13 #include "base/test/histogram_tester.h" 14 #include "base/test/histogram_tester.h"
14 #include "base/test/scoped_feature_list.h" 15 #include "base/test/scoped_feature_list.h"
15 #include "base/test/scoped_mock_time_message_loop_task_runner.h" 16 #include "base/test/scoped_mock_time_message_loop_task_runner.h"
16 #include "base/threading/platform_thread.h" 17 #include "base/threading/platform_thread.h"
17 #include "net/base/test_proxy_delegate.h" 18 #include "net/base/test_proxy_delegate.h"
18 #include "net/dns/mock_host_resolver.h" 19 #include "net/dns/mock_host_resolver.h"
19 #include "net/http/http_basic_stream.h" 20 #include "net/http/http_basic_stream.h"
21 #include "net/http/http_stream_factory_impl.h"
22 #include "net/http/http_stream_factory_impl_job.h"
20 #include "net/http/http_stream_factory_impl_request.h" 23 #include "net/http/http_stream_factory_impl_request.h"
21 #include "net/http/http_stream_factory_test_util.h" 24 #include "net/http/http_stream_factory_test_util.h"
22 #include "net/log/net_log_with_source.h" 25 #include "net/log/net_log_with_source.h"
23 #include "net/proxy/mock_proxy_resolver.h" 26 #include "net/proxy/mock_proxy_resolver.h"
24 #include "net/proxy/proxy_config_service_fixed.h" 27 #include "net/proxy/proxy_config_service_fixed.h"
25 #include "net/proxy/proxy_info.h" 28 #include "net/proxy/proxy_info.h"
26 #include "net/proxy/proxy_service.h" 29 #include "net/proxy/proxy_service.h"
30 #include "net/quic/chromium/mock_crypto_client_stream_factory.h"
31 #include "net/quic/chromium/mock_quic_data.h"
32 #include "net/quic/chromium/quic_stream_factory.h"
27 #include "net/quic/chromium/quic_stream_factory_peer.h" 33 #include "net/quic/chromium/quic_stream_factory_peer.h"
34 #include "net/quic/chromium/quic_test_packet_maker.h"
35 #include "net/quic/test_tools/mock_random.h"
28 #include "net/socket/socket_test_util.h" 36 #include "net/socket/socket_test_util.h"
29 #include "net/spdy/chromium/spdy_test_util_common.h" 37 #include "net/spdy/chromium/spdy_test_util_common.h"
30 #include "testing/gmock/include/gmock/gmock.h" 38 #include "testing/gmock/include/gmock/gmock.h"
31 #include "testing/gmock_mutant.h" 39 #include "testing/gmock_mutant.h"
32 #include "testing/gtest/include/gtest/gtest.h" 40 #include "testing/gtest/include/gtest/gtest.h"
33 41
34 using ::testing::_; 42 using ::testing::_;
35 using ::testing::Invoke; 43 using ::testing::Invoke;
36 44
37 namespace net { 45 namespace net {
38 46
39 namespace { 47 namespace {
40 48
49 const char kServerHostname[] = "www.example.com";
50
51 // List of errors that are used in the proxy resolution tests.
52 const int proxy_test_mock_errors[] = {
53 ERR_PROXY_CONNECTION_FAILED,
54 ERR_NAME_NOT_RESOLVED,
55 ERR_ADDRESS_UNREACHABLE,
56 ERR_CONNECTION_CLOSED,
57 ERR_CONNECTION_TIMED_OUT,
58 ERR_CONNECTION_RESET,
59 ERR_CONNECTION_REFUSED,
60 ERR_CONNECTION_ABORTED,
61 ERR_TIMED_OUT,
62 ERR_TUNNEL_CONNECTION_FAILED,
63 ERR_SOCKS_CONNECTION_FAILED,
64 ERR_PROXY_CERTIFICATE_INVALID,
65 ERR_QUIC_PROTOCOL_ERROR,
66 ERR_QUIC_HANDSHAKE_FAILED,
67 ERR_SSL_PROTOCOL_ERROR,
68 ERR_MSG_TOO_BIG,
69 };
70
41 void DeleteHttpStreamPointer(const SSLConfig& used_ssl_config, 71 void DeleteHttpStreamPointer(const SSLConfig& used_ssl_config,
42 const ProxyInfo& used_proxy_info, 72 const ProxyInfo& used_proxy_info,
43 HttpStream* stream) { 73 HttpStream* stream) {
44 delete stream; 74 delete stream;
45 } 75 }
46 76
47 class FailingProxyResolverFactory : public ProxyResolverFactory { 77 class FailingProxyResolverFactory : public ProxyResolverFactory {
48 public: 78 public:
49 FailingProxyResolverFactory() : ProxyResolverFactory(false) {} 79 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
50 80
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 // Start() is mocked for MockHttpStreamFactoryImplJob. 137 // Start() is mocked for MockHttpStreamFactoryImplJob.
108 // This is the alternative method to invoke real Start() method on Job. 138 // This is the alternative method to invoke real Start() method on Job.
109 job->stream_type_ = stream_type; 139 job->stream_type_ = stream_type;
110 job->StartInternal(); 140 job->StartInternal();
111 } 141 }
112 142
113 // Returns |num_streams_| of |job|. It should be 0 for non-preconnect Jobs. 143 // Returns |num_streams_| of |job|. It should be 0 for non-preconnect Jobs.
114 static int GetNumStreams(const HttpStreamFactoryImpl::Job* job) { 144 static int GetNumStreams(const HttpStreamFactoryImpl::Job* job) {
115 return job->num_streams_; 145 return job->num_streams_;
116 } 146 }
147
148 // Return SpdySessionKey of |job|.
149 static const SpdySessionKey GetSpdySessionKey(
150 const HttpStreamFactoryImpl::Job* job) {
151 return job->GetSpdySessionKey();
152 }
117 }; 153 };
118 154
119 class JobControllerPeer { 155 class JobControllerPeer {
120 public: 156 public:
121 static bool main_job_is_blocked( 157 static bool main_job_is_blocked(
122 HttpStreamFactoryImpl::JobController* job_controller) { 158 HttpStreamFactoryImpl::JobController* job_controller) {
123 return job_controller->main_job_is_blocked_; 159 return job_controller->main_job_is_blocked_;
124 } 160 }
161 static bool main_job_is_resumed(
162 HttpStreamFactoryImpl::JobController* job_controller) {
163 return job_controller->main_job_is_resumed_;
164 }
125 }; 165 };
126 166
127 class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { 167 class HttpStreamFactoryImplJobControllerTest : public ::testing::Test {
128 public: 168 public:
129 HttpStreamFactoryImplJobControllerTest() 169 HttpStreamFactoryImplJobControllerTest()
130 : session_deps_(ProxyService::CreateDirect()), 170 : session_deps_(ProxyService::CreateDirect()),
171 random_generator_(0),
172 client_maker_(HttpNetworkSession::Params().quic_supported_versions[0],
173 0,
174 &clock_,
175 kServerHostname,
176 Perspective::IS_CLIENT),
131 use_alternative_proxy_(false), 177 use_alternative_proxy_(false),
132 is_preconnect_(false), 178 is_preconnect_(false),
133 enable_ip_based_pooling_(true), 179 enable_ip_based_pooling_(true),
134 enable_alternative_services_(true), 180 enable_alternative_services_(true),
135 test_proxy_delegate_(nullptr) { 181 test_proxy_delegate_(nullptr) {
136 session_deps_.enable_quic = true; 182 session_deps_.enable_quic = true;
137 } 183 }
138 184
139 void UseAlternativeProxy() { 185 void UseAlternativeProxy() {
140 ASSERT_FALSE(test_proxy_delegate_); 186 ASSERT_FALSE(test_proxy_delegate_);
(...skipping 18 matching lines...) Expand all
159 void Initialize(const HttpRequestInfo& request_info) { 205 void Initialize(const HttpRequestInfo& request_info) {
160 ASSERT_FALSE(test_proxy_delegate_); 206 ASSERT_FALSE(test_proxy_delegate_);
161 auto test_proxy_delegate = base::MakeUnique<TestProxyDelegate>(); 207 auto test_proxy_delegate = base::MakeUnique<TestProxyDelegate>();
162 test_proxy_delegate_ = test_proxy_delegate.get(); 208 test_proxy_delegate_ = test_proxy_delegate.get();
163 209
164 test_proxy_delegate->set_alternative_proxy_server( 210 test_proxy_delegate->set_alternative_proxy_server(
165 ProxyServer::FromPacString("QUIC myproxy.org:443")); 211 ProxyServer::FromPacString("QUIC myproxy.org:443"));
166 EXPECT_TRUE(test_proxy_delegate->alternative_proxy_server().is_quic()); 212 EXPECT_TRUE(test_proxy_delegate->alternative_proxy_server().is_quic());
167 session_deps_.proxy_delegate = std::move(test_proxy_delegate); 213 session_deps_.proxy_delegate = std::move(test_proxy_delegate);
168 214
215 if (quic_data_)
216 quic_data_->AddSocketDataToFactory(session_deps_.socket_factory.get());
217 if (tcp_data_)
218 session_deps_.socket_factory->AddSocketDataProvider(tcp_data_.get());
219
169 if (use_alternative_proxy_) { 220 if (use_alternative_proxy_) {
170 std::unique_ptr<ProxyService> proxy_service = 221 std::unique_ptr<ProxyService> proxy_service =
171 ProxyService::CreateFixedFromPacResult("HTTPS myproxy.org:443"); 222 ProxyService::CreateFixedFromPacResult("HTTPS myproxy.org:443");
172 session_deps_.proxy_service = std::move(proxy_service); 223 session_deps_.proxy_service = std::move(proxy_service);
173 } 224 }
174 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); 225 HttpNetworkSession::Params params =
226 SpdySessionDependencies::CreateSessionParams(&session_deps_);
227 HttpNetworkSession::Context session_context =
228 SpdySessionDependencies::CreateSessionContext(&session_deps_);
229
230 session_context.quic_crypto_client_stream_factory =
231 &crypto_client_stream_factory_;
232 session_context.quic_random = &random_generator_;
233 session_ = base::MakeUnique<HttpNetworkSession>(params, session_context);
175 factory_ = 234 factory_ =
176 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); 235 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory());
177 job_controller_ = new HttpStreamFactoryImpl::JobController( 236 job_controller_ = new HttpStreamFactoryImpl::JobController(
178 factory_, &request_delegate_, session_.get(), &job_factory_, 237 factory_, &request_delegate_, session_.get(), &job_factory_,
179 request_info, is_preconnect_, enable_ip_based_pooling_, 238 request_info, is_preconnect_, enable_ip_based_pooling_,
180 enable_alternative_services_); 239 enable_alternative_services_, SSLConfig(), SSLConfig());
181 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); 240 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_);
182 } 241 }
183 242
184 TestProxyDelegate* test_proxy_delegate() const { 243 TestProxyDelegate* test_proxy_delegate() const {
185 return test_proxy_delegate_; 244 return test_proxy_delegate_;
186 } 245 }
187 246
188 ~HttpStreamFactoryImplJobControllerTest() override {} 247 ~HttpStreamFactoryImplJobControllerTest() override {
248 if (quic_data_) {
249 EXPECT_TRUE(quic_data_->AllReadDataConsumed());
250 EXPECT_TRUE(quic_data_->AllWriteDataConsumed());
251 }
252 if (tcp_data_) {
253 EXPECT_TRUE(tcp_data_->AllReadDataConsumed());
254 EXPECT_TRUE(tcp_data_->AllWriteDataConsumed());
255 }
256 }
189 257
190 void SetAlternativeService(const HttpRequestInfo& request_info, 258 void SetAlternativeService(const HttpRequestInfo& request_info,
191 AlternativeService alternative_service) { 259 AlternativeService alternative_service) {
192 HostPortPair host_port_pair = HostPortPair::FromURL(request_info.url); 260 HostPortPair host_port_pair = HostPortPair::FromURL(request_info.url);
193 url::SchemeHostPort server(request_info.url); 261 url::SchemeHostPort server(request_info.url);
194 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); 262 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
195 session_->http_server_properties()->SetAlternativeService( 263 session_->http_server_properties()->SetAlternativeService(
196 server, alternative_service, expiration); 264 server, alternative_service, expiration);
197 } 265 }
198 266
199 void VerifyBrokenAlternateProtocolMapping(const HttpRequestInfo& request_info, 267 void VerifyBrokenAlternateProtocolMapping(const HttpRequestInfo& request_info,
200 bool should_mark_broken) { 268 bool should_mark_broken) {
201 const url::SchemeHostPort server(request_info.url); 269 const url::SchemeHostPort server(request_info.url);
202 const AlternativeServiceInfoVector alternative_service_info_vector = 270 const AlternativeServiceInfoVector alternative_service_info_vector =
203 session_->http_server_properties()->GetAlternativeServiceInfos(server); 271 session_->http_server_properties()->GetAlternativeServiceInfos(server);
204 EXPECT_EQ(1u, alternative_service_info_vector.size()); 272 EXPECT_EQ(1u, alternative_service_info_vector.size());
205 EXPECT_EQ(should_mark_broken, 273 EXPECT_EQ(should_mark_broken,
206 session_->http_server_properties()->IsAlternativeServiceBroken( 274 session_->http_server_properties()->IsAlternativeServiceBroken(
207 alternative_service_info_vector[0].alternative_service)); 275 alternative_service_info_vector[0].alternative_service));
208 } 276 }
209 277
210 TestJobFactory job_factory_; 278 TestJobFactory job_factory_;
211 MockHttpStreamRequestDelegate request_delegate_; 279 MockHttpStreamRequestDelegate request_delegate_;
212 SpdySessionDependencies session_deps_; 280 SpdySessionDependencies session_deps_;
213 std::unique_ptr<HttpNetworkSession> session_; 281 std::unique_ptr<HttpNetworkSession> session_;
214 HttpStreamFactoryImpl* factory_; 282 HttpStreamFactoryImpl* factory_;
215 HttpStreamFactoryImpl::JobController* job_controller_; 283 HttpStreamFactoryImpl::JobController* job_controller_;
216 std::unique_ptr<HttpStreamFactoryImpl::Request> request_; 284 std::unique_ptr<HttpStreamFactoryImpl::Request> request_;
217 285 std::unique_ptr<SequencedSocketData> tcp_data_;
218 private: 286 std::unique_ptr<test::MockQuicData> quic_data_;
287 MockCryptoClientStreamFactory crypto_client_stream_factory_;
288 MockClock clock_;
289 test::MockRandom random_generator_;
290 test::QuicTestPacketMaker client_maker_;
291
292 protected:
219 bool use_alternative_proxy_; 293 bool use_alternative_proxy_;
220 bool is_preconnect_; 294 bool is_preconnect_;
221 bool enable_ip_based_pooling_; 295 bool enable_ip_based_pooling_;
222 bool enable_alternative_services_; 296 bool enable_alternative_services_;
223 297
298 private:
224 // Not owned by |this|. 299 // Not owned by |this|.
225 TestProxyDelegate* test_proxy_delegate_; 300 TestProxyDelegate* test_proxy_delegate_;
226 301
227 DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest); 302 DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest);
228 }; 303 };
229 304
230 TEST_F(HttpStreamFactoryImplJobControllerTest, 305 TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsSync) {
231 OnStreamFailedWithNoAlternativeJob) {
232 ProxyConfig proxy_config; 306 ProxyConfig proxy_config;
233 proxy_config.set_auto_detect(true); 307 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
234 // Use asynchronous proxy resolver. 308 proxy_config.set_pac_mandatory(true);
309 MockAsyncProxyResolver resolver;
310 session_deps_.proxy_service.reset(new ProxyService(
311 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
312 base::WrapUnique(new FailingProxyResolverFactory), nullptr));
313 HttpRequestInfo request_info;
314 request_info.method = "GET";
315 request_info.url = GURL("http://www.google.com");
316
317 Initialize(request_info);
318
319 EXPECT_CALL(request_delegate_,
320 OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _))
321 .Times(1);
322 request_ =
323 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
324 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
325
326 EXPECT_FALSE(job_controller_->main_job());
327 EXPECT_FALSE(job_controller_->alternative_job());
328
329 // Make sure calling GetLoadState() when before job creation does not crash.
330 // Regression test for crbug.com/723920.
331 EXPECT_EQ(LOAD_STATE_IDLE, job_controller_->GetLoadState());
332
333 base::RunLoop().RunUntilIdle();
334 request_.reset();
335 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
336 }
337
338 TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsAsync) {
339 ProxyConfig proxy_config;
340 proxy_config.set_pac_url(GURL("http://fooproxyurl"));
341 proxy_config.set_pac_mandatory(true);
235 MockAsyncProxyResolverFactory* proxy_resolver_factory = 342 MockAsyncProxyResolverFactory* proxy_resolver_factory =
236 new MockAsyncProxyResolverFactory(false); 343 new MockAsyncProxyResolverFactory(false);
344 MockAsyncProxyResolver resolver;
237 session_deps_.proxy_service.reset( 345 session_deps_.proxy_service.reset(
238 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), 346 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
239 base::WrapUnique(proxy_resolver_factory), nullptr)); 347 base::WrapUnique(proxy_resolver_factory), nullptr));
240 348 HttpRequestInfo request_info;
241 HttpRequestInfo request_info; 349 request_info.method = "GET";
242 request_info.method = "GET"; 350 request_info.url = GURL("http://www.google.com");
351
352 Initialize(request_info);
353
354 request_ =
355 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
356 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
357
358 EXPECT_FALSE(job_controller_->main_job());
359 EXPECT_FALSE(job_controller_->alternative_job());
360
361 EXPECT_EQ(LOAD_STATE_RESOLVING_PROXY_FOR_URL,
362 job_controller_->GetLoadState());
363
364 EXPECT_CALL(request_delegate_,
365 OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _))
366 .Times(1);
367 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
368 ERR_FAILED, &resolver);
369 base::RunLoop().RunUntilIdle();
370 request_.reset();
371 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
372 }
373
374 TEST_F(HttpStreamFactoryImplJobControllerTest, NoSupportedProxies) {
375 session_deps_.proxy_service =
376 ProxyService::CreateFixedFromPacResult("QUIC myproxy.org:443");
377 session_deps_.enable_quic = false;
378 HttpRequestInfo request_info;
379 request_info.method = "GET";
380 request_info.url = GURL("http://www.google.com");
381
382 Initialize(request_info);
383
384 EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_NO_SUPPORTED_PROXIES, _))
385 .Times(1);
386 request_ =
387 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
388 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
389
390 EXPECT_FALSE(job_controller_->main_job());
391 EXPECT_FALSE(job_controller_->alternative_job());
392
393 base::RunLoop().RunUntilIdle();
394 request_.reset();
395 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
396 }
397
398 class JobControllerReconsiderProxyAfterErrorTest
399 : public HttpStreamFactoryImplJobControllerTest,
400 public ::testing::WithParamInterface<::testing::tuple<bool, int>> {
401 public:
402 void Initialize(std::unique_ptr<ProxyService> proxy_service,
403 std::unique_ptr<ProxyDelegate> proxy_delegate) {
404 session_deps_.proxy_delegate = std::move(proxy_delegate);
405 session_deps_.proxy_service = std::move(proxy_service);
406 session_ = base::MakeUnique<HttpNetworkSession>(
407 SpdySessionDependencies::CreateSessionParams(&session_deps_),
408 SpdySessionDependencies::CreateSessionContext(&session_deps_));
409 factory_ =
410 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory());
411 }
412
413 std::unique_ptr<HttpStreamRequest> CreateJobController(
414 const HttpRequestInfo& request_info) {
415 HttpStreamFactoryImpl::JobController* job_controller =
416 new HttpStreamFactoryImpl::JobController(
417 factory_, &request_delegate_, session_.get(), &default_job_factory_,
418 request_info, is_preconnect_, enable_ip_based_pooling_,
419 enable_alternative_services_, SSLConfig(), SSLConfig());
420 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller);
421 return job_controller->Start(
422 &request_delegate_, nullptr, NetLogWithSource(),
423 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
424 }
425
426 private:
427 // Use real Jobs so that Job::Resume() is not mocked out. When main job is
428 // resumed it will use mock socket data.
429 HttpStreamFactoryImpl::JobFactory default_job_factory_;
430 };
431
432 INSTANTIATE_TEST_CASE_P(
433 /* no prefix */,
434 JobControllerReconsiderProxyAfterErrorTest,
435 ::testing::Combine(::testing::Bool(),
436 testing::ValuesIn(proxy_test_mock_errors)));
437
438 TEST_P(JobControllerReconsiderProxyAfterErrorTest, ReconsiderProxyAfterError) {
439 const bool set_alternative_proxy_server = ::testing::get<0>(GetParam());
440 const int mock_error = ::testing::get<1>(GetParam());
441 std::unique_ptr<ProxyService> proxy_service =
442 ProxyService::CreateFixedFromPacResult(
443 "HTTPS badproxy:99; HTTPS badfallbackproxy:98; DIRECT");
444 std::unique_ptr<TestProxyDelegate> test_proxy_delegate =
445 base::MakeUnique<TestProxyDelegate>();
446 TestProxyDelegate* test_proxy_delegate_raw = test_proxy_delegate.get();
447
448 // Before starting the test, verify that there are no proxies marked as bad.
449 ASSERT_TRUE(proxy_service->proxy_retry_info().empty()) << mock_error;
450
451 StaticSocketDataProvider socket_data_proxy_main_job;
452 socket_data_proxy_main_job.set_connect_data(MockConnect(ASYNC, mock_error));
453 session_deps_.socket_factory->AddSocketDataProvider(
454 &socket_data_proxy_main_job);
455
456 StaticSocketDataProvider socket_data_proxy_alternate_job;
457 if (set_alternative_proxy_server) {
458 // Mock socket used by the QUIC job.
459 socket_data_proxy_alternate_job.set_connect_data(
460 MockConnect(ASYNC, mock_error));
461 session_deps_.socket_factory->AddSocketDataProvider(
462 &socket_data_proxy_alternate_job);
463 test_proxy_delegate->set_alternative_proxy_server(
464 ProxyServer::FromPacString("QUIC badproxy:99"));
465 }
466
467 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
468
469 // When retrying the job using the second proxy (badFallback:98),
470 // alternative job must not be created. So, socket data for only the
471 // main job is needed.
472 StaticSocketDataProvider socket_data_proxy_main_job_2;
473 socket_data_proxy_main_job_2.set_connect_data(MockConnect(ASYNC, mock_error));
474 session_deps_.socket_factory->AddSocketDataProvider(
475 &socket_data_proxy_main_job_2);
476 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
477
478 // First request would use DIRECT, and succeed.
479 StaticSocketDataProvider socket_data_direct_first_request;
480 socket_data_direct_first_request.set_connect_data(MockConnect(ASYNC, OK));
481 session_deps_.socket_factory->AddSocketDataProvider(
482 &socket_data_direct_first_request);
483 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
484
485 // Second request would use DIRECT, and succeed.
486 StaticSocketDataProvider socket_data_direct_second_request;
487 socket_data_direct_second_request.set_connect_data(MockConnect(ASYNC, OK));
488 session_deps_.socket_factory->AddSocketDataProvider(
489 &socket_data_direct_second_request);
490 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
491
492 // Now request a stream. It should succeed using the DIRECT.
493 HttpRequestInfo request_info;
494 request_info.method = "GET";
495 request_info.url = GURL("http://www.example.com");
496
497 Initialize(std::move(proxy_service), std::move(test_proxy_delegate));
498 EXPECT_EQ(set_alternative_proxy_server,
499 test_proxy_delegate_raw->alternative_proxy_server().is_quic());
500
501 // Start two requests. The first request should consume data from
502 // |socket_data_proxy_main_job|,
503 // |socket_data_proxy_alternate_job| and
504 // |socket_data_direct_first_request|. The second request should consume
505 // data from |socket_data_direct_second_request|.
506
507 for (size_t i = 0; i < 2; ++i) {
508 ProxyInfo used_proxy_info;
509 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
510 .Times(1)
511 .WillOnce(DoAll(::testing::SaveArg<1>(&used_proxy_info),
512 Invoke(DeleteHttpStreamPointer)));
513
514 std::unique_ptr<HttpStreamRequest> request =
515 CreateJobController(request_info);
516
517 base::RunLoop().RunUntilIdle();
518 // The proxy that failed should now be known to the proxy_service as
519 // bad.
520 const ProxyRetryInfoMap retry_info =
521 session_->proxy_service()->proxy_retry_info();
522 EXPECT_EQ(2u, retry_info.size()) << mock_error;
523 EXPECT_NE(retry_info.end(), retry_info.find("https://badproxy:99"));
524 EXPECT_NE(retry_info.end(), retry_info.find("https://badfallbackproxy:98"));
525
526 // Verify that request was fetched without proxy.
527 EXPECT_TRUE(used_proxy_info.is_direct());
528
529 // If alternative proxy server was specified, it should have been marked
530 // as invalid so that it is not used for subsequent requests.
531 EXPECT_FALSE(
532 test_proxy_delegate_raw->alternative_proxy_server().is_valid());
533
534 if (set_alternative_proxy_server) {
535 // GetAlternativeProxy should be called only once for the first
536 // request.
537 EXPECT_EQ(1,
538 test_proxy_delegate_raw->get_alternative_proxy_invocations());
539 } else {
540 // Alternative proxy server job is never started. So, ProxyDelegate is
541 // queried once per request.
542 EXPECT_EQ(2,
543 test_proxy_delegate_raw->get_alternative_proxy_invocations());
544 }
545 }
546 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
547 }
548
549 TEST_F(HttpStreamFactoryImplJobControllerTest,
550 OnStreamFailedWithNoAlternativeJob) {
551 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
552 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
553
554 HttpRequestInfo request_info;
555 request_info.method = "GET";
243 request_info.url = GURL("http://www.google.com"); 556 request_info.url = GURL("http://www.google.com");
244 557
245 Initialize(request_info); 558 Initialize(request_info);
246 559
247 request_.reset( 560 request_ =
248 job_controller_->Start(request_info, &request_delegate_, nullptr, 561 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
249 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 562 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
250 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
251 563
252 EXPECT_TRUE(job_controller_->main_job()); 564 EXPECT_TRUE(job_controller_->main_job());
565 EXPECT_FALSE(job_controller_->alternative_job());
253 566
254 // There's no other alternative job. Thus when stream failed, it should 567 // There's no other alternative job. Thus when stream failed, it should
255 // notify Request of the stream failure. 568 // notify Request of the stream failure.
256 EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_FAILED, _)).Times(1); 569 EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_FAILED, _)).Times(1);
257 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, 570 base::RunLoop().RunUntilIdle();
258 SSLConfig());
259 } 571 }
260 572
261 TEST_F(HttpStreamFactoryImplJobControllerTest, 573 TEST_F(HttpStreamFactoryImplJobControllerTest,
262 OnStreamReadyWithNoAlternativeJob) { 574 OnStreamReadyWithNoAlternativeJob) {
263 ProxyConfig proxy_config; 575 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
264 proxy_config.set_auto_detect(true); 576 tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
265 // Use asynchronous proxy resolver. 577
266 MockAsyncProxyResolverFactory* proxy_resolver_factory =
267 new MockAsyncProxyResolverFactory(false);
268 session_deps_.proxy_service.reset(
269 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
270 base::WrapUnique(proxy_resolver_factory), nullptr));
271 HttpRequestInfo request_info; 578 HttpRequestInfo request_info;
272 request_info.method = "GET"; 579 request_info.method = "GET";
273 request_info.url = GURL("http://www.google.com"); 580 request_info.url = GURL("http://www.google.com");
274 581
275 Initialize(request_info); 582 Initialize(request_info);
276 583
277 request_.reset( 584 request_ =
278 job_controller_->Start(request_info, &request_delegate_, nullptr, 585 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
279 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 586 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
280 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
281 587
282 // There's no other alternative job. Thus when a stream is ready, it should 588 // There's no other alternative job. Thus when a stream is ready, it should
283 // notify Request. 589 // notify Request.
284 HttpStream* http_stream = 590 EXPECT_TRUE(job_controller_->main_job());
285 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
286 job_factory_.main_job()->SetStream(http_stream);
287 591
288 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) 592 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
289 .WillOnce(Invoke(DeleteHttpStreamPointer)); 593 .WillOnce(Invoke(DeleteHttpStreamPointer));
290 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); 594 base::RunLoop().RunUntilIdle();
291 } 595 }
292 596
293 // Test we cancel Jobs correctly when the Request is explicitly canceled 597 // Test we cancel Jobs correctly when the Request is explicitly canceled
294 // before any Job is bound to Request. 598 // before any Job is bound to Request.
295 TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { 599 TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) {
296 ProxyConfig proxy_config; 600 // Use COLD_START to make the alt job pending.
297 proxy_config.set_auto_detect(true); 601 crypto_client_stream_factory_.set_handshake_mode(
298 // Use asynchronous proxy resolver. 602 MockCryptoClientStream::COLD_START);
299 MockAsyncProxyResolverFactory* proxy_resolver_factory = 603 quic_data_ = base::MakeUnique<test::MockQuicData>();
300 new MockAsyncProxyResolverFactory(false); 604 quic_data_->AddRead(SYNCHRONOUS, OK);
301 session_deps_.proxy_service.reset(new ProxyService(
302 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)),
303 base::WrapUnique(proxy_resolver_factory), nullptr));
304 605
606 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
607 tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
305 HttpRequestInfo request_info; 608 HttpRequestInfo request_info;
306 request_info.method = "GET"; 609 request_info.method = "GET";
307 request_info.url = GURL("https://www.google.com"); 610 request_info.url = GURL("https://www.google.com");
308 611
309 Initialize(request_info); 612 Initialize(request_info);
310 url::SchemeHostPort server(request_info.url); 613 url::SchemeHostPort server(request_info.url);
311 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 614 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
312 SetAlternativeService(request_info, alternative_service); 615 SetAlternativeService(request_info, alternative_service);
313 616
314 request_.reset( 617 request_ =
315 job_controller_->Start(request_info, &request_delegate_, nullptr, 618 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
316 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 619 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
317 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
318 EXPECT_TRUE(job_controller_->main_job()); 620 EXPECT_TRUE(job_controller_->main_job());
319 EXPECT_TRUE(job_controller_->alternative_job()); 621 EXPECT_TRUE(job_controller_->alternative_job());
320 622
321 // Reset the Request will cancel all the Jobs since there's no Job determined 623 // Reset the Request will cancel all the Jobs since there's no Job determined
322 // to serve Request yet and JobController will notify the factory to delete 624 // to serve Request yet and JobController will notify the factory to delete
323 // itself upon completion. 625 // itself upon completion.
324 request_.reset(); 626 request_.reset();
325 VerifyBrokenAlternateProtocolMapping(request_info, false); 627 VerifyBrokenAlternateProtocolMapping(request_info, false);
326 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 628 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
327 } 629 }
328 630
329 TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) { 631 TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) {
330 ProxyConfig proxy_config; 632 quic_data_ = base::MakeUnique<test::MockQuicData>();
331 proxy_config.set_auto_detect(true); 633 quic_data_->AddConnect(ASYNC, ERR_FAILED);
332 // Use asynchronous proxy resolver. 634 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
333 MockAsyncProxyResolverFactory* proxy_resolver_factory = 635 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
334 new MockAsyncProxyResolverFactory(false);
335 session_deps_.proxy_service.reset(
336 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
337 base::WrapUnique(proxy_resolver_factory), nullptr));
338 636
339 HttpRequestInfo request_info; 637 HttpRequestInfo request_info;
340 request_info.method = "GET"; 638 request_info.method = "GET";
341 request_info.url = GURL("https://www.google.com"); 639 request_info.url = GURL("https://www.google.com");
342 640
343 Initialize(request_info); 641 Initialize(request_info);
344 url::SchemeHostPort server(request_info.url); 642 url::SchemeHostPort server(request_info.url);
345 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 643 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
346 SetAlternativeService(request_info, alternative_service); 644 SetAlternativeService(request_info, alternative_service);
347 645
348 request_.reset( 646 request_ =
349 job_controller_->Start(request_info, &request_delegate_, nullptr, 647 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
350 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 648 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
351 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
352 EXPECT_TRUE(job_controller_->main_job()); 649 EXPECT_TRUE(job_controller_->main_job());
353 EXPECT_TRUE(job_controller_->alternative_job()); 650 EXPECT_TRUE(job_controller_->alternative_job());
354 651
355 // We have the main job with unknown status when the alternative job is failed
356 // thus should not notify Request of the alternative job's failure. But should
357 // notify the main job to mark the alternative job failed.
358 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
359 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED,
360 SSLConfig());
361 EXPECT_TRUE(!job_controller_->alternative_job());
362 EXPECT_TRUE(job_controller_->main_job());
363
364 // The failure of second Job should be reported to Request as there's no more 652 // The failure of second Job should be reported to Request as there's no more
365 // pending Job to serve the Request. 653 // pending Job to serve the Request.
366 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); 654 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1);
367 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, 655 base::RunLoop().RunUntilIdle();
368 SSLConfig());
369 VerifyBrokenAlternateProtocolMapping(request_info, false); 656 VerifyBrokenAlternateProtocolMapping(request_info, false);
657 request_.reset();
658 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
370 } 659 }
371 660
372 TEST_F(HttpStreamFactoryImplJobControllerTest, 661 TEST_F(HttpStreamFactoryImplJobControllerTest,
373 AltJobFailsAfterMainJobSucceeds) { 662 AltJobFailsAfterMainJobSucceeds) {
374 ProxyConfig proxy_config; 663 quic_data_ = base::MakeUnique<test::MockQuicData>();
375 proxy_config.set_auto_detect(true); 664 quic_data_->AddRead(ASYNC, ERR_FAILED);
376 // Use asynchronous proxy resolver. 665 crypto_client_stream_factory_.set_handshake_mode(
377 MockAsyncProxyResolverFactory* proxy_resolver_factory = 666 MockCryptoClientStream::COLD_START);
378 new MockAsyncProxyResolverFactory(false); 667
379 session_deps_.proxy_service.reset( 668 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
380 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), 669 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
381 base::WrapUnique(proxy_resolver_factory), nullptr)); 670 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(SYNCHRONOUS, OK);
671 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
382 672
383 HttpRequestInfo request_info; 673 HttpRequestInfo request_info;
384 request_info.method = "GET"; 674 request_info.method = "GET";
385 request_info.url = GURL("https://www.google.com"); 675 request_info.url = GURL("https://www.google.com");
386 676
387 Initialize(request_info); 677 Initialize(request_info);
388 url::SchemeHostPort server(request_info.url); 678 url::SchemeHostPort server(request_info.url);
389 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 679 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
390 SetAlternativeService(request_info, alternative_service); 680 SetAlternativeService(request_info, alternative_service);
391 681
392 request_.reset( 682 request_ =
393 job_controller_->Start(request_info, &request_delegate_, nullptr, 683 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
394 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 684 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
395 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
396 EXPECT_TRUE(job_controller_->main_job()); 685 EXPECT_TRUE(job_controller_->main_job());
397 EXPECT_TRUE(job_controller_->alternative_job()); 686 EXPECT_TRUE(job_controller_->alternative_job());
398 687
399 // Main job succeeds, starts serving Request and it should report status 688 // Main job succeeds, starts serving Request and it should report status
400 // to Request. The alternative job will mark the main job complete and gets 689 // to Request. The alternative job will mark the main job complete and gets
401 // orphaned. 690 // orphaned.
402 HttpStream* http_stream = 691 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
403 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
404 job_factory_.main_job()->SetStream(http_stream);
405
406 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
407 .WillOnce(Invoke(DeleteHttpStreamPointer)); 692 .WillOnce(Invoke(DeleteHttpStreamPointer));
408 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig());
409
410 // JobController shouldn't report the status of second job as request 693 // JobController shouldn't report the status of second job as request
411 // is already successfully served. 694 // is already successfully served.
412 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 695 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
413 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, 696
414 SSLConfig()); 697 base::RunLoop().RunUntilIdle();
415 698
416 VerifyBrokenAlternateProtocolMapping(request_info, true); 699 VerifyBrokenAlternateProtocolMapping(request_info, true);
417 // Reset the request as it's been successfully served. 700 // Reset the request as it's been successfully served.
418 request_.reset(); 701 request_.reset();
419 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 702 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
420 } 703 }
421 704
422 // Tests that if alt job succeeds and main job is blocked, main job should be 705 // Tests that if alt job succeeds and main job is blocked, main job should be
423 // cancelled immediately. |request_| completion will clean up the JobController. 706 // cancelled immediately. |request_| completion will clean up the JobController.
424 // Regression test for crbug.com/678768. 707 // Regression test for crbug.com/678768.
425 TEST_F(HttpStreamFactoryImplJobControllerTest, 708 TEST_F(HttpStreamFactoryImplJobControllerTest,
426 AltJobSucceedsMainJobBlockedControllerDestroyed) { 709 AltJobSucceedsMainJobBlockedControllerDestroyed) {
427 ProxyConfig proxy_config; 710 quic_data_ = base::MakeUnique<test::MockQuicData>();
428 proxy_config.set_auto_detect(true); 711 quic_data_->AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr));
429 MockAsyncProxyResolverFactory* proxy_resolver_factory = 712 quic_data_->AddRead(ASYNC, OK);
430 new MockAsyncProxyResolverFactory(false); 713
431 session_deps_.proxy_service.reset(
432 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
433 base::WrapUnique(proxy_resolver_factory), nullptr));
434 HttpRequestInfo request_info; 714 HttpRequestInfo request_info;
435 request_info.method = "GET"; 715 request_info.method = "GET";
436 request_info.url = GURL("https://www.google.com"); 716 request_info.url = GURL("https://www.google.com");
437 717
438 Initialize(request_info); 718 Initialize(request_info);
439 719
440 url::SchemeHostPort server(request_info.url); 720 url::SchemeHostPort server(request_info.url);
441 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 721 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
442 SetAlternativeService(request_info, alternative_service); 722 SetAlternativeService(request_info, alternative_service);
443 request_.reset( 723 request_ =
444 job_controller_->Start(request_info, &request_delegate_, nullptr, 724 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
445 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 725 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
446 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
447 EXPECT_TRUE(job_controller_->main_job()); 726 EXPECT_TRUE(job_controller_->main_job());
448 EXPECT_TRUE(job_controller_->alternative_job()); 727 EXPECT_TRUE(job_controller_->alternative_job());
449 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); 728 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
450 729
451 // |alternative_job| succeeds and should report status to Request. 730 // |alternative_job| succeeds and should report status to |request_delegate_|.
452 HttpStream* http_stream = 731 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
453 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
454 job_factory_.alternative_job()->SetStream(http_stream);
455 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
456 .WillOnce(Invoke(DeleteHttpStreamPointer)); 732 .WillOnce(Invoke(DeleteHttpStreamPointer));
457 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); 733
734 base::RunLoop().RunUntilIdle();
458 735
459 EXPECT_FALSE(job_controller_->main_job()); 736 EXPECT_FALSE(job_controller_->main_job());
460 EXPECT_TRUE(job_controller_->alternative_job()); 737 EXPECT_TRUE(job_controller_->alternative_job());
461 738
462 // Invoke OnRequestComplete() which should delete |job_controller_| from 739 // Invoke OnRequestComplete() which should delete |job_controller_| from
463 // |factory_|. 740 // |factory_|.
464 request_.reset(); 741 request_.reset();
465 VerifyBrokenAlternateProtocolMapping(request_info, false); 742 VerifyBrokenAlternateProtocolMapping(request_info, false);
466 // This fails without the fix for crbug.com/678768. 743 // This fails without the fix for crbug.com/678768.
467 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 744 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
468 } 745 }
469 746
747 TEST_F(HttpStreamFactoryImplJobControllerTest,
748 SpdySessionKeyHasOriginHostPortPair) {
749 session_deps_.enable_http2_alternative_service = true;
750
751 const char origin_host[] = "www.example.org";
752 const uint16_t origin_port = 443;
753 const char alternative_host[] = "mail.example.org";
754 const uint16_t alternative_port = 123;
755
756 HttpRequestInfo request_info;
757 request_info.method = "GET";
758 request_info.url =
759 GURL(base::StringPrintf("https://%s:%u", origin_host, origin_port));
760 Initialize(request_info);
761
762 url::SchemeHostPort server(request_info.url);
763 AlternativeService alternative_service(kProtoHTTP2, alternative_host,
764 alternative_port);
765 SetAlternativeService(request_info, alternative_service);
766
767 request_ =
768 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
769 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
770
771 HostPortPair main_host_port_pair =
772 HttpStreamFactoryImplJobPeer::GetSpdySessionKey(
773 job_controller_->main_job())
774 .host_port_pair();
775 EXPECT_EQ(origin_host, main_host_port_pair.host());
776 EXPECT_EQ(origin_port, main_host_port_pair.port());
777
778 HostPortPair alternative_host_port_pair =
779 HttpStreamFactoryImplJobPeer::GetSpdySessionKey(
780 job_controller_->alternative_job())
781 .host_port_pair();
782 EXPECT_EQ(origin_host, alternative_host_port_pair.host());
783 EXPECT_EQ(origin_port, alternative_host_port_pair.port());
784 }
785
470 // Tests that if an orphaned job completes after |request_| is gone, 786 // Tests that if an orphaned job completes after |request_| is gone,
471 // JobController will be cleaned up. 787 // JobController will be cleaned up.
472 TEST_F(HttpStreamFactoryImplJobControllerTest, 788 TEST_F(HttpStreamFactoryImplJobControllerTest,
473 OrphanedJobCompletesControllerDestroyed) { 789 OrphanedJobCompletesControllerDestroyed) {
474 ProxyConfig proxy_config; 790 quic_data_ = base::MakeUnique<test::MockQuicData>();
475 proxy_config.set_auto_detect(true); 791 quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
476 MockAsyncProxyResolverFactory* proxy_resolver_factory = 792 // Use cold start and complete alt job manually.
477 new MockAsyncProxyResolverFactory(false); 793 crypto_client_stream_factory_.set_handshake_mode(
478 session_deps_.proxy_service.reset( 794 MockCryptoClientStream::COLD_START);
479 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), 795
480 base::WrapUnique(proxy_resolver_factory), nullptr)); 796 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
797 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
798 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
799 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
800
481 HttpRequestInfo request_info; 801 HttpRequestInfo request_info;
482 request_info.method = "GET"; 802 request_info.method = "GET";
483 request_info.url = GURL("https://www.google.com"); 803 request_info.url = GURL("https://www.google.com");
484 804
485 Initialize(request_info); 805 Initialize(request_info);
486 806
487 url::SchemeHostPort server(request_info.url); 807 url::SchemeHostPort server(request_info.url);
488 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 808 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
489 SetAlternativeService(request_info, alternative_service); 809 SetAlternativeService(request_info, alternative_service);
490 // Hack to use different URL for the main job to help differentiate the proxy 810
491 // requests. 811 request_ =
492 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com")); 812 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
493 request_.reset( 813 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
494 job_controller_->Start(request_info, &request_delegate_, nullptr,
495 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM,
496 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
497 EXPECT_TRUE(job_controller_->main_job()); 814 EXPECT_TRUE(job_controller_->main_job());
498 EXPECT_TRUE(job_controller_->alternative_job()); 815 EXPECT_TRUE(job_controller_->alternative_job());
499 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); 816 // main job should not be blocked because alt job returned ERR_IO_PENDING.
817 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
818
819 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
820 .WillOnce(Invoke(DeleteHttpStreamPointer));
500 821
501 // Complete main job now. 822 // Complete main job now.
502 MockAsyncProxyResolver resolver; 823 base::RunLoop().RunUntilIdle();
503 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
504 net::OK, &resolver);
505 int main_job_request_id =
506 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1;
507 824
508 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy(
509 "result1:80");
510 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK);
511
512 HttpStream* http_stream =
513 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
514 job_factory_.main_job()->SetStream(http_stream);
515
516 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
517 .WillOnce(Invoke(DeleteHttpStreamPointer));
518 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig());
519 // Invoke OnRequestComplete() which should not delete |job_controller_| from 825 // Invoke OnRequestComplete() which should not delete |job_controller_| from
520 // |factory_| because alt job is yet to finish. 826 // |factory_| because alt job is yet to finish.
521 request_.reset(); 827 request_.reset();
522 ASSERT_FALSE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 828 ASSERT_FALSE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
523 EXPECT_FALSE(job_controller_->main_job()); 829 EXPECT_FALSE(job_controller_->main_job());
524 EXPECT_TRUE(job_controller_->alternative_job()); 830 EXPECT_TRUE(job_controller_->alternative_job());
525 831
526 // Make |alternative_job| succeed. 832 // Make |alternative_job| succeed.
527 resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80"); 833 HttpStream* http_stream =
528 resolver.pending_jobs()[0]->CompleteNow(net::OK);
529 HttpStream* http_stream2 =
530 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); 834 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
531 job_factory_.alternative_job()->SetStream(http_stream2); 835 job_factory_.alternative_job()->SetStream(http_stream);
532 // This should not call request_delegate_::OnStreamReady. 836 // This should not call request_delegate_::OnStreamReady.
533 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); 837 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
534 // Make sure that controller does not leak. 838 // Make sure that controller does not leak.
535 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 839 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
536 } 840 }
537 841
538 TEST_F(HttpStreamFactoryImplJobControllerTest, 842 TEST_F(HttpStreamFactoryImplJobControllerTest,
539 AltJobSucceedsAfterMainJobFailed) { 843 AltJobSucceedsAfterMainJobFailed) {
540 ProxyConfig proxy_config; 844 quic_data_ = base::MakeUnique<test::MockQuicData>();
541 proxy_config.set_auto_detect(true); 845 quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
542 // Use asynchronous proxy resolver. 846 // Use cold start and complete alt job manually.
543 MockAsyncProxyResolverFactory* proxy_resolver_factory = 847 crypto_client_stream_factory_.set_handshake_mode(
544 new MockAsyncProxyResolverFactory(false); 848 MockCryptoClientStream::COLD_START);
545 session_deps_.proxy_service.reset( 849
546 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), 850 // One failed TCP connect.
547 base::WrapUnique(proxy_resolver_factory), nullptr)); 851 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
852 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, ERR_FAILED));
853
548 HttpRequestInfo request_info; 854 HttpRequestInfo request_info;
549 request_info.method = "GET"; 855 request_info.method = "GET";
550 request_info.url = GURL("https://www.google.com"); 856 request_info.url = GURL("https://www.google.com");
551 857
552 Initialize(request_info); 858 Initialize(request_info);
553 859
554 url::SchemeHostPort server(request_info.url); 860 url::SchemeHostPort server(request_info.url);
555 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 861 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
556 SetAlternativeService(request_info, alternative_service); 862 SetAlternativeService(request_info, alternative_service);
557 863
558 request_.reset(
559 job_controller_->Start(request_info, &request_delegate_, nullptr,
560 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM,
561 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
562 EXPECT_TRUE(job_controller_->main_job());
563 EXPECT_TRUE(job_controller_->alternative_job());
564
565 // |main_job| fails but should not report status to Request. 864 // |main_job| fails but should not report status to Request.
566 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 865 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
567 866
568 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, 867 request_ =
569 SSLConfig()); 868 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
869 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
870 EXPECT_TRUE(job_controller_->main_job());
871 EXPECT_TRUE(job_controller_->alternative_job());
570 872
571 // |alternative_job| succeeds and should report status to Request. 873 base::RunLoop().RunUntilIdle();
874
875 // Make |alternative_job| succeed.
572 HttpStream* http_stream = 876 HttpStream* http_stream =
573 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); 877 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
574 job_factory_.alternative_job()->SetStream(http_stream);
575 878
576 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) 879 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
577 .WillOnce(Invoke(DeleteHttpStreamPointer)); 880 .WillOnce(Invoke(DeleteHttpStreamPointer));
881
882 job_factory_.alternative_job()->SetStream(http_stream);
578 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); 883 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
884
885 // |alternative_job| succeeds and should report status to Request.
579 VerifyBrokenAlternateProtocolMapping(request_info, false); 886 VerifyBrokenAlternateProtocolMapping(request_info, false);
887 request_.reset();
888 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
580 } 889 }
581 890
582 TEST_F(HttpStreamFactoryImplJobControllerTest, 891 TEST_F(HttpStreamFactoryImplJobControllerTest,
583 MainJobSucceedsAfterAltJobFailed) { 892 MainJobSucceedsAfterAltJobFailed) {
893 quic_data_ = base::MakeUnique<test::MockQuicData>();
894 quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED);
895
896 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
897 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
898 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
899 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
900
584 base::HistogramTester histogram_tester; 901 base::HistogramTester histogram_tester;
585 ProxyConfig proxy_config;
586 proxy_config.set_auto_detect(true);
587 // Use asynchronous proxy resolver.
588 MockAsyncProxyResolverFactory* proxy_resolver_factory =
589 new MockAsyncProxyResolverFactory(false);
590 session_deps_.proxy_service.reset(
591 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
592 base::WrapUnique(proxy_resolver_factory), nullptr));
593 HttpRequestInfo request_info; 902 HttpRequestInfo request_info;
594 request_info.method = "GET"; 903 request_info.method = "GET";
595 request_info.url = GURL("https://www.google.com"); 904 request_info.url = GURL("https://www.google.com");
596 905
597 Initialize(request_info); 906 Initialize(request_info);
598 907
599 url::SchemeHostPort server(request_info.url); 908 url::SchemeHostPort server(request_info.url);
600 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 909 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
601 SetAlternativeService(request_info, alternative_service); 910 SetAlternativeService(request_info, alternative_service);
602 911
603 request_.reset( 912 request_ =
604 job_controller_->Start(request_info, &request_delegate_, nullptr, 913 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
605 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 914 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
606 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
607 EXPECT_TRUE(job_controller_->main_job()); 915 EXPECT_TRUE(job_controller_->main_job());
608 EXPECT_TRUE(job_controller_->alternative_job()); 916 EXPECT_TRUE(job_controller_->alternative_job());
609 917
610 // |alternative_job| fails but should not report status to Request. 918 // |alternative_job| fails but should not report status to Request.
611 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 919 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
920 // |main_job| succeeds and should report status to Request.
921 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
922 .WillOnce(Invoke(DeleteHttpStreamPointer));
612 923
613 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, 924 base::RunLoop().RunUntilIdle();
614 SSLConfig());
615
616 // |main_job| succeeds and should report status to Request.
617 HttpStream* http_stream =
618 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
619 job_factory_.main_job()->SetStream(http_stream);
620
621 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
622 .WillOnce(Invoke(DeleteHttpStreamPointer));
623 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig());
624 925
625 // Verify that the alternate protocol is marked as broken. 926 // Verify that the alternate protocol is marked as broken.
626 VerifyBrokenAlternateProtocolMapping(request_info, true); 927 VerifyBrokenAlternateProtocolMapping(request_info, true);
627 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", -ERR_FAILED, 928 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", -ERR_FAILED,
628 1); 929 1);
930 request_.reset();
931 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
629 } 932 }
630 933
631 // Verifies that if the alternative job fails due to a connection change event, 934 // Verifies that if the alternative job fails due to a connection change event,
632 // then the alternative service is not marked as broken. 935 // then the alternative service is not marked as broken.
633 TEST_F(HttpStreamFactoryImplJobControllerTest, 936 TEST_F(HttpStreamFactoryImplJobControllerTest,
634 MainJobSucceedsAfterConnectionChanged) { 937 MainJobSucceedsAfterConnectionChanged) {
938 quic_data_ = base::MakeUnique<test::MockQuicData>();
939 quic_data_->AddConnect(SYNCHRONOUS, ERR_NETWORK_CHANGED);
940 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
941 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
942 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
943 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
944
635 base::HistogramTester histogram_tester; 945 base::HistogramTester histogram_tester;
636 ProxyConfig proxy_config;
637 proxy_config.set_auto_detect(true);
638 // Use asynchronous proxy resolver.
639 MockAsyncProxyResolverFactory* proxy_resolver_factory =
640 new MockAsyncProxyResolverFactory(false);
641 session_deps_.proxy_service.reset(
642 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
643 base::WrapUnique(proxy_resolver_factory), nullptr));
644 946
645 HttpRequestInfo request_info; 947 HttpRequestInfo request_info;
646 request_info.method = "GET"; 948 request_info.method = "GET";
647 request_info.url = GURL("https://www.google.com"); 949 request_info.url = GURL("https://www.google.com");
648 Initialize(request_info); 950 Initialize(request_info);
649 951
650 url::SchemeHostPort server(request_info.url); 952 url::SchemeHostPort server(request_info.url);
651 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 953 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
652 SetAlternativeService(request_info, alternative_service); 954 SetAlternativeService(request_info, alternative_service);
653 955
654 request_.reset( 956 request_ =
655 job_controller_->Start(request_info, &request_delegate_, nullptr, 957 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
656 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 958 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
657 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
658 EXPECT_TRUE(job_controller_->main_job()); 959 EXPECT_TRUE(job_controller_->main_job());
659 EXPECT_TRUE(job_controller_->alternative_job()); 960 EXPECT_TRUE(job_controller_->alternative_job());
660 961
661 // |alternative_job| fails but should not report status to Request. 962 // |alternative_job| fails but should not report status to Request.
662 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 963 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
663
664 job_controller_->OnStreamFailed(job_factory_.alternative_job(),
665 ERR_NETWORK_CHANGED, SSLConfig());
666
667 // |main_job| succeeds and should report status to Request. 964 // |main_job| succeeds and should report status to Request.
668 HttpStream* http_stream = 965 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
669 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
670 job_factory_.main_job()->SetStream(http_stream);
671
672 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
673 .WillOnce(Invoke(DeleteHttpStreamPointer)); 966 .WillOnce(Invoke(DeleteHttpStreamPointer));
674 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); 967 base::RunLoop().RunUntilIdle();
675 968
676 // Verify that the alternate protocol is not marked as broken. 969 // Verify that the alternate protocol is not marked as broken.
677 VerifyBrokenAlternateProtocolMapping(request_info, false); 970 VerifyBrokenAlternateProtocolMapping(request_info, false);
678 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", 971 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed",
679 -ERR_NETWORK_CHANGED, 1); 972 -ERR_NETWORK_CHANGED, 1);
973 request_.reset();
974 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
680 } 975 }
681 976
682 // Regression test for crbug/621069. 977 // Regression test for crbug/621069.
683 // Get load state after main job fails and before alternative job succeeds. 978 // Get load state after main job fails and before alternative job succeeds.
684 TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { 979 TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) {
685 ProxyConfig proxy_config; 980 // Use COLD_START to complete alt job manually.
686 proxy_config.set_auto_detect(true); 981 quic_data_ = base::MakeUnique<test::MockQuicData>();
687 // Use asynchronous proxy resolver. 982 quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
688 MockAsyncProxyResolverFactory* proxy_resolver_factory = 983 crypto_client_stream_factory_.set_handshake_mode(
689 new MockAsyncProxyResolverFactory(false); 984 MockCryptoClientStream::COLD_START);
690 session_deps_.proxy_service.reset(new ProxyService( 985
691 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)), 986 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
692 base::WrapUnique(proxy_resolver_factory), nullptr)); 987 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
693 988
694 HttpRequestInfo request_info; 989 HttpRequestInfo request_info;
695 request_info.method = "GET"; 990 request_info.method = "GET";
696 request_info.url = GURL("https://www.google.com"); 991 request_info.url = GURL("https://www.google.com");
697 992
698 Initialize(request_info); 993 Initialize(request_info);
699 url::SchemeHostPort server(request_info.url); 994 url::SchemeHostPort server(request_info.url);
700 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 995 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
701 SetAlternativeService(request_info, alternative_service); 996 SetAlternativeService(request_info, alternative_service);
702 997
703 request_.reset( 998 request_ =
704 job_controller_->Start(request_info, &request_delegate_, nullptr, 999 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
705 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1000 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
706 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
707 EXPECT_TRUE(job_controller_->main_job()); 1001 EXPECT_TRUE(job_controller_->main_job());
708 EXPECT_TRUE(job_controller_->alternative_job()); 1002 EXPECT_TRUE(job_controller_->alternative_job());
709 1003
710 // |main_job| fails but should not report status to Request. 1004 // |main_job| fails but should not report status to Request.
711 // The alternative job will mark the main job complete. 1005 // The alternative job will mark the main job complete.
712 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 1006 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
713 1007
714 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, 1008 base::RunLoop().RunUntilIdle();
715 SSLConfig());
716 1009
717 // Controller should use alternative job to get load state. 1010 // Controller should use alternative job to get load state.
718 job_controller_->GetLoadState(); 1011 job_controller_->GetLoadState();
719 1012
720 // |alternative_job| succeeds and should report status to Request. 1013 // |alternative_job| succeeds and should report status to Request.
721 HttpStream* http_stream = 1014 HttpStream* http_stream =
722 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); 1015 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
723 job_factory_.alternative_job()->SetStream(http_stream); 1016 job_factory_.alternative_job()->SetStream(http_stream);
724 1017
725 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) 1018 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
726 .WillOnce(Invoke(DeleteHttpStreamPointer)); 1019 .WillOnce(Invoke(DeleteHttpStreamPointer));
727 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); 1020 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
1021 request_.reset();
1022 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
728 } 1023 }
729 1024
730 TEST_F(HttpStreamFactoryImplJobControllerTest, DoNotResumeMainJobBeforeWait) { 1025 TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobWhenAltJobStalls) {
731 // Use failing ProxyResolverFactory which is unable to create ProxyResolver 1026 // Use COLD_START to stall alt job.
732 // to stall the alternative job and report to controller to maybe resume the 1027 quic_data_ = base::MakeUnique<test::MockQuicData>();
733 // main job. 1028 quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
734 ProxyConfig proxy_config; 1029 crypto_client_stream_factory_.set_handshake_mode(
735 proxy_config.set_auto_detect(true); 1030 MockCryptoClientStream::COLD_START);
736 proxy_config.set_pac_mandatory(true); 1031
737 session_deps_.proxy_service.reset(new ProxyService( 1032 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
738 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), 1033 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
739 base::WrapUnique(new FailingProxyResolverFactory), nullptr)); 1034 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
1035 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
740 1036
741 HttpRequestInfo request_info; 1037 HttpRequestInfo request_info;
742 request_info.method = "GET"; 1038 request_info.method = "GET";
743 request_info.url = GURL("https://www.google.com"); 1039 request_info.url = GURL("https://www.google.com");
744 1040
745 Initialize(request_info); 1041 Initialize(request_info);
746 url::SchemeHostPort server(request_info.url); 1042 url::SchemeHostPort server(request_info.url);
747 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 1043 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
748 SetAlternativeService(request_info, alternative_service); 1044 SetAlternativeService(request_info, alternative_service);
749 1045
750 request_.reset( 1046 request_ =
751 job_controller_->Start(request_info, &request_delegate_, nullptr, 1047 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
752 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1048 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
753 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
754 EXPECT_TRUE(job_controller_->main_job()); 1049 EXPECT_TRUE(job_controller_->main_job());
755 EXPECT_TRUE(job_controller_->alternative_job()); 1050 EXPECT_TRUE(job_controller_->alternative_job());
756 1051
757 // Wait until OnStreamFailedCallback is executed on the alternative job. 1052 // Alt job is stalled and main job should complete successfully.
758 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); 1053 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
1054 .WillOnce(Invoke(DeleteHttpStreamPointer));
1055
759 base::RunLoop().RunUntilIdle(); 1056 base::RunLoop().RunUntilIdle();
760 } 1057 }
761 1058
762 TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) { 1059 TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) {
763 HttpRequestInfo request_info; 1060 HttpRequestInfo request_info;
764 request_info.method = "GET"; 1061 request_info.method = "GET";
765 request_info.url = GURL("https://www.google.com"); 1062 request_info.url = GURL("https://www.google.com");
766 1063
767 // Using a restricted port 101 for QUIC should fail and the alternative job 1064 // Using a restricted port 101 for QUIC should fail and the alternative job
768 // should post OnStreamFailedCall on the controller to resume the main job. 1065 // should post OnStreamFailedCall on the controller to resume the main job.
769 Initialize(request_info); 1066 Initialize(request_info);
770 1067
771 url::SchemeHostPort server(request_info.url); 1068 url::SchemeHostPort server(request_info.url);
772 AlternativeService alternative_service(kProtoQUIC, server.host(), 101); 1069 AlternativeService alternative_service(kProtoQUIC, server.host(), 101);
773 SetAlternativeService(request_info, alternative_service); 1070 SetAlternativeService(request_info, alternative_service);
774 1071
775 request_.reset( 1072 request_ =
776 job_controller_->Start(request_info, &request_delegate_, nullptr, 1073 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
777 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1074 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
778 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
779 1075
780 EXPECT_TRUE(job_factory_.main_job()->is_waiting()); 1076 EXPECT_TRUE(job_factory_.main_job()->is_waiting());
781 1077
782 // Wait until OnStreamFailedCallback is executed on the alternative job. 1078 // Wait until OnStreamFailedCallback is executed on the alternative job.
783 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); 1079 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
784 base::RunLoop().RunUntilIdle(); 1080 base::RunLoop().RunUntilIdle();
785 } 1081 }
786 1082
787 TEST_F(HttpStreamFactoryImplJobControllerTest,
788 NoAvailableSpdySessionToResumeMainJob) {
789 // Test the alternative job is not resumed when the alternative job is
790 // IO_PENDING for proxy resolution. Once all the proxy resolution succeeds,
791 // the latter part of this test tests controller resumes the main job
792 // when there's no SPDY session for the alternative job.
793 ProxyConfig proxy_config;
794 proxy_config.set_auto_detect(true);
795 // Use asynchronous proxy resolver.
796 MockAsyncProxyResolverFactory* proxy_resolver_factory =
797 new MockAsyncProxyResolverFactory(false);
798 session_deps_.proxy_service.reset(
799 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
800 base::WrapUnique(proxy_resolver_factory), nullptr));
801
802 HangingResolver* host_resolver = new HangingResolver();
803 session_deps_.host_resolver.reset(host_resolver);
804 session_deps_.host_resolver->set_synchronous_mode(false);
805
806 HttpRequestInfo request_info;
807 request_info.method = "GET";
808 request_info.url = GURL("https://www.google.com");
809
810 Initialize(request_info);
811
812 // Set a SPDY alternative service for the server.
813 url::SchemeHostPort server(request_info.url);
814 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
815 SetAlternativeService(request_info, alternative_service);
816 // Hack to use different URL for the main job to help differentiate the proxy
817 // requests.
818 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com"));
819
820 request_.reset(
821 job_controller_->Start(request_info, &request_delegate_, nullptr,
822 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM,
823 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
824 // Both jobs should be created but stalled as proxy resolution not completed.
825 EXPECT_TRUE(job_controller_->main_job());
826 EXPECT_TRUE(job_controller_->alternative_job());
827
828 MockAsyncProxyResolver resolver;
829 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
830 net::OK, &resolver);
831
832 // Resolve proxy for the main job which then proceed to wait for the
833 // alternative job which is IO_PENDING.
834 int main_job_request_id =
835 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1;
836
837 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy(
838 "result1:80");
839 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK);
840 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
841
842 // Resolve proxy for the alternative job to proceed to create a connection.
843 // Use hanging HostResolver to fail creation of a SPDY session for the
844 // alternative job. The alternative job will be IO_PENDING thus should resume
845 // the main job.
846 resolver.pending_jobs()[0]->CompleteNow(net::OK);
847 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
848 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
849
850 base::RunLoop().RunUntilIdle();
851 }
852
853 TEST_F(HttpStreamFactoryImplJobControllerTest,
854 NoAvailableQuicSessionToResumeMainJob) {
855 // Use failing HostResolver which is unable to resolve the host name for QUIC.
856 // No QUIC session is created and thus should resume the main job.
857 FailingHostResolver* host_resolver = new FailingHostResolver();
858 session_deps_.host_resolver.reset(host_resolver);
859
860 ProxyConfig proxy_config;
861 proxy_config.set_auto_detect(true);
862 // Use asynchronous proxy resolver.
863 MockAsyncProxyResolverFactory* proxy_resolver_factory =
864 new MockAsyncProxyResolverFactory(false);
865 session_deps_.proxy_service.reset(
866 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
867 base::WrapUnique(proxy_resolver_factory), nullptr));
868
869 HttpRequestInfo request_info;
870 request_info.method = "GET";
871 request_info.url = GURL("https://www.google.com");
872
873 Initialize(request_info);
874 url::SchemeHostPort server(request_info.url);
875 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
876 SetAlternativeService(request_info, alternative_service);
877 // Hack to use different URL for the main job to help differentiate the proxy
878 // requests.
879 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com"));
880
881 request_.reset(
882 job_controller_->Start(request_info, &request_delegate_, nullptr,
883 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM,
884 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
885 EXPECT_TRUE(job_controller_->main_job());
886 EXPECT_TRUE(job_controller_->alternative_job());
887
888 MockAsyncProxyResolver resolver;
889 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
890 net::OK, &resolver);
891
892 // Resolve proxy for the main job which then proceed to wait for the
893 // alternative job which is IO_PENDING.
894 int main_job_request_id =
895 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1;
896
897 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy(
898 "result1:80");
899 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK);
900 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
901
902 // Resolve proxy for the alternative job to proceed to create a connection.
903 // Use failing HostResolver to fail creation of a QUIC session for the
904 // alternative job. The alternative job will thus resume the main job.
905 resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80");
906 resolver.pending_jobs()[0]->CompleteNow(net::OK);
907
908 // Wait until OnStreamFailedCallback is executed on the alternative job.
909 // Request shouldn't be notified as the main job is still pending status.
910 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
911 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
912
913 base::RunLoop().RunUntilIdle();
914 }
915
916 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { 1083 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) {
917 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; 1084 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
918 auto failing_resolver = base::MakeUnique<MockHostResolver>(); 1085 auto failing_resolver = base::MakeUnique<MockHostResolver>();
919 failing_resolver->set_ondemand_mode(true); 1086 failing_resolver->set_ondemand_mode(true);
920 failing_resolver->rules()->AddSimulatedFailure("*google.com"); 1087 failing_resolver->rules()->AddSimulatedFailure("*google.com");
921 session_deps_.host_resolver = std::move(failing_resolver); 1088 session_deps_.host_resolver = std::move(failing_resolver);
922 1089
923 HttpRequestInfo request_info; 1090 HttpRequestInfo request_info;
924 request_info.method = "GET"; 1091 request_info.method = "GET";
925 request_info.url = GURL("https://www.google.com"); 1092 request_info.url = GURL("https://www.google.com");
926 1093
927 Initialize(request_info); 1094 Initialize(request_info);
928 1095
929 // Enable delayed TCP and set time delay for waiting job. 1096 // Enable delayed TCP and set time delay for waiting job.
930 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); 1097 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
931 quic_stream_factory->set_require_confirmation(false); 1098 quic_stream_factory->set_require_confirmation(false);
932 ServerNetworkStats stats1; 1099 ServerNetworkStats stats1;
933 stats1.srtt = base::TimeDelta::FromMicroseconds(10); 1100 stats1.srtt = base::TimeDelta::FromMicroseconds(10);
934 session_->http_server_properties()->SetServerNetworkStats( 1101 session_->http_server_properties()->SetServerNetworkStats(
935 url::SchemeHostPort(GURL("https://www.google.com")), stats1); 1102 url::SchemeHostPort(GURL("https://www.google.com")), stats1);
936 1103
937 // Set a SPDY alternative service for the server.
938 url::SchemeHostPort server(request_info.url); 1104 url::SchemeHostPort server(request_info.url);
939 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 1105 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
940 SetAlternativeService(request_info, alternative_service); 1106 SetAlternativeService(request_info, alternative_service);
941 1107
942 request_.reset( 1108 request_ =
943 job_controller_->Start(request_info, &request_delegate_, nullptr, 1109 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
944 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1110 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
945 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
946 EXPECT_TRUE(job_controller_->main_job()); 1111 EXPECT_TRUE(job_controller_->main_job());
947 EXPECT_TRUE(job_controller_->alternative_job()); 1112 EXPECT_TRUE(job_controller_->alternative_job());
948 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 1113 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
949 1114
950 // The alternative job stalls as host resolution hangs when creating the QUIC 1115 // The alternative job stalls as host resolution hangs when creating the QUIC
951 // request and controller should resume the main job after delay. 1116 // request and controller should resume the main job after delay.
952 EXPECT_TRUE(test_task_runner->HasPendingTask()); 1117 EXPECT_TRUE(test_task_runner->HasPendingTask());
953 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 1118 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
954 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); 1119 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
955 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); 1120 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 ServerNetworkStats stats1; 1165 ServerNetworkStats stats1;
1001 stats1.srtt = base::TimeDelta::FromSeconds(100); 1166 stats1.srtt = base::TimeDelta::FromSeconds(100);
1002 session_->http_server_properties()->SetServerNetworkStats( 1167 session_->http_server_properties()->SetServerNetworkStats(
1003 url::SchemeHostPort(GURL("https://www.google.com")), stats1); 1168 url::SchemeHostPort(GURL("https://www.google.com")), stats1);
1004 1169
1005 // Set a SPDY alternative service for the server. 1170 // Set a SPDY alternative service for the server.
1006 url::SchemeHostPort server(request_info.url); 1171 url::SchemeHostPort server(request_info.url);
1007 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 1172 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
1008 SetAlternativeService(request_info, alternative_service); 1173 SetAlternativeService(request_info, alternative_service);
1009 1174
1010 request_.reset( 1175 request_ =
1011 job_controller_->Start(request_info, &request_delegate_, nullptr, 1176 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1012 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1177 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1013 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1014 EXPECT_TRUE(job_controller_->main_job()); 1178 EXPECT_TRUE(job_controller_->main_job());
1015 EXPECT_TRUE(job_controller_->alternative_job()); 1179 EXPECT_TRUE(job_controller_->alternative_job());
1016 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 1180 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
1017 1181
1018 // The alternative job stalls as host resolution hangs when creating the QUIC 1182 // The alternative job stalls as host resolution hangs when creating the QUIC
1019 // request and controller should resume the main job after delay. 1183 // request and controller should resume the main job after delay.
1020 EXPECT_TRUE(test_task_runner->HasPendingTask()); 1184 EXPECT_TRUE(test_task_runner->HasPendingTask());
1021 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 1185 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1022 1186
1023 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); 1187 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 url::SchemeHostPort(GURL("https://www.google.com")), stats1); 1224 url::SchemeHostPort(GURL("https://www.google.com")), stats1);
1061 1225
1062 // Set a SPDY alternative service for the server. 1226 // Set a SPDY alternative service for the server.
1063 url::SchemeHostPort server(request_info.url); 1227 url::SchemeHostPort server(request_info.url);
1064 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 1228 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
1065 SetAlternativeService(request_info, alternative_service); 1229 SetAlternativeService(request_info, alternative_service);
1066 1230
1067 // The alternative job stalls as host resolution hangs when creating the QUIC 1231 // The alternative job stalls as host resolution hangs when creating the QUIC
1068 // request and controller should resume the main job with delay. 1232 // request and controller should resume the main job with delay.
1069 // OnStreamFailed should resume the main job immediately. 1233 // OnStreamFailed should resume the main job immediately.
1070 request_.reset( 1234 request_ =
1071 job_controller_->Start(request_info, &request_delegate_, nullptr, 1235 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1072 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1236 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1073 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1074 EXPECT_TRUE(job_controller_->main_job()); 1237 EXPECT_TRUE(job_controller_->main_job());
1075 EXPECT_TRUE(job_controller_->alternative_job()); 1238 EXPECT_TRUE(job_controller_->alternative_job());
1076 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 1239 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
1077 1240
1078 EXPECT_TRUE(test_task_runner->HasPendingTask()); 1241 EXPECT_TRUE(test_task_runner->HasPendingTask());
1079 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 1242 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1080 1243
1081 // |alternative_job| fails but should not report status to Request. 1244 // |alternative_job| fails but should not report status to Request.
1082 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 1245 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
1083 // Now unblock Resolver to fail the alternate job. 1246 // Now unblock Resolver to fail the alternate job.
(...skipping 21 matching lines...) Expand all
1105 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) { 1268 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) {
1106 // Using hanging resolver will cause the alternative job to hang indefinitely. 1269 // Using hanging resolver will cause the alternative job to hang indefinitely.
1107 session_deps_.host_resolver = base::MakeUnique<HangingResolver>(); 1270 session_deps_.host_resolver = base::MakeUnique<HangingResolver>();
1108 1271
1109 HttpRequestInfo request_info; 1272 HttpRequestInfo request_info;
1110 request_info.method = "GET"; 1273 request_info.method = "GET";
1111 request_info.url = GURL("https://mail.example.org/"); 1274 request_info.url = GURL("https://mail.example.org/");
1112 Initialize(request_info); 1275 Initialize(request_info);
1113 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); 1276 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic());
1114 1277
1115 request_.reset( 1278 request_ =
1116 job_controller_->Start(request_info, &request_delegate_, nullptr, 1279 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1117 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1280 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1118 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1119 EXPECT_TRUE(job_controller_->main_job()); 1281 EXPECT_TRUE(job_controller_->main_job());
1120 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); 1282 EXPECT_FALSE(job_controller_->main_job()->is_waiting());
1121 EXPECT_FALSE(job_controller_->alternative_job()); 1283 EXPECT_FALSE(job_controller_->alternative_job());
1122 1284
1123 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); 1285 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
1124 base::RunLoop().RunUntilIdle(); 1286 base::RunLoop().RunUntilIdle();
1125 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); 1287 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations());
1126 } 1288 }
1127 1289
1128 // Verifies that the alternative proxy server job is not created if the main job 1290 // Verifies that the alternative proxy server job is not created if the main job
1129 // does not fetch the resource through a proxy. 1291 // does not fetch the resource through a proxy.
1130 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) { 1292 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) {
1131 // Using hanging resolver will cause the alternative job to hang indefinitely. 1293 // Using hanging resolver will cause the alternative job to hang indefinitely.
1132 session_deps_.host_resolver = base::MakeUnique<HangingResolver>(); 1294 session_deps_.host_resolver = base::MakeUnique<HangingResolver>();
1133 1295
1134 HttpRequestInfo request_info; 1296 HttpRequestInfo request_info;
1135 request_info.method = "GET"; 1297 request_info.method = "GET";
1136 request_info.url = GURL("http://mail.example.org/"); 1298 request_info.url = GURL("http://mail.example.org/");
1137 1299
1138 Initialize(request_info); 1300 Initialize(request_info);
1139 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); 1301 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic());
1140 1302
1141 request_.reset( 1303 request_ =
1142 job_controller_->Start(request_info, &request_delegate_, nullptr, 1304 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1143 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1305 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1144 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1145 EXPECT_TRUE(job_controller_->main_job()); 1306 EXPECT_TRUE(job_controller_->main_job());
1146 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); 1307 EXPECT_FALSE(job_controller_->main_job()->is_waiting());
1147 EXPECT_FALSE(job_controller_->alternative_job()); 1308 EXPECT_FALSE(job_controller_->alternative_job());
1148 1309
1149 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); 1310 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
1150 base::RunLoop().RunUntilIdle(); 1311 base::RunLoop().RunUntilIdle();
1151 1312
1152 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); 1313 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations());
1153 } 1314 }
1154 1315
(...skipping 19 matching lines...) Expand all
1174 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); 1335 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic());
1175 1336
1176 // Enable delayed TCP and set time delay for waiting job. 1337 // Enable delayed TCP and set time delay for waiting job.
1177 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); 1338 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
1178 quic_stream_factory->set_require_confirmation(false); 1339 quic_stream_factory->set_require_confirmation(false);
1179 ServerNetworkStats stats1; 1340 ServerNetworkStats stats1;
1180 stats1.srtt = base::TimeDelta::FromMicroseconds(10); 1341 stats1.srtt = base::TimeDelta::FromMicroseconds(10);
1181 session_->http_server_properties()->SetServerNetworkStats( 1342 session_->http_server_properties()->SetServerNetworkStats(
1182 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); 1343 url::SchemeHostPort(GURL("https://myproxy.org")), stats1);
1183 1344
1184 request_.reset( 1345 request_ =
1185 job_controller_->Start(request_info, &request_delegate_, nullptr, 1346 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1186 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1347 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1187 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1188 EXPECT_TRUE(job_controller_->main_job()); 1348 EXPECT_TRUE(job_controller_->main_job());
1189 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 1349 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
1190 EXPECT_TRUE(job_controller_->alternative_job()); 1350 EXPECT_TRUE(job_controller_->alternative_job());
1191 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); 1351 // The main job is unblocked but is resumed one message loop iteration later.
1192 1352 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
1193 // Alternative proxy server job will start in the next message loop. 1353 EXPECT_FALSE(JobControllerPeer::main_job_is_resumed(job_controller_));
1194 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1195
1196 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
1197 // Run tasks with no remaining delay, this will start the alternative proxy
1198 // server job. The alternative proxy server job stalls when connecting to the
1199 // alternative proxy server, and should schedule a task to resume the main job
1200 // after delay. That task will be queued.
1201 test_task_runner->RunUntilIdle();
1202 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 1354 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1203 1355
1204 // Move forward the delay and verify the main job is resumed. 1356 // Move forward the delay and verify the main job is resumed.
1205 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); 1357 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
1206 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); 1358 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15));
1207 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); 1359 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
1360 EXPECT_TRUE(JobControllerPeer::main_job_is_resumed(job_controller_));
1208 1361
1209 test_task_runner->RunUntilIdle(); 1362 test_task_runner->RunUntilIdle();
1210 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); 1363 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid());
1211 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); 1364 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations());
1212 EXPECT_FALSE(test_task_runner->HasPendingTask()); 1365 EXPECT_FALSE(test_task_runner->HasPendingTask());
1213 1366
1214 // Now unblock Resolver so that alternate job (and QuicStreamFactory::Job) can 1367 // Now unblock Resolver so that alternate job (and QuicStreamFactory::Job) can
1215 // be cleaned up. 1368 // be cleaned up.
1216 session_deps_.host_resolver->ResolveAllPending(); 1369 session_deps_.host_resolver->ResolveAllPending();
1217 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 1370 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1218 test_task_runner->FastForwardUntilNoTasksRemain(); 1371 test_task_runner->FastForwardUntilNoTasksRemain();
1219 EXPECT_FALSE(job_controller_->alternative_job()); 1372 EXPECT_FALSE(job_controller_->alternative_job());
1220 } 1373 }
1221 1374
1222 // Verifies that the alternative proxy server job fails immediately, and the 1375 // Verifies that if the alternative proxy server job fails immediately, the
1223 // main job is not blocked. 1376 // main job is not blocked.
1224 TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { 1377 TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) {
1225 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; 1378 quic_data_ = base::MakeUnique<test::MockQuicData>();
1226 // Using failing resolver will cause the alternative job to fail. 1379 quic_data_->AddConnect(SYNCHRONOUS, ERR_FAILED);
1227 FailingHostResolver* resolver = new FailingHostResolver(); 1380 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
1228 session_deps_.host_resolver.reset(resolver); 1381 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
1382 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
1383 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
1229 1384
1230 UseAlternativeProxy(); 1385 UseAlternativeProxy();
1231 1386
1232 HttpRequestInfo request_info; 1387 HttpRequestInfo request_info;
1233 request_info.method = "GET"; 1388 request_info.method = "GET";
1234 request_info.url = GURL("http://mail.example.org/"); 1389 request_info.url = GURL("http://mail.example.org/");
1235 Initialize(request_info); 1390 Initialize(request_info);
1236 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); 1391 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic());
1237 1392
1238 // Enable delayed TCP and set time delay for waiting job. 1393 // Enable delayed TCP and set time delay for waiting job.
1239 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); 1394 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
1240 quic_stream_factory->set_require_confirmation(false); 1395 quic_stream_factory->set_require_confirmation(false);
1241 ServerNetworkStats stats1; 1396 ServerNetworkStats stats1;
1242 stats1.srtt = base::TimeDelta::FromMicroseconds(300 * 1000); 1397 stats1.srtt = base::TimeDelta::FromMicroseconds(300 * 1000);
1243 session_->http_server_properties()->SetServerNetworkStats( 1398 session_->http_server_properties()->SetServerNetworkStats(
1244 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); 1399 url::SchemeHostPort(GURL("https://myproxy.org")), stats1);
1245 1400
1246 request_.reset( 1401 request_ =
1247 job_controller_->Start(request_info, &request_delegate_, nullptr, 1402 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1248 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1403 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1249 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); 1404 EXPECT_TRUE(job_controller_->main_job());
1250 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
1251 EXPECT_TRUE(job_controller_->alternative_job()); 1405 EXPECT_TRUE(job_controller_->alternative_job());
1252 1406
1253 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 1407 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
1408 .WillOnce(Invoke(DeleteHttpStreamPointer));
1254 1409
1255 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)).Times(0); 1410 base::RunLoop().RunUntilIdle();
1256
1257 // Since the alternative proxy server job is started in the next message loop,
1258 // the main job would remain blocked until the alternative proxy starts, and
1259 // fails.
1260 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
1261
1262 // Run tasks with no remaining delay.
1263 test_task_runner->RunUntilIdle();
1264 1411
1265 EXPECT_FALSE(job_controller_->alternative_job()); 1412 EXPECT_FALSE(job_controller_->alternative_job());
1266 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 1413 EXPECT_TRUE(job_controller_->main_job());
1267 // Since the main job did not complete successfully, the alternative proxy 1414
1268 // server should not be marked as bad. 1415 // The alternative proxy server should be marked as bad.
1269 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); 1416 EXPECT_FALSE(test_proxy_delegate()->alternative_proxy_server().is_valid());
1270 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); 1417 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations());
1271 EXPECT_FALSE(test_task_runner->HasPendingTask()); 1418 request_.reset();
1419 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
1272 } 1420 }
1273 1421
1274 TEST_F(HttpStreamFactoryImplJobControllerTest, 1422 TEST_F(HttpStreamFactoryImplJobControllerTest,
1275 AlternativeProxyServerJobFailsAfterMainJobSucceeds) { 1423 AlternativeProxyServerJobFailsAfterMainJobSucceeds) {
1276 base::HistogramTester histogram_tester; 1424 base::HistogramTester histogram_tester;
1277 1425
1426 // Use COLD_START to make the alt job pending.
1427 crypto_client_stream_factory_.set_handshake_mode(
1428 MockCryptoClientStream::COLD_START);
1429 quic_data_ = base::MakeUnique<test::MockQuicData>();
1430 quic_data_->AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1431 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
1432 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
1433 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
1434 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
1435
1278 UseAlternativeProxy(); 1436 UseAlternativeProxy();
1279 1437
1280 HttpRequestInfo request_info; 1438 HttpRequestInfo request_info;
1281 request_info.method = "GET"; 1439 request_info.method = "GET";
1282 request_info.url = GURL("http://www.google.com"); 1440 request_info.url = GURL("http://www.google.com");
1283 Initialize(request_info); 1441 Initialize(request_info);
1284 1442
1285 url::SchemeHostPort server(request_info.url); 1443 url::SchemeHostPort server(request_info.url);
1286 1444
1287 request_.reset( 1445 request_ =
1288 job_controller_->Start(request_info, &request_delegate_, nullptr, 1446 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1289 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1447 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1290 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1291 EXPECT_TRUE(job_controller_->main_job()); 1448 EXPECT_TRUE(job_controller_->main_job());
1292 EXPECT_TRUE(job_controller_->alternative_job()); 1449 EXPECT_TRUE(job_controller_->alternative_job());
1293 1450
1294 // Main job succeeds, starts serving Request and it should report status 1451 // Main job succeeds, starts serving Request and it should report status
1295 // to Request. The alternative job will mark the main job complete and gets 1452 // to Request. The alternative job will mark the main job complete and gets
1296 // orphaned. 1453 // orphaned.
1297 HttpStream* http_stream = 1454 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
1298 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); 1455 .WillOnce(Invoke(DeleteHttpStreamPointer));
1299 job_factory_.main_job()->SetStream(http_stream);
1300 1456
1301 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) 1457 base::RunLoop().RunUntilIdle();
1302 .WillOnce(Invoke(DeleteHttpStreamPointer)); 1458
1303 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); 1459 EXPECT_TRUE(job_controller_->main_job());
1460 EXPECT_TRUE(job_controller_->alternative_job());
1304 1461
1305 // JobController shouldn't report the status of alternative server job as 1462 // JobController shouldn't report the status of alternative server job as
1306 // request is already successfully served. 1463 // request is already successfully served.
1307 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 1464 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
1308 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, 1465 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED,
1309 SSLConfig()); 1466 SSLConfig());
1310 1467
1311 // Reset the request as it's been successfully served. 1468 // Reset the request as it's been successfully served.
1312 request_.reset(); 1469 request_.reset();
1313 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 1470 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
1314 1471
1315 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage", 1472 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
1316 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */, 1473 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */,
1317 1); 1474 1);
1318 } 1475 }
1319 1476
1477 TEST_F(HttpStreamFactoryImplJobControllerTest,
1478 PreconnectToHostWithValidAltSvc) {
1479 quic_data_ = base::MakeUnique<test::MockQuicData>();
1480 quic_data_->AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr));
1481 quic_data_->AddRead(ASYNC, OK);
1482
1483 HttpRequestInfo request_info;
1484 request_info.method = "GET";
1485 request_info.url = GURL("https://www.example.com");
1486 SetPreconnect();
1487
1488 Initialize(request_info);
1489
1490 url::SchemeHostPort server(request_info.url);
1491 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
1492 SetAlternativeService(request_info, alternative_service);
1493
1494 job_controller_->Preconnect(1);
1495 EXPECT_TRUE(job_controller_->main_job());
1496 EXPECT_EQ(HttpStreamFactoryImpl::PRECONNECT,
1497 job_controller_->main_job()->job_type());
1498 EXPECT_FALSE(job_controller_->alternative_job());
1499
1500 base::RunLoop().RunUntilIdle();
1501 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
1502 }
1503
1320 // When preconnect to a H2 supported server, only 1 connection is opened. 1504 // When preconnect to a H2 supported server, only 1 connection is opened.
1321 TEST_F(HttpStreamFactoryImplJobControllerTest, 1505 TEST_F(HttpStreamFactoryImplJobControllerTest,
1322 PreconnectMultipleStreamsToH2Server) { 1506 PreconnectMultipleStreamsToH2Server) {
1323 MockRead reads[] = {MockRead(ASYNC, OK)}; 1507 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
1324 SequencedSocketData data(reads, arraysize(reads), nullptr, 0); 1508 tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
1325 session_deps_.socket_factory->AddSocketDataProvider(&data);
1326
1327 SetPreconnect(); 1509 SetPreconnect();
1328 1510
1329 HttpRequestInfo request_info; 1511 HttpRequestInfo request_info;
1330 request_info.method = "GET"; 1512 request_info.method = "GET";
1331 request_info.url = GURL("http://www.example.com"); 1513 request_info.url = GURL("http://www.example.com");
1332 Initialize(request_info); 1514 Initialize(request_info);
1333 1515
1334 url::SchemeHostPort server(request_info.url); 1516 url::SchemeHostPort server(request_info.url);
1335 1517
1336 // Sets server support Http/2. 1518 // Sets server support Http/2.
1337 session_->http_server_properties()->SetSupportsSpdy(server, true); 1519 session_->http_server_properties()->SetSupportsSpdy(server, true);
1338 1520
1339 job_controller_->Preconnect(/*num_streams=*/5, request_info, SSLConfig(), 1521 job_controller_->Preconnect(/*num_streams=*/5);
1340 SSLConfig());
1341 // Only one job is started. 1522 // Only one job is started.
1342 EXPECT_TRUE(job_controller_->main_job()); 1523 EXPECT_TRUE(job_controller_->main_job());
1343 EXPECT_FALSE(job_controller_->alternative_job()); 1524 EXPECT_FALSE(job_controller_->alternative_job());
1525 EXPECT_EQ(HttpStreamFactoryImpl::PRECONNECT,
1526 job_controller_->main_job()->job_type());
1344 // There is only 1 connect even though multiple streams were requested. 1527 // There is only 1 connect even though multiple streams were requested.
1345 EXPECT_EQ(1, HttpStreamFactoryImplJobPeer::GetNumStreams( 1528 EXPECT_EQ(1, HttpStreamFactoryImplJobPeer::GetNumStreams(
1346 job_controller_->main_job())); 1529 job_controller_->main_job()));
1347 1530
1348 base::RunLoop().RunUntilIdle(); 1531 base::RunLoop().RunUntilIdle();
1349 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 1532 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
1350 } 1533 }
1351 1534
1352 class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry 1535 class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry
1353 : public HttpStreamFactoryImplJobControllerTest, 1536 : public HttpStreamFactoryImplJobControllerTest,
1354 public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; 1537 public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {};
1355 1538
1356 INSTANTIATE_TEST_CASE_P( 1539 INSTANTIATE_TEST_CASE_P(
1357 /* no prefix */, 1540 /* no prefix */,
1358 HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, 1541 HttpStreamFactoryImplJobControllerMisdirectedRequestRetry,
1359 ::testing::Combine(::testing::Bool(), ::testing::Bool())); 1542 ::testing::Combine(::testing::Bool(), ::testing::Bool()));
1360 1543
1361 TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, 1544 TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry,
1362 DisableIPBasedPoolingAndAlternativeServices) { 1545 DisableIPBasedPoolingAndAlternativeServices) {
1363 const bool enable_ip_based_pooling = ::testing::get<0>(GetParam()); 1546 const bool enable_ip_based_pooling = ::testing::get<0>(GetParam());
1364 const bool enable_alternative_services = ::testing::get<1>(GetParam()); 1547 const bool enable_alternative_services = ::testing::get<1>(GetParam());
1548 if (enable_alternative_services) {
1549 quic_data_ = base::MakeUnique<test::MockQuicData>();
1550 quic_data_->AddConnect(SYNCHRONOUS, OK);
1551 quic_data_->AddWrite(client_maker_.MakeInitialSettingsPacket(1, nullptr));
1552 quic_data_->AddRead(ASYNC, OK);
1553 }
1554 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
1555 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
1556 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
1557 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
1365 1558
1366 ProxyConfig proxy_config;
1367 proxy_config.set_auto_detect(true);
1368 // Use asynchronous proxy resolver.
1369 MockAsyncProxyResolverFactory* proxy_resolver_factory =
1370 new MockAsyncProxyResolverFactory(false);
1371 session_deps_.proxy_service.reset(
1372 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
1373 base::WrapUnique(proxy_resolver_factory), nullptr));
1374 HttpRequestInfo request_info; 1559 HttpRequestInfo request_info;
1375 request_info.method = "GET"; 1560 request_info.method = "GET";
1376 request_info.url = GURL("https://www.google.com"); 1561 request_info.url = GURL("https://www.google.com");
1377 1562
1378 if (!enable_ip_based_pooling) 1563 if (!enable_ip_based_pooling)
1379 DisableIPBasedPooling(); 1564 DisableIPBasedPooling();
1380 if (!enable_alternative_services) 1565 if (!enable_alternative_services)
1381 DisableAlternativeServices(); 1566 DisableAlternativeServices();
1382 1567
1383 Initialize(request_info); 1568 Initialize(request_info);
1384 1569
1385 url::SchemeHostPort server(request_info.url); 1570 url::SchemeHostPort server(request_info.url);
1386 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 1571 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
1387 SetAlternativeService(request_info, alternative_service); 1572 SetAlternativeService(request_info, alternative_service);
1388 1573
1389 request_.reset( 1574 request_ =
1390 job_controller_->Start(request_info, &request_delegate_, nullptr, 1575 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1391 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1576 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY);
1392 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1393 EXPECT_TRUE(job_controller_->main_job()); 1577 EXPECT_TRUE(job_controller_->main_job());
1394 if (enable_alternative_services) { 1578 if (enable_alternative_services) {
1395 EXPECT_TRUE(job_controller_->alternative_job()); 1579 EXPECT_TRUE(job_controller_->alternative_job());
1396 } else { 1580 } else {
1397 EXPECT_FALSE(job_controller_->alternative_job()); 1581 EXPECT_FALSE(job_controller_->alternative_job());
1398 } 1582 }
1399 1583
1400 // |main_job| succeeds and should report status to Request. 1584 // |main_job| succeeds and should report status to Request.
1401 HttpStream* http_stream = 1585 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
1402 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
1403 job_factory_.main_job()->SetStream(http_stream);
1404
1405 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
1406 .WillOnce(Invoke(DeleteHttpStreamPointer)); 1586 .WillOnce(Invoke(DeleteHttpStreamPointer));
1407 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); 1587 base::RunLoop().RunUntilIdle();
1408 } 1588 }
1409 1589
1410 class HttpStreamFactoryImplJobControllerPreconnectTest 1590 class HttpStreamFactoryImplJobControllerPreconnectTest
1411 : public HttpStreamFactoryImplJobControllerTest, 1591 : public HttpStreamFactoryImplJobControllerTest,
1412 public ::testing::WithParamInterface<bool> { 1592 public ::testing::WithParamInterface<bool> {
1413 protected: 1593 protected:
1414 void SetUp() override { 1594 void SetUp() override {
1415 if (GetParam()) { 1595 if (GetParam()) {
1416 scoped_feature_list_.InitFromCommandLine("LimitEarlyPreconnects", 1596 scoped_feature_list_.InitFromCommandLine("LimitEarlyPreconnects",
1417 std::string()); 1597 std::string());
1418 } 1598 }
1419 } 1599 }
1420 1600
1421 void Initialize() { 1601 void Initialize() {
1422 session_deps_.http_server_properties = 1602 session_deps_.http_server_properties =
1423 base::MakeUnique<MockHttpServerProperties>(); 1603 base::MakeUnique<MockHttpServerProperties>();
1424 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); 1604 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
1425 factory_ = 1605 factory_ =
1426 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); 1606 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory());
1427 request_info_.method = "GET"; 1607 request_info_.method = "GET";
1428 request_info_.url = GURL("https://www.example.com"); 1608 request_info_.url = GURL("https://www.example.com");
1429 job_controller_ = new HttpStreamFactoryImpl::JobController( 1609 job_controller_ = new HttpStreamFactoryImpl::JobController(
1430 factory_, &request_delegate_, session_.get(), &job_factory_, 1610 factory_, &request_delegate_, session_.get(), &job_factory_,
1431 request_info_, /* is_preconnect = */ true, 1611 request_info_, /* is_preconnect = */ true,
1432 /* enable_ip_based_pooling = */ true, 1612 /* enable_ip_based_pooling = */ true,
1433 /* enable_alternative_services = */ true); 1613 /* enable_alternative_services = */ true, SSLConfig(), SSLConfig());
1434 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); 1614 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_);
1435 } 1615 }
1436 1616
1437 protected: 1617 protected:
1438 void Preconnect(int num_streams) { 1618 void Preconnect(int num_streams) {
1439 job_controller_->Preconnect(num_streams, request_info_, SSLConfig(), 1619 job_controller_->Preconnect(num_streams);
1440 SSLConfig());
1441 // Only one job is started. 1620 // Only one job is started.
1442 EXPECT_TRUE(job_controller_->main_job()); 1621 EXPECT_TRUE(job_controller_->main_job());
1443 EXPECT_FALSE(job_controller_->alternative_job()); 1622 EXPECT_FALSE(job_controller_->alternative_job());
1444 } 1623 }
1445 1624
1446 private: 1625 private:
1447 base::test::ScopedFeatureList scoped_feature_list_; 1626 base::test::ScopedFeatureList scoped_feature_list_;
1448 HttpRequestInfo request_info_; 1627 HttpRequestInfo request_info_;
1449 }; 1628 };
1450 1629
(...skipping 23 matching lines...) Expand all
1474 Preconnect(kNumPreconects); 1653 Preconnect(kNumPreconects);
1475 // If experiment is enabled, only 1 stream is requested. 1654 // If experiment is enabled, only 1 stream is requested.
1476 EXPECT_EQ( 1655 EXPECT_EQ(
1477 (int)actual_num_connects, 1656 (int)actual_num_connects,
1478 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); 1657 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job()));
1479 base::RunLoop().RunUntilIdle(); 1658 base::RunLoop().RunUntilIdle();
1480 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 1659 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
1481 } 1660 }
1482 1661
1483 } // namespace net 1662 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_stream_factory_impl_job_controller.cc ('k') | net/http/http_stream_factory_impl_request_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698