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

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

Issue 2814633003: Extract Proxy Resolution out of HttpStreamFactoryImpl::Job (Closed)
Patch Set: temp (do not review this patch. review next patch) Created 3 years, 7 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 <memory> 7 #include <memory>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
11 #include "base/run_loop.h" 11 #include "base/run_loop.h"
12 #include "base/test/histogram_tester.h" 12 #include "base/test/histogram_tester.h"
13 #include "base/test/scoped_feature_list.h" 13 #include "base/test/scoped_feature_list.h"
14 #include "base/test/scoped_mock_time_message_loop_task_runner.h" 14 #include "base/test/scoped_mock_time_message_loop_task_runner.h"
15 #include "base/threading/platform_thread.h" 15 #include "base/threading/platform_thread.h"
16 #include "net/base/test_proxy_delegate.h" 16 #include "net/base/test_proxy_delegate.h"
17 #include "net/dns/mock_host_resolver.h" 17 #include "net/dns/mock_host_resolver.h"
18 #include "net/http/http_basic_stream.h" 18 #include "net/http/http_basic_stream.h"
19 #include "net/http/http_stream_factory_impl_request.h" 19 #include "net/http/http_stream_factory_impl_request.h"
20 #include "net/http/http_stream_factory_test_util.h" 20 #include "net/http/http_stream_factory_test_util.h"
21 #include "net/log/net_log_with_source.h" 21 #include "net/log/net_log_with_source.h"
22 #include "net/proxy/mock_proxy_resolver.h" 22 #include "net/proxy/mock_proxy_resolver.h"
23 #include "net/proxy/proxy_config_service_fixed.h" 23 #include "net/proxy/proxy_config_service_fixed.h"
24 #include "net/proxy/proxy_info.h" 24 #include "net/proxy/proxy_info.h"
25 #include "net/proxy/proxy_service.h" 25 #include "net/proxy/proxy_service.h"
26 #include "net/quic/chromium/mock_crypto_client_stream_factory.h"
27 #include "net/quic/chromium/mock_quic_data.h"
28 #include "net/quic/chromium/quic_stream_factory.h"
26 #include "net/quic/chromium/quic_stream_factory_peer.h" 29 #include "net/quic/chromium/quic_stream_factory_peer.h"
30 #include "net/quic/chromium/quic_test_packet_maker.h"
27 #include "net/socket/socket_test_util.h" 31 #include "net/socket/socket_test_util.h"
28 #include "net/spdy/chromium/spdy_test_util_common.h" 32 #include "net/spdy/chromium/spdy_test_util_common.h"
29 #include "testing/gmock/include/gmock/gmock.h" 33 #include "testing/gmock/include/gmock/gmock.h"
30 #include "testing/gmock_mutant.h" 34 #include "testing/gmock_mutant.h"
31 #include "testing/gtest/include/gtest/gtest.h" 35 #include "testing/gtest/include/gtest/gtest.h"
32 36
33 using ::testing::_; 37 using ::testing::_;
34 using ::testing::Invoke; 38 using ::testing::Invoke;
35 39
36 namespace net { 40 namespace net {
37 41
38 namespace { 42 namespace {
39 43
44 const char kServerHostname[] = "www.example.com";
45
40 void DeleteHttpStreamPointer(const SSLConfig& used_ssl_config, 46 void DeleteHttpStreamPointer(const SSLConfig& used_ssl_config,
41 const ProxyInfo& used_proxy_info, 47 const ProxyInfo& used_proxy_info,
42 HttpStream* stream) { 48 HttpStream* stream) {
43 delete stream; 49 delete stream;
44 } 50 }
45 51
46 class FailingProxyResolverFactory : public ProxyResolverFactory { 52 class FailingProxyResolverFactory : public ProxyResolverFactory {
47 public: 53 public:
48 FailingProxyResolverFactory() : ProxyResolverFactory(false) {} 54 FailingProxyResolverFactory() : ProxyResolverFactory(false) {}
49 55
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 int Resolve(const RequestInfo& info, 88 int Resolve(const RequestInfo& info,
83 RequestPriority priority, 89 RequestPriority priority,
84 AddressList* addresses, 90 AddressList* addresses,
85 const CompletionCallback& callback, 91 const CompletionCallback& callback,
86 std::unique_ptr<Request>* out_req, 92 std::unique_ptr<Request>* out_req,
87 const NetLogWithSource& net_log) override { 93 const NetLogWithSource& net_log) override {
88 return ERR_IO_PENDING; 94 return ERR_IO_PENDING;
89 } 95 }
90 }; 96 };
91 97
98 // A mock QuicStreamRequest that always succeeds.
99 class MockQuicStreamRequest : public QuicStreamRequest {
100 public:
101 MockQuicStreamRequest(int net_error)
102 : QuicStreamRequest(nullptr, nullptr), net_error_(net_error) {}
103 ~MockQuicStreamRequest() {}
104
105 int Request(const HostPortPair& destination,
106 PrivacyMode privacy_mode,
107 int cert_verify_flags,
108 const GURL& url,
109 QuicStringPiece method,
110 const NetLogWithSource& net_log,
111 const CompletionCallback& callback) override {
112 return net_error_;
113 }
114
115 std::unique_ptr<HttpStream> CreateStream() override {
116 if (net_error_ != OK) {
117 NOTREACHED();
118 return nullptr;
119 }
120 return base::MakeUnique<HttpBasicStream>(
121 base::MakeUnique<ClientSocketHandle>(), false, false);
122 }
123
124 std::unique_ptr<BidirectionalStreamImpl> CreateBidirectionalStreamImpl()
125 override {
126 NOTREACHED();
127 return nullptr;
128 }
129
130 private:
131 int net_error_;
132 };
133
134 // A mock QuicStreamRequest that always succeeds.
135 class MockQuicStreamRequestFactory : public QuicStreamRequestFactory {
136 public:
137 MockQuicStreamRequestFactory(int net_error)
138 : QuicStreamRequestFactory(), net_error_(net_error) {}
139 ~MockQuicStreamRequestFactory() {}
140
141 std::unique_ptr<QuicStreamRequest> CreateRequest(
142 QuicStreamFactory* factory,
143 HttpServerProperties* http_server_properties) override {
144 return base::MakeUnique<MockQuicStreamRequest>(net_error_);
145 }
146
147 private:
148 int net_error_;
149 };
150
92 // A mock HttpServerProperties that always returns false for IsInitialized(). 151 // A mock HttpServerProperties that always returns false for IsInitialized().
93 class MockHttpServerProperties : public HttpServerPropertiesImpl { 152 class MockHttpServerProperties : public HttpServerPropertiesImpl {
94 public: 153 public:
95 MockHttpServerProperties() {} 154 MockHttpServerProperties() {}
96 ~MockHttpServerProperties() override {} 155 ~MockHttpServerProperties() override {}
97 bool IsInitialized() const override { return false; } 156 bool IsInitialized() const override { return false; }
98 }; 157 };
99 158
100 } // anonymous namespace 159 } // anonymous namespace
101 160
(...skipping 18 matching lines...) Expand all
120 static bool main_job_is_blocked( 179 static bool main_job_is_blocked(
121 HttpStreamFactoryImpl::JobController* job_controller) { 180 HttpStreamFactoryImpl::JobController* job_controller) {
122 return job_controller->main_job_is_blocked_; 181 return job_controller->main_job_is_blocked_;
123 } 182 }
124 }; 183 };
125 184
126 class HttpStreamFactoryImplJobControllerTest : public ::testing::Test { 185 class HttpStreamFactoryImplJobControllerTest : public ::testing::Test {
127 public: 186 public:
128 HttpStreamFactoryImplJobControllerTest() 187 HttpStreamFactoryImplJobControllerTest()
129 : session_deps_(ProxyService::CreateDirect()), 188 : session_deps_(ProxyService::CreateDirect()),
189 client_maker_(kSupportedQuicVersions[0],
190 0,
191 &clock_,
192 kServerHostname,
193 Perspective::IS_CLIENT),
130 use_alternative_proxy_(false), 194 use_alternative_proxy_(false),
131 is_preconnect_(false), 195 is_preconnect_(false),
132 enable_ip_based_pooling_(true), 196 enable_ip_based_pooling_(true),
133 enable_alternative_services_(true), 197 enable_alternative_services_(true),
134 test_proxy_delegate_(nullptr) { 198 test_proxy_delegate_(nullptr) {
135 session_deps_.enable_quic = true; 199 session_deps_.enable_quic = true;
136 } 200 }
137 201
138 void UseAlternativeProxy() { 202 void UseAlternativeProxy() {
139 ASSERT_FALSE(test_proxy_delegate_); 203 ASSERT_FALSE(test_proxy_delegate_);
(...skipping 19 matching lines...) Expand all
159 ASSERT_FALSE(test_proxy_delegate_); 223 ASSERT_FALSE(test_proxy_delegate_);
160 std::unique_ptr<TestProxyDelegate> test_proxy_delegate( 224 std::unique_ptr<TestProxyDelegate> test_proxy_delegate(
161 new TestProxyDelegate()); 225 new TestProxyDelegate());
162 test_proxy_delegate_ = test_proxy_delegate.get(); 226 test_proxy_delegate_ = test_proxy_delegate.get();
163 227
164 test_proxy_delegate->set_alternative_proxy_server( 228 test_proxy_delegate->set_alternative_proxy_server(
165 ProxyServer::FromPacString("QUIC myproxy.org:443")); 229 ProxyServer::FromPacString("QUIC myproxy.org:443"));
166 EXPECT_TRUE(test_proxy_delegate->alternative_proxy_server().is_quic()); 230 EXPECT_TRUE(test_proxy_delegate->alternative_proxy_server().is_quic());
167 session_deps_.proxy_delegate = std::move(test_proxy_delegate); 231 session_deps_.proxy_delegate = std::move(test_proxy_delegate);
168 232
233 if (tcp_data_)
234 session_deps_.socket_factory->AddSocketDataProvider(tcp_data_.get());
235
169 if (use_alternative_proxy_) { 236 if (use_alternative_proxy_) {
170 std::unique_ptr<ProxyService> proxy_service = 237 std::unique_ptr<ProxyService> proxy_service =
171 ProxyService::CreateFixedFromPacResult("HTTPS myproxy.org:443"); 238 ProxyService::CreateFixedFromPacResult("HTTPS myproxy.org:443");
172 session_deps_.proxy_service = std::move(proxy_service); 239 session_deps_.proxy_service = std::move(proxy_service);
173 } 240 }
174 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); 241 HttpNetworkSession::Params params =
242 SpdySessionDependencies::CreateSessionParams(&session_deps_);
243 params.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
244 session_ = base::MakeUnique<HttpNetworkSession>(params);
175 factory_ = 245 factory_ =
176 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); 246 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory());
177 job_controller_ = new HttpStreamFactoryImpl::JobController( 247 job_controller_ = new HttpStreamFactoryImpl::JobController(
178 factory_, &request_delegate_, session_.get(), &job_factory_, 248 factory_, &request_delegate_, session_.get(), &job_factory_,
179 request_info, is_preconnect_, enable_ip_based_pooling_, 249 request_info, is_preconnect_, enable_ip_based_pooling_,
180 enable_alternative_services_); 250 enable_alternative_services_, SSLConfig(), SSLConfig());
181 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); 251 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_);
182 } 252 }
183 253
184 TestProxyDelegate* test_proxy_delegate() const { 254 TestProxyDelegate* test_proxy_delegate() const {
185 return test_proxy_delegate_; 255 return test_proxy_delegate_;
186 } 256 }
187 257
188 ~HttpStreamFactoryImplJobControllerTest() override {} 258 ~HttpStreamFactoryImplJobControllerTest() override {
259 if (tcp_data_) {
260 EXPECT_TRUE(tcp_data_->AllReadDataConsumed());
261 EXPECT_TRUE(tcp_data_->AllWriteDataConsumed());
262 }
263 }
189 264
190 void SetAlternativeService(const HttpRequestInfo& request_info, 265 void SetAlternativeService(const HttpRequestInfo& request_info,
191 AlternativeService alternative_service) { 266 AlternativeService alternative_service) {
192 HostPortPair host_port_pair = HostPortPair::FromURL(request_info.url); 267 HostPortPair host_port_pair = HostPortPair::FromURL(request_info.url);
193 url::SchemeHostPort server(request_info.url); 268 url::SchemeHostPort server(request_info.url);
194 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); 269 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
195 session_->http_server_properties()->SetAlternativeService( 270 session_->http_server_properties()->SetAlternativeService(
196 server, alternative_service, expiration); 271 server, alternative_service, expiration);
197 } 272 }
198 273
199 void VerifyBrokenAlternateProtocolMapping(const HttpRequestInfo& request_info, 274 void VerifyBrokenAlternateProtocolMapping(const HttpRequestInfo& request_info,
200 bool should_mark_broken) { 275 bool should_mark_broken) {
201 const url::SchemeHostPort server(request_info.url); 276 const url::SchemeHostPort server(request_info.url);
202 const AlternativeServiceVector alternative_service_vector = 277 const AlternativeServiceVector alternative_service_vector =
203 session_->http_server_properties()->GetAlternativeServices(server); 278 session_->http_server_properties()->GetAlternativeServices(server);
204 EXPECT_EQ(1u, alternative_service_vector.size()); 279 EXPECT_EQ(1u, alternative_service_vector.size());
205 EXPECT_EQ(should_mark_broken, 280 EXPECT_EQ(should_mark_broken,
206 session_->http_server_properties()->IsAlternativeServiceBroken( 281 session_->http_server_properties()->IsAlternativeServiceBroken(
207 alternative_service_vector[0])); 282 alternative_service_vector[0]));
208 } 283 }
209 284
210 TestJobFactory job_factory_; 285 TestJobFactory job_factory_;
211 MockHttpStreamRequestDelegate request_delegate_; 286 MockHttpStreamRequestDelegate request_delegate_;
212 SpdySessionDependencies session_deps_; 287 SpdySessionDependencies session_deps_;
213 std::unique_ptr<HttpNetworkSession> session_; 288 std::unique_ptr<HttpNetworkSession> session_;
214 HttpStreamFactoryImpl* factory_; 289 HttpStreamFactoryImpl* factory_;
215 HttpStreamFactoryImpl::JobController* job_controller_; 290 HttpStreamFactoryImpl::JobController* job_controller_;
216 std::unique_ptr<HttpStreamFactoryImpl::Request> request_; 291 std::unique_ptr<HttpStreamFactoryImpl::Request> request_;
292 std::unique_ptr<SequencedSocketData> tcp_data_;
293 MockCryptoClientStreamFactory crypto_client_stream_factory_;
294 MockClock clock_;
295 test::QuicTestPacketMaker client_maker_;
217 296
218 private: 297 private:
219 bool use_alternative_proxy_; 298 bool use_alternative_proxy_;
220 bool is_preconnect_; 299 bool is_preconnect_;
221 bool enable_ip_based_pooling_; 300 bool enable_ip_based_pooling_;
222 bool enable_alternative_services_; 301 bool enable_alternative_services_;
223 302
224 // Not owned by |this|. 303 // Not owned by |this|.
225 TestProxyDelegate* test_proxy_delegate_; 304 TestProxyDelegate* test_proxy_delegate_;
226 305
227 DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest); 306 DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest);
228 }; 307 };
229 308
230 TEST_F(HttpStreamFactoryImplJobControllerTest, 309 TEST_F(HttpStreamFactoryImplJobControllerTest, ProxyResolutionFailsSync) {
231 OnStreamFailedWithNoAlternativeJob) {
232 ProxyConfig proxy_config; 310 ProxyConfig proxy_config;
233 proxy_config.set_auto_detect(true); 311 proxy_config.set_pac_url(GURL("http://www.example.com"));
234 // Use asynchronous proxy resolver. 312 proxy_config.set_pac_mandatory(true);
313 MockAsyncProxyResolver resolver;
314 session_deps_.proxy_service.reset(new ProxyService(
315 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
316 base::WrapUnique(new FailingProxyResolverFactory), nullptr));
317 HttpRequestInfo request_info;
318 request_info.method = "GET";
319 request_info.url = GURL("http://www.google.com");
320
321 Initialize(request_info);
322
323 EXPECT_CALL(request_delegate_,
324 OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _))
325 .Times(1);
326 request_.reset(
327 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
328 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
329
330 EXPECT_FALSE(job_controller_->main_job());
331 EXPECT_FALSE(job_controller_->alternative_job());
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://www.example.com"));
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));
348 HttpRequestInfo request_info;
349 request_info.method = "GET";
350 request_info.url = GURL("http://www.google.com");
351
352 Initialize(request_info);
353
354 request_.reset(
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_CALL(request_delegate_,
362 OnStreamFailed(ERR_MANDATORY_PROXY_CONFIGURATION_FAILED, _))
363 .Times(1);
364 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
365 ERR_FAILED, &resolver);
366 base::RunLoop().RunUntilIdle();
367 request_.reset();
368 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
369 }
370
371 TEST_F(HttpStreamFactoryImplJobControllerTest,
372 OnStreamFailedWithNoAlternativeJob) {
373 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
374 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
240 375
241 HttpRequestInfo request_info; 376 HttpRequestInfo request_info;
242 request_info.method = "GET"; 377 request_info.method = "GET";
243 request_info.url = GURL("http://www.google.com"); 378 request_info.url = GURL("http://www.google.com");
244 379
245 Initialize(request_info); 380 Initialize(request_info);
246 381
247 request_.reset( 382 request_.reset(
248 job_controller_->Start(request_info, &request_delegate_, nullptr, 383 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
249 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 384 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
250 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
251 385
252 EXPECT_TRUE(job_controller_->main_job()); 386 EXPECT_TRUE(job_controller_->main_job());
387 EXPECT_FALSE(job_controller_->alternative_job());
253 388
254 // There's no other alternative job. Thus when stream failed, it should 389 // There's no other alternative job. Thus when stream failed, it should
255 // notify Request of the stream failure. 390 // notify Request of the stream failure.
256 EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_FAILED, _)).Times(1); 391 EXPECT_CALL(request_delegate_, OnStreamFailed(ERR_FAILED, _)).Times(1);
257 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, 392 base::RunLoop().RunUntilIdle();
258 SSLConfig());
259 } 393 }
260 394
261 TEST_F(HttpStreamFactoryImplJobControllerTest, 395 TEST_F(HttpStreamFactoryImplJobControllerTest,
262 OnStreamReadyWithNoAlternativeJob) { 396 OnStreamReadyWithNoAlternativeJob) {
263 ProxyConfig proxy_config; 397 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
264 proxy_config.set_auto_detect(true); 398 tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
265 // Use asynchronous proxy resolver. 399
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; 400 HttpRequestInfo request_info;
272 request_info.method = "GET"; 401 request_info.method = "GET";
273 request_info.url = GURL("http://www.google.com"); 402 request_info.url = GURL("http://www.google.com");
274 403
275 Initialize(request_info); 404 Initialize(request_info);
276 405
277 request_.reset( 406 request_.reset(
278 job_controller_->Start(request_info, &request_delegate_, nullptr, 407 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
279 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 408 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
280 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
281 409
282 // There's no other alternative job. Thus when a stream is ready, it should 410 // There's no other alternative job. Thus when a stream is ready, it should
283 // notify Request. 411 // notify Request.
284 HttpStream* http_stream = 412 EXPECT_TRUE(job_controller_->main_job());
285 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
286 job_factory_.main_job()->SetStream(http_stream);
287 413
288 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) 414 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
289 .WillOnce(Invoke(DeleteHttpStreamPointer)); 415 .WillOnce(Invoke(DeleteHttpStreamPointer));
290 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); 416 base::RunLoop().RunUntilIdle();
291 } 417 }
292 418
293 // Test we cancel Jobs correctly when the Request is explicitly canceled 419 // Test we cancel Jobs correctly when the Request is explicitly canceled
294 // before any Job is bound to Request. 420 // before any Job is bound to Request.
295 TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) { 421 TEST_F(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) {
296 ProxyConfig proxy_config; 422 // One TCP connect.
297 proxy_config.set_auto_detect(true); 423 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
298 // Use asynchronous proxy resolver. 424 tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
299 MockAsyncProxyResolverFactory* proxy_resolver_factory =
300 new MockAsyncProxyResolverFactory(false);
301 session_deps_.proxy_service.reset(new ProxyService(
302 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)),
303 base::WrapUnique(proxy_resolver_factory), nullptr));
304
305 HttpRequestInfo request_info; 425 HttpRequestInfo request_info;
306 request_info.method = "GET"; 426 request_info.method = "GET";
307 request_info.url = GURL("https://www.google.com"); 427 request_info.url = GURL("https://www.google.com");
308 428
309 Initialize(request_info); 429 Initialize(request_info);
310 url::SchemeHostPort server(request_info.url); 430 url::SchemeHostPort server(request_info.url);
311 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 431 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
312 SetAlternativeService(request_info, alternative_service); 432 SetAlternativeService(request_info, alternative_service);
313 433
434 /**
435 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
436 session_->quic_stream_factory(),
437 base::MakeUnique<MockQuicStreamRequestFactory>(OK));
438 */
439
314 request_.reset( 440 request_.reset(
315 job_controller_->Start(request_info, &request_delegate_, nullptr, 441 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
316 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 442 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
317 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
318 EXPECT_TRUE(job_controller_->main_job()); 443 EXPECT_TRUE(job_controller_->main_job());
319 EXPECT_TRUE(job_controller_->alternative_job()); 444 EXPECT_TRUE(job_controller_->alternative_job());
320 445
321 // Reset the Request will cancel all the Jobs since there's no Job determined 446 // 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 447 // to serve Request yet and JobController will notify the factory to delete
323 // itself upon completion. 448 // itself upon completion.
324 request_.reset(); 449 request_.reset();
325 VerifyBrokenAlternateProtocolMapping(request_info, false); 450 VerifyBrokenAlternateProtocolMapping(request_info, false);
326 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 451 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
327 } 452 }
328 453
329 TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) { 454 TEST_F(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) {
330 ProxyConfig proxy_config; 455 // One TCP connect and one UDP connect.
331 proxy_config.set_auto_detect(true); 456 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
332 // Use asynchronous proxy resolver. 457 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
333 MockAsyncProxyResolverFactory* proxy_resolver_factory =
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 458
339 HttpRequestInfo request_info; 459 HttpRequestInfo request_info;
340 request_info.method = "GET"; 460 request_info.method = "GET";
341 request_info.url = GURL("https://www.google.com"); 461 request_info.url = GURL("https://www.google.com");
342 462
343 Initialize(request_info); 463 Initialize(request_info);
344 url::SchemeHostPort server(request_info.url); 464 url::SchemeHostPort server(request_info.url);
345 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 465 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
346 SetAlternativeService(request_info, alternative_service); 466 SetAlternativeService(request_info, alternative_service);
347 467
468 /**
469 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
470 session_->quic_stream_factory(),
471 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED));
472 */
473
348 request_.reset( 474 request_.reset(
349 job_controller_->Start(request_info, &request_delegate_, nullptr, 475 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
350 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 476 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
351 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
352 EXPECT_TRUE(job_controller_->main_job()); 477 EXPECT_TRUE(job_controller_->main_job());
353 EXPECT_TRUE(job_controller_->alternative_job()); 478 EXPECT_TRUE(job_controller_->alternative_job());
354 479
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 480 // The failure of second Job should be reported to Request as there's no more
365 // pending Job to serve the Request. 481 // pending Job to serve the Request.
366 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); 482 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1);
367 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, 483 base::RunLoop().RunUntilIdle();
368 SSLConfig());
369 VerifyBrokenAlternateProtocolMapping(request_info, false); 484 VerifyBrokenAlternateProtocolMapping(request_info, false);
485 request_.reset();
486 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
370 } 487 }
371 488
372 TEST_F(HttpStreamFactoryImplJobControllerTest, 489 TEST_F(HttpStreamFactoryImplJobControllerTest,
373 AltJobFailsAfterMainJobSucceeds) { 490 AltJobFailsAfterMainJobSucceeds) {
374 ProxyConfig proxy_config; 491 // One TCP connect.
375 proxy_config.set_auto_detect(true); 492 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
376 // Use asynchronous proxy resolver. 493 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
377 MockAsyncProxyResolverFactory* proxy_resolver_factory = 494 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
378 new MockAsyncProxyResolverFactory(false); 495 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
379 session_deps_.proxy_service.reset(
380 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
381 base::WrapUnique(proxy_resolver_factory), nullptr));
382 496
383 HttpRequestInfo request_info; 497 HttpRequestInfo request_info;
384 request_info.method = "GET"; 498 request_info.method = "GET";
385 request_info.url = GURL("https://www.google.com"); 499 request_info.url = GURL("https://www.google.com");
386 500
387 Initialize(request_info); 501 Initialize(request_info);
388 url::SchemeHostPort server(request_info.url); 502 url::SchemeHostPort server(request_info.url);
389 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 503 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
390 SetAlternativeService(request_info, alternative_service); 504 SetAlternativeService(request_info, alternative_service);
505 /**
506 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
507 session_->quic_stream_factory(),
508 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED));
509 */
391 510
392 request_.reset( 511 request_.reset(
393 job_controller_->Start(request_info, &request_delegate_, nullptr, 512 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
394 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 513 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
395 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
396 EXPECT_TRUE(job_controller_->main_job()); 514 EXPECT_TRUE(job_controller_->main_job());
397 EXPECT_TRUE(job_controller_->alternative_job()); 515 EXPECT_TRUE(job_controller_->alternative_job());
398 516
399 // Main job succeeds, starts serving Request and it should report status 517 // 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 518 // to Request. The alternative job will mark the main job complete and gets
401 // orphaned. 519 // orphaned.
402 HttpStream* http_stream = 520 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)); 521 .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 522 // JobController shouldn't report the status of second job as request
411 // is already successfully served. 523 // is already successfully served.
412 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 524 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
413 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, 525
414 SSLConfig()); 526 base::RunLoop().RunUntilIdle();
415 527
416 VerifyBrokenAlternateProtocolMapping(request_info, true); 528 VerifyBrokenAlternateProtocolMapping(request_info, true);
417 // Reset the request as it's been successfully served. 529 // Reset the request as it's been successfully served.
418 request_.reset(); 530 request_.reset();
419 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 531 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
420 } 532 }
421 533
422 // Tests that if alt job succeeds and main job is blocked, main job should be 534 // 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. 535 // cancelled immediately. |request_| completion will clean up the JobController.
424 // Regression test for crbug.com/678768. 536 // Regression test for crbug.com/678768.
425 TEST_F(HttpStreamFactoryImplJobControllerTest, 537 TEST_F(HttpStreamFactoryImplJobControllerTest,
426 AltJobSucceedsMainJobBlockedControllerDestroyed) { 538 AltJobSucceedsMainJobBlockedControllerDestroyed) {
427 ProxyConfig proxy_config;
428 proxy_config.set_auto_detect(true);
429 MockAsyncProxyResolverFactory* proxy_resolver_factory =
430 new MockAsyncProxyResolverFactory(false);
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; 539 HttpRequestInfo request_info;
435 request_info.method = "GET"; 540 request_info.method = "GET";
436 request_info.url = GURL("https://www.google.com"); 541 request_info.url = GURL("https://www.google.com");
437 542
438 Initialize(request_info); 543 Initialize(request_info);
439 544
545 /**
546 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
547 session_->quic_stream_factory(),
548 base::MakeUnique<MockQuicStreamRequestFactory>(OK));
549 */
550
440 url::SchemeHostPort server(request_info.url); 551 url::SchemeHostPort server(request_info.url);
441 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 552 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
442 SetAlternativeService(request_info, alternative_service); 553 SetAlternativeService(request_info, alternative_service);
443 request_.reset( 554 request_.reset(
444 job_controller_->Start(request_info, &request_delegate_, nullptr, 555 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
445 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 556 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
446 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
447 EXPECT_TRUE(job_controller_->main_job()); 557 EXPECT_TRUE(job_controller_->main_job());
448 EXPECT_TRUE(job_controller_->alternative_job()); 558 EXPECT_TRUE(job_controller_->alternative_job());
449 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); 559 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
450 560
451 // |alternative_job| succeeds and should report status to Request. 561 // |alternative_job| succeeds and should report status to |request_delegate_|.
452 HttpStream* http_stream = 562 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)); 563 .WillOnce(Invoke(DeleteHttpStreamPointer));
457 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); 564
565 base::RunLoop().RunUntilIdle();
458 566
459 EXPECT_FALSE(job_controller_->main_job()); 567 EXPECT_FALSE(job_controller_->main_job());
460 EXPECT_TRUE(job_controller_->alternative_job()); 568 EXPECT_TRUE(job_controller_->alternative_job());
461 569
462 // Invoke OnRequestComplete() which should delete |job_controller_| from 570 // Invoke OnRequestComplete() which should delete |job_controller_| from
463 // |factory_|. 571 // |factory_|.
464 request_.reset(); 572 request_.reset();
465 VerifyBrokenAlternateProtocolMapping(request_info, false); 573 VerifyBrokenAlternateProtocolMapping(request_info, false);
466 // This fails without the fix for crbug.com/678768. 574 // This fails without the fix for crbug.com/678768.
467 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 575 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
468 } 576 }
469 577
470 // Tests that if an orphaned job completes after |request_| is gone, 578 // Tests that if an orphaned job completes after |request_| is gone,
471 // JobController will be cleaned up. 579 // JobController will be cleaned up.
472 TEST_F(HttpStreamFactoryImplJobControllerTest, 580 TEST_F(HttpStreamFactoryImplJobControllerTest,
473 OrphanedJobCompletesControllerDestroyed) { 581 OrphanedJobCompletesControllerDestroyed) {
474 ProxyConfig proxy_config; 582 // One TCP connect.
475 proxy_config.set_auto_detect(true); 583 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
476 MockAsyncProxyResolverFactory* proxy_resolver_factory = 584 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
477 new MockAsyncProxyResolverFactory(false); 585 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
478 session_deps_.proxy_service.reset( 586 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
479 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), 587
480 base::WrapUnique(proxy_resolver_factory), nullptr));
481 HttpRequestInfo request_info; 588 HttpRequestInfo request_info;
482 request_info.method = "GET"; 589 request_info.method = "GET";
483 request_info.url = GURL("https://www.google.com"); 590 request_info.url = GURL("https://www.google.com");
484 591
485 Initialize(request_info); 592 Initialize(request_info);
486 593
594 // Make QuicStreamRequest complete asynchonously.
595 /**
596 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
597 session_->quic_stream_factory(),
598 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING));
599 */
600
487 url::SchemeHostPort server(request_info.url); 601 url::SchemeHostPort server(request_info.url);
488 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 602 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
489 SetAlternativeService(request_info, alternative_service); 603 SetAlternativeService(request_info, alternative_service);
490 // Hack to use different URL for the main job to help differentiate the proxy 604
491 // requests.
492 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com"));
493 request_.reset( 605 request_.reset(
494 job_controller_->Start(request_info, &request_delegate_, nullptr, 606 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
495 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 607 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
496 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
497 EXPECT_TRUE(job_controller_->main_job()); 608 EXPECT_TRUE(job_controller_->main_job());
498 EXPECT_TRUE(job_controller_->alternative_job()); 609 EXPECT_TRUE(job_controller_->alternative_job());
499 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); 610 // main job should not be blocked because alt job returned ERR_IO_PENDING.
611 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
612
613 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
614 .WillOnce(Invoke(DeleteHttpStreamPointer));
500 615
501 // Complete main job now. 616 // Complete main job now.
502 MockAsyncProxyResolver resolver; 617 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 618
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 619 // Invoke OnRequestComplete() which should not delete |job_controller_| from
520 // |factory_| because alt job is yet to finish. 620 // |factory_| because alt job is yet to finish.
521 request_.reset(); 621 request_.reset();
522 ASSERT_FALSE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 622 ASSERT_FALSE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
523 EXPECT_FALSE(job_controller_->main_job()); 623 EXPECT_FALSE(job_controller_->main_job());
524 EXPECT_TRUE(job_controller_->alternative_job()); 624 EXPECT_TRUE(job_controller_->alternative_job());
525 625
526 // Make |alternative_job| succeed. 626 // Make |alternative_job| succeed.
527 resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80"); 627 HttpStream* http_stream =
528 resolver.pending_jobs()[0]->CompleteNow(net::OK);
529 HttpStream* http_stream2 =
530 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); 628 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
531 job_factory_.alternative_job()->SetStream(http_stream2); 629 job_factory_.alternative_job()->SetStream(http_stream);
532 // This should not call request_delegate_::OnStreamReady. 630 // This should not call request_delegate_::OnStreamReady.
533 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); 631 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
534 // Make sure that controller does not leak. 632 // Make sure that controller does not leak.
535 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 633 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
536 } 634 }
537 635
538 TEST_F(HttpStreamFactoryImplJobControllerTest, 636 TEST_F(HttpStreamFactoryImplJobControllerTest,
539 AltJobSucceedsAfterMainJobFailed) { 637 AltJobSucceedsAfterMainJobFailed) {
540 ProxyConfig proxy_config; 638 // One failed TCP connect.
541 proxy_config.set_auto_detect(true); 639 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
542 // Use asynchronous proxy resolver. 640 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, ERR_FAILED));
543 MockAsyncProxyResolverFactory* proxy_resolver_factory = 641
544 new MockAsyncProxyResolverFactory(false);
545 session_deps_.proxy_service.reset(
546 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
547 base::WrapUnique(proxy_resolver_factory), nullptr));
548 HttpRequestInfo request_info; 642 HttpRequestInfo request_info;
549 request_info.method = "GET"; 643 request_info.method = "GET";
550 request_info.url = GURL("https://www.google.com"); 644 request_info.url = GURL("https://www.google.com");
551 645
552 Initialize(request_info); 646 Initialize(request_info);
553 647
554 url::SchemeHostPort server(request_info.url); 648 url::SchemeHostPort server(request_info.url);
555 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 649 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
556 SetAlternativeService(request_info, alternative_service); 650 SetAlternativeService(request_info, alternative_service);
557 651
558 request_.reset( 652 /**
559 job_controller_->Start(request_info, &request_delegate_, nullptr, 653 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
560 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 654 session_->quic_stream_factory(),
561 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); 655 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING));
562 EXPECT_TRUE(job_controller_->main_job()); 656 */
563 EXPECT_TRUE(job_controller_->alternative_job());
564 657
565 // |main_job| fails but should not report status to Request. 658 // |main_job| fails but should not report status to Request.
566 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 659 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
567 660
568 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, 661 request_.reset(
569 SSLConfig()); 662 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
663 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
664 EXPECT_TRUE(job_controller_->main_job());
665 EXPECT_TRUE(job_controller_->alternative_job());
570 666
571 // |alternative_job| succeeds and should report status to Request. 667 base::RunLoop().RunUntilIdle();
668
669 // Make |alternative_job| succeed.
572 HttpStream* http_stream = 670 HttpStream* http_stream =
573 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); 671 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
574 job_factory_.alternative_job()->SetStream(http_stream);
575 672
576 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) 673 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
577 .WillOnce(Invoke(DeleteHttpStreamPointer)); 674 .WillOnce(Invoke(DeleteHttpStreamPointer));
675
676 job_factory_.alternative_job()->SetStream(http_stream);
578 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); 677 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
678
679 // |alternative_job| succeeds and should report status to Request.
579 VerifyBrokenAlternateProtocolMapping(request_info, false); 680 VerifyBrokenAlternateProtocolMapping(request_info, false);
580 } 681 }
581 682
582 TEST_F(HttpStreamFactoryImplJobControllerTest, 683 TEST_F(HttpStreamFactoryImplJobControllerTest,
583 MainJobSucceedsAfterAltJobFailed) { 684 MainJobSucceedsAfterAltJobFailed) {
685 // One TCP connect.
686 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
687 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
688 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
689 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
690
584 base::HistogramTester histogram_tester; 691 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; 692 HttpRequestInfo request_info;
594 request_info.method = "GET"; 693 request_info.method = "GET";
595 request_info.url = GURL("https://www.google.com"); 694 request_info.url = GURL("https://www.google.com");
596 695
597 Initialize(request_info); 696 Initialize(request_info);
598 697
599 url::SchemeHostPort server(request_info.url); 698 url::SchemeHostPort server(request_info.url);
600 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 699 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
601 SetAlternativeService(request_info, alternative_service); 700 SetAlternativeService(request_info, alternative_service);
701 /*
702 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
703 session_->quic_stream_factory(),
704 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED));
705 */
602 706
603 request_.reset( 707 request_.reset(
604 job_controller_->Start(request_info, &request_delegate_, nullptr, 708 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
605 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 709 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
606 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
607 EXPECT_TRUE(job_controller_->main_job()); 710 EXPECT_TRUE(job_controller_->main_job());
608 EXPECT_TRUE(job_controller_->alternative_job()); 711 EXPECT_TRUE(job_controller_->alternative_job());
609 712
610 // |alternative_job| fails but should not report status to Request. 713 // |alternative_job| fails but should not report status to Request.
611 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 714 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
715 // |main_job| succeeds and should report status to Request.
716 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
717 .WillOnce(Invoke(DeleteHttpStreamPointer));
612 718
613 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED, 719 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 720
625 // Verify that the alternate protocol is marked as broken. 721 // Verify that the alternate protocol is marked as broken.
626 VerifyBrokenAlternateProtocolMapping(request_info, true); 722 VerifyBrokenAlternateProtocolMapping(request_info, true);
627 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", -ERR_FAILED, 723 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", -ERR_FAILED,
628 1); 724 1);
629 } 725 }
630 726
631 // Verifies that if the alternative job fails due to a connection change event, 727 // Verifies that if the alternative job fails due to a connection change event,
632 // then the alternative service is not marked as broken. 728 // then the alternative service is not marked as broken.
633 TEST_F(HttpStreamFactoryImplJobControllerTest, 729 TEST_F(HttpStreamFactoryImplJobControllerTest,
634 MainJobSucceedsAfterConnectionChanged) { 730 MainJobSucceedsAfterConnectionChanged) {
731 // One TCP connect.
732 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
733 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
734 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
735 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
736
635 base::HistogramTester histogram_tester; 737 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 session_deps_.quic_do_not_mark_as_broken_on_network_change = true; 738 session_deps_.quic_do_not_mark_as_broken_on_network_change = true;
645 739
646 HttpRequestInfo request_info; 740 HttpRequestInfo request_info;
647 request_info.method = "GET"; 741 request_info.method = "GET";
648 request_info.url = GURL("https://www.google.com"); 742 request_info.url = GURL("https://www.google.com");
649 Initialize(request_info); 743 Initialize(request_info);
650 744
651 url::SchemeHostPort server(request_info.url); 745 url::SchemeHostPort server(request_info.url);
652 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 746 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
653 SetAlternativeService(request_info, alternative_service); 747 SetAlternativeService(request_info, alternative_service);
654 748
749 /**
750 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
751 session_->quic_stream_factory(),
752 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_NETWORK_CHANGED));
753 */
754
655 request_.reset( 755 request_.reset(
656 job_controller_->Start(request_info, &request_delegate_, nullptr, 756 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
657 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 757 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
658 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
659 EXPECT_TRUE(job_controller_->main_job()); 758 EXPECT_TRUE(job_controller_->main_job());
660 EXPECT_TRUE(job_controller_->alternative_job()); 759 EXPECT_TRUE(job_controller_->alternative_job());
661 760
662 // |alternative_job| fails but should not report status to Request. 761 // |alternative_job| fails but should not report status to Request.
663 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 762 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
664
665 job_controller_->OnStreamFailed(job_factory_.alternative_job(),
666 ERR_NETWORK_CHANGED, SSLConfig());
667
668 // |main_job| succeeds and should report status to Request. 763 // |main_job| succeeds and should report status to Request.
669 HttpStream* http_stream = 764 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
670 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
671 job_factory_.main_job()->SetStream(http_stream);
672
673 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
674 .WillOnce(Invoke(DeleteHttpStreamPointer)); 765 .WillOnce(Invoke(DeleteHttpStreamPointer));
675 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); 766 base::RunLoop().RunUntilIdle();
676 767
677 // Verify that the alternate protocol is not marked as broken. 768 // Verify that the alternate protocol is not marked as broken.
678 VerifyBrokenAlternateProtocolMapping(request_info, false); 769 VerifyBrokenAlternateProtocolMapping(request_info, false);
679 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed", 770 histogram_tester.ExpectUniqueSample("Net.AlternateServiceFailed",
680 -ERR_NETWORK_CHANGED, 1); 771 -ERR_NETWORK_CHANGED, 1);
681 } 772 }
682 773
683 // Regression test for crbug/621069. 774 // Regression test for crbug/621069.
684 // Get load state after main job fails and before alternative job succeeds. 775 // Get load state after main job fails and before alternative job succeeds.
685 TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) { 776 TEST_F(HttpStreamFactoryImplJobControllerTest, GetLoadStateAfterMainJobFailed) {
686 ProxyConfig proxy_config; 777 // One failed TCP connect.
687 proxy_config.set_auto_detect(true); 778 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
688 // Use asynchronous proxy resolver. 779 tcp_data_->set_connect_data(MockConnect(ASYNC, ERR_FAILED));
689 MockAsyncProxyResolverFactory* proxy_resolver_factory =
690 new MockAsyncProxyResolverFactory(false);
691 session_deps_.proxy_service.reset(new ProxyService(
692 base::WrapUnique(new ProxyConfigServiceFixed(proxy_config)),
693 base::WrapUnique(proxy_resolver_factory), nullptr));
694 780
695 HttpRequestInfo request_info; 781 HttpRequestInfo request_info;
696 request_info.method = "GET"; 782 request_info.method = "GET";
697 request_info.url = GURL("https://www.google.com"); 783 request_info.url = GURL("https://www.google.com");
698 784
699 Initialize(request_info); 785 Initialize(request_info);
700 url::SchemeHostPort server(request_info.url); 786 url::SchemeHostPort server(request_info.url);
701 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 787 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
702 SetAlternativeService(request_info, alternative_service); 788 SetAlternativeService(request_info, alternative_service);
703 789
790 /**
791 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
792 session_->quic_stream_factory(),
793 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING));
794 */
795
704 request_.reset( 796 request_.reset(
705 job_controller_->Start(request_info, &request_delegate_, nullptr, 797 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
706 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 798 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
707 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
708 EXPECT_TRUE(job_controller_->main_job()); 799 EXPECT_TRUE(job_controller_->main_job());
709 EXPECT_TRUE(job_controller_->alternative_job()); 800 EXPECT_TRUE(job_controller_->alternative_job());
710 801
711 // |main_job| fails but should not report status to Request. 802 // |main_job| fails but should not report status to Request.
712 // The alternative job will mark the main job complete. 803 // The alternative job will mark the main job complete.
713 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 804 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
714 805
715 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED, 806 base::RunLoop().RunUntilIdle();
716 SSLConfig());
717 807
718 // Controller should use alternative job to get load state. 808 // Controller should use alternative job to get load state.
719 job_controller_->GetLoadState(); 809 job_controller_->GetLoadState();
720 810
721 // |alternative_job| succeeds and should report status to Request. 811 // |alternative_job| succeeds and should report status to Request.
722 HttpStream* http_stream = 812 HttpStream* http_stream =
723 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); 813 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
724 job_factory_.alternative_job()->SetStream(http_stream); 814 job_factory_.alternative_job()->SetStream(http_stream);
725 815
726 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream)) 816 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
727 .WillOnce(Invoke(DeleteHttpStreamPointer)); 817 .WillOnce(Invoke(DeleteHttpStreamPointer));
728 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig()); 818 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig());
729 } 819 }
730 820
731 TEST_F(HttpStreamFactoryImplJobControllerTest, DoNotResumeMainJobBeforeWait) { 821 TEST_F(HttpStreamFactoryImplJobControllerTest, ResumeMainJobWhenAltJobStalls) {
732 // Use failing ProxyResolverFactory which is unable to create ProxyResolver 822 // One TCP connect.
733 // to stall the alternative job and report to controller to maybe resume the 823 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
734 // main job. 824 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
735 ProxyConfig proxy_config; 825 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
736 proxy_config.set_auto_detect(true); 826 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
737 proxy_config.set_pac_mandatory(true);
738 session_deps_.proxy_service.reset(new ProxyService(
739 base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
740 base::WrapUnique(new FailingProxyResolverFactory), nullptr));
741 827
742 HttpRequestInfo request_info; 828 HttpRequestInfo request_info;
743 request_info.method = "GET"; 829 request_info.method = "GET";
744 request_info.url = GURL("https://www.google.com"); 830 request_info.url = GURL("https://www.google.com");
745 831
746 Initialize(request_info); 832 Initialize(request_info);
747 url::SchemeHostPort server(request_info.url); 833 url::SchemeHostPort server(request_info.url);
748 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 834 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
749 SetAlternativeService(request_info, alternative_service); 835 SetAlternativeService(request_info, alternative_service);
836 /**
837 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
838 session_->quic_stream_factory(),
839 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING));
840 */
750 841
751 request_.reset( 842 request_.reset(
752 job_controller_->Start(request_info, &request_delegate_, nullptr, 843 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
753 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 844 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
754 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
755 EXPECT_TRUE(job_controller_->main_job()); 845 EXPECT_TRUE(job_controller_->main_job());
756 EXPECT_TRUE(job_controller_->alternative_job()); 846 EXPECT_TRUE(job_controller_->alternative_job());
757 847
758 // Wait until OnStreamFailedCallback is executed on the alternative job. 848 // Alt job is stalled and main job should complete successfully.
759 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(1); 849 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
850 .WillOnce(Invoke(DeleteHttpStreamPointer));
851
760 base::RunLoop().RunUntilIdle(); 852 base::RunLoop().RunUntilIdle();
761 } 853 }
762 854
763 TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) { 855 TEST_F(HttpStreamFactoryImplJobControllerTest, InvalidPortForQuic) {
764 HttpRequestInfo request_info; 856 HttpRequestInfo request_info;
765 request_info.method = "GET"; 857 request_info.method = "GET";
766 request_info.url = GURL("https://www.google.com"); 858 request_info.url = GURL("https://www.google.com");
767 859
768 // Using a restricted port 101 for QUIC should fail and the alternative job 860 // Using a restricted port 101 for QUIC should fail and the alternative job
769 // should post OnStreamFailedCall on the controller to resume the main job. 861 // should post OnStreamFailedCall on the controller to resume the main job.
770 Initialize(request_info); 862 Initialize(request_info);
771 863
772 url::SchemeHostPort server(request_info.url); 864 url::SchemeHostPort server(request_info.url);
773 AlternativeService alternative_service(kProtoQUIC, server.host(), 101); 865 AlternativeService alternative_service(kProtoQUIC, server.host(), 101);
774 SetAlternativeService(request_info, alternative_service); 866 SetAlternativeService(request_info, alternative_service);
775 867
776 request_.reset( 868 request_.reset(
777 job_controller_->Start(request_info, &request_delegate_, nullptr, 869 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
778 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 870 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
779 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
780 871
781 EXPECT_TRUE(job_factory_.main_job()->is_waiting()); 872 EXPECT_TRUE(job_factory_.main_job()->is_waiting());
782 873
783 // Wait until OnStreamFailedCallback is executed on the alternative job. 874 // Wait until OnStreamFailedCallback is executed on the alternative job.
784 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); 875 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
785 base::RunLoop().RunUntilIdle(); 876 base::RunLoop().RunUntilIdle();
786 } 877 }
787 878
788 TEST_F(HttpStreamFactoryImplJobControllerTest,
789 NoAvailableSpdySessionToResumeMainJob) {
790 // Test the alternative job is not resumed when the alternative job is
791 // IO_PENDING for proxy resolution. Once all the proxy resolution succeeds,
792 // the latter part of this test tests controller resumes the main job
793 // when there's no SPDY session for the alternative job.
794 ProxyConfig proxy_config;
795 proxy_config.set_auto_detect(true);
796 // Use asynchronous proxy resolver.
797 MockAsyncProxyResolverFactory* proxy_resolver_factory =
798 new MockAsyncProxyResolverFactory(false);
799 session_deps_.proxy_service.reset(
800 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
801 base::WrapUnique(proxy_resolver_factory), nullptr));
802
803 HangingResolver* host_resolver = new HangingResolver();
804 session_deps_.host_resolver.reset(host_resolver);
805 session_deps_.host_resolver->set_synchronous_mode(false);
806
807 HttpRequestInfo request_info;
808 request_info.method = "GET";
809 request_info.url = GURL("https://www.google.com");
810
811 Initialize(request_info);
812
813 // Set a SPDY alternative service for the server.
814 url::SchemeHostPort server(request_info.url);
815 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
816 SetAlternativeService(request_info, alternative_service);
817 // Hack to use different URL for the main job to help differentiate the proxy
818 // requests.
819 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com"));
820
821 request_.reset(
822 job_controller_->Start(request_info, &request_delegate_, nullptr,
823 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM,
824 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
825 // Both jobs should be created but stalled as proxy resolution not completed.
826 EXPECT_TRUE(job_controller_->main_job());
827 EXPECT_TRUE(job_controller_->alternative_job());
828
829 MockAsyncProxyResolver resolver;
830 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
831 net::OK, &resolver);
832
833 // Resolve proxy for the main job which then proceed to wait for the
834 // alternative job which is IO_PENDING.
835 int main_job_request_id =
836 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1;
837
838 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy(
839 "result1:80");
840 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK);
841 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
842
843 // Resolve proxy for the alternative job to proceed to create a connection.
844 // Use hanging HostResolver to fail creation of a SPDY session for the
845 // alternative job. The alternative job will be IO_PENDING thus should resume
846 // the main job.
847 resolver.pending_jobs()[0]->CompleteNow(net::OK);
848 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
849 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
850
851 base::RunLoop().RunUntilIdle();
852 }
853
854 TEST_F(HttpStreamFactoryImplJobControllerTest,
855 NoAvailableQuicSessionToResumeMainJob) {
856 // Use failing HostResolver which is unable to resolve the host name for QUIC.
857 // No QUIC session is created and thus should resume the main job.
858 FailingHostResolver* host_resolver = new FailingHostResolver();
859 session_deps_.host_resolver.reset(host_resolver);
860
861 ProxyConfig proxy_config;
862 proxy_config.set_auto_detect(true);
863 // Use asynchronous proxy resolver.
864 MockAsyncProxyResolverFactory* proxy_resolver_factory =
865 new MockAsyncProxyResolverFactory(false);
866 session_deps_.proxy_service.reset(
867 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config),
868 base::WrapUnique(proxy_resolver_factory), nullptr));
869
870 HttpRequestInfo request_info;
871 request_info.method = "GET";
872 request_info.url = GURL("https://www.google.com");
873
874 Initialize(request_info);
875 url::SchemeHostPort server(request_info.url);
876 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
877 SetAlternativeService(request_info, alternative_service);
878 // Hack to use different URL for the main job to help differentiate the proxy
879 // requests.
880 job_factory_.UseDifferentURLForMainJob(GURL("http://www.google.com"));
881
882 request_.reset(
883 job_controller_->Start(request_info, &request_delegate_, nullptr,
884 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM,
885 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
886 EXPECT_TRUE(job_controller_->main_job());
887 EXPECT_TRUE(job_controller_->alternative_job());
888
889 MockAsyncProxyResolver resolver;
890 proxy_resolver_factory->pending_requests()[0]->CompleteNowWithForwarder(
891 net::OK, &resolver);
892
893 // Resolve proxy for the main job which then proceed to wait for the
894 // alternative job which is IO_PENDING.
895 int main_job_request_id =
896 resolver.pending_jobs()[0]->url().SchemeIs("http") ? 0 : 1;
897
898 resolver.pending_jobs()[main_job_request_id]->results()->UseNamedProxy(
899 "result1:80");
900 resolver.pending_jobs()[main_job_request_id]->CompleteNow(net::OK);
901 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
902
903 // Resolve proxy for the alternative job to proceed to create a connection.
904 // Use failing HostResolver to fail creation of a QUIC session for the
905 // alternative job. The alternative job will thus resume the main job.
906 resolver.pending_jobs()[0]->results()->UseNamedProxy("result1:80");
907 resolver.pending_jobs()[0]->CompleteNow(net::OK);
908
909 // Wait until OnStreamFailedCallback is executed on the alternative job.
910 // Request shouldn't be notified as the main job is still pending status.
911 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
912 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
913
914 base::RunLoop().RunUntilIdle();
915 }
916
917 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { 879 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) {
918 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; 880 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
919 auto failing_resolver = base::MakeUnique<MockHostResolver>(); 881 auto failing_resolver = base::MakeUnique<MockHostResolver>();
920 failing_resolver->set_ondemand_mode(true); 882 failing_resolver->set_ondemand_mode(true);
921 failing_resolver->rules()->AddSimulatedFailure("*google.com"); 883 failing_resolver->rules()->AddSimulatedFailure("*google.com");
922 session_deps_.host_resolver = std::move(failing_resolver); 884 session_deps_.host_resolver = std::move(failing_resolver);
923 885
924 HttpRequestInfo request_info; 886 HttpRequestInfo request_info;
925 request_info.method = "GET"; 887 request_info.method = "GET";
926 request_info.url = GURL("https://www.google.com"); 888 request_info.url = GURL("https://www.google.com");
927 889
928 Initialize(request_info); 890 Initialize(request_info);
929 891
930 // Enable delayed TCP and set time delay for waiting job. 892 // Enable delayed TCP and set time delay for waiting job.
931 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); 893 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
932 quic_stream_factory->set_require_confirmation(false); 894 quic_stream_factory->set_require_confirmation(false);
933 ServerNetworkStats stats1; 895 ServerNetworkStats stats1;
934 stats1.srtt = base::TimeDelta::FromMicroseconds(10); 896 stats1.srtt = base::TimeDelta::FromMicroseconds(10);
935 session_->http_server_properties()->SetServerNetworkStats( 897 session_->http_server_properties()->SetServerNetworkStats(
936 url::SchemeHostPort(GURL("https://www.google.com")), stats1); 898 url::SchemeHostPort(GURL("https://www.google.com")), stats1);
937 899
938 // Set a SPDY alternative service for the server.
939 url::SchemeHostPort server(request_info.url); 900 url::SchemeHostPort server(request_info.url);
940 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 901 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
941 SetAlternativeService(request_info, alternative_service); 902 SetAlternativeService(request_info, alternative_service);
942 903
943 request_.reset( 904 request_.reset(
944 job_controller_->Start(request_info, &request_delegate_, nullptr, 905 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
945 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 906 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
946 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
947 EXPECT_TRUE(job_controller_->main_job()); 907 EXPECT_TRUE(job_controller_->main_job());
948 EXPECT_TRUE(job_controller_->alternative_job()); 908 EXPECT_TRUE(job_controller_->alternative_job());
949 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 909 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
950 910
951 // The alternative job stalls as host resolution hangs when creating the QUIC 911 // The alternative job stalls as host resolution hangs when creating the QUIC
952 // request and controller should resume the main job after delay. 912 // request and controller should resume the main job after delay.
953 EXPECT_TRUE(test_task_runner->HasPendingTask()); 913 EXPECT_TRUE(test_task_runner->HasPendingTask());
954 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 914 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
955 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); 915 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
956 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); 916 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 stats1.srtt = base::TimeDelta::FromSeconds(100); 962 stats1.srtt = base::TimeDelta::FromSeconds(100);
1003 session_->http_server_properties()->SetServerNetworkStats( 963 session_->http_server_properties()->SetServerNetworkStats(
1004 url::SchemeHostPort(GURL("https://www.google.com")), stats1); 964 url::SchemeHostPort(GURL("https://www.google.com")), stats1);
1005 965
1006 // Set a SPDY alternative service for the server. 966 // Set a SPDY alternative service for the server.
1007 url::SchemeHostPort server(request_info.url); 967 url::SchemeHostPort server(request_info.url);
1008 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 968 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
1009 SetAlternativeService(request_info, alternative_service); 969 SetAlternativeService(request_info, alternative_service);
1010 970
1011 request_.reset( 971 request_.reset(
1012 job_controller_->Start(request_info, &request_delegate_, nullptr, 972 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1013 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 973 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
1014 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1015 EXPECT_TRUE(job_controller_->main_job()); 974 EXPECT_TRUE(job_controller_->main_job());
1016 EXPECT_TRUE(job_controller_->alternative_job()); 975 EXPECT_TRUE(job_controller_->alternative_job());
1017 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 976 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
1018 977
1019 // The alternative job stalls as host resolution hangs when creating the QUIC 978 // The alternative job stalls as host resolution hangs when creating the QUIC
1020 // request and controller should resume the main job after delay. 979 // request and controller should resume the main job after delay.
1021 EXPECT_TRUE(test_task_runner->HasPendingTask()); 980 EXPECT_TRUE(test_task_runner->HasPendingTask());
1022 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 981 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1023 982
1024 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); 983 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 1021
1063 // Set a SPDY alternative service for the server. 1022 // Set a SPDY alternative service for the server.
1064 url::SchemeHostPort server(request_info.url); 1023 url::SchemeHostPort server(request_info.url);
1065 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 1024 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
1066 SetAlternativeService(request_info, alternative_service); 1025 SetAlternativeService(request_info, alternative_service);
1067 1026
1068 // The alternative job stalls as host resolution hangs when creating the QUIC 1027 // The alternative job stalls as host resolution hangs when creating the QUIC
1069 // request and controller should resume the main job with delay. 1028 // request and controller should resume the main job with delay.
1070 // OnStreamFailed should resume the main job immediately. 1029 // OnStreamFailed should resume the main job immediately.
1071 request_.reset( 1030 request_.reset(
1072 job_controller_->Start(request_info, &request_delegate_, nullptr, 1031 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1073 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1032 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
1074 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1075 EXPECT_TRUE(job_controller_->main_job()); 1033 EXPECT_TRUE(job_controller_->main_job());
1076 EXPECT_TRUE(job_controller_->alternative_job()); 1034 EXPECT_TRUE(job_controller_->alternative_job());
1077 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 1035 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
1078 1036
1079 EXPECT_TRUE(test_task_runner->HasPendingTask()); 1037 EXPECT_TRUE(test_task_runner->HasPendingTask());
1080 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 1038 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1081 1039
1082 // |alternative_job| fails but should not report status to Request. 1040 // |alternative_job| fails but should not report status to Request.
1083 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 1041 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
1084 // Now unblock Resolver to fail the alternate job. 1042 // Now unblock Resolver to fail the alternate job.
(...skipping 23 matching lines...) Expand all
1108 HangingResolver* resolver = new HangingResolver(); 1066 HangingResolver* resolver = new HangingResolver();
1109 session_deps_.host_resolver.reset(resolver); 1067 session_deps_.host_resolver.reset(resolver);
1110 1068
1111 HttpRequestInfo request_info; 1069 HttpRequestInfo request_info;
1112 request_info.method = "GET"; 1070 request_info.method = "GET";
1113 request_info.url = GURL("https://mail.example.org/"); 1071 request_info.url = GURL("https://mail.example.org/");
1114 Initialize(request_info); 1072 Initialize(request_info);
1115 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); 1073 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic());
1116 1074
1117 request_.reset( 1075 request_.reset(
1118 job_controller_->Start(request_info, &request_delegate_, nullptr, 1076 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1119 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1077 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
1120 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1121 EXPECT_TRUE(job_controller_->main_job()); 1078 EXPECT_TRUE(job_controller_->main_job());
1122 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); 1079 EXPECT_FALSE(job_controller_->main_job()->is_waiting());
1123 EXPECT_FALSE(job_controller_->alternative_job()); 1080 EXPECT_FALSE(job_controller_->alternative_job());
1124 1081
1125 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); 1082 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
1126 base::RunLoop().RunUntilIdle(); 1083 base::RunLoop().RunUntilIdle();
1127 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); 1084 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations());
1128 } 1085 }
1129 1086
1130 // Verifies that the alternative proxy server job is not created if the main job 1087 // Verifies that the alternative proxy server job is not created if the main job
1131 // does not fetch the resource through a proxy. 1088 // does not fetch the resource through a proxy.
1132 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) { 1089 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpURLWithNoProxy) {
1133 // Using hanging resolver will cause the alternative job to hang indefinitely. 1090 // Using hanging resolver will cause the alternative job to hang indefinitely.
1134 HangingResolver* resolver = new HangingResolver(); 1091 HangingResolver* resolver = new HangingResolver();
1135 session_deps_.host_resolver.reset(resolver); 1092 session_deps_.host_resolver.reset(resolver);
1136 1093
1137 HttpRequestInfo request_info; 1094 HttpRequestInfo request_info;
1138 request_info.method = "GET"; 1095 request_info.method = "GET";
1139 request_info.url = GURL("http://mail.example.org/"); 1096 request_info.url = GURL("http://mail.example.org/");
1140 1097
1141 Initialize(request_info); 1098 Initialize(request_info);
1142 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); 1099 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic());
1143 1100
1144 request_.reset( 1101 request_.reset(
1145 job_controller_->Start(request_info, &request_delegate_, nullptr, 1102 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1146 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1103 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
1147 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1148 EXPECT_TRUE(job_controller_->main_job()); 1104 EXPECT_TRUE(job_controller_->main_job());
1149 EXPECT_FALSE(job_controller_->main_job()->is_waiting()); 1105 EXPECT_FALSE(job_controller_->main_job()->is_waiting());
1150 EXPECT_FALSE(job_controller_->alternative_job()); 1106 EXPECT_FALSE(job_controller_->alternative_job());
1151 1107
1152 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); 1108 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
1153 base::RunLoop().RunUntilIdle(); 1109 base::RunLoop().RunUntilIdle();
1154 1110
1155 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations()); 1111 EXPECT_EQ(0, test_proxy_delegate()->get_alternative_proxy_invocations());
1156 } 1112 }
1157 1113
1158 // Verifies that the main job is resumed properly after a delay when the 1114 // Verifies that the main job is resumed properly after a delay when the
1159 // alternative proxy server job hangs. 1115 // alternative proxy server job hangs.
1160 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) { 1116 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPAlternativeProxy) {
1161 // Overrides the main thread's message loop with a mock tick clock so that we 1117 // Overrides the main thread's message loop with a mock tick clock so that we
1162 // could verify the main job is resumed with appropriate delay. 1118 // could verify the main job is resumed with appropriate delay.
1163 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; 1119 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
1164
1165 auto failing_resolver = base::MakeUnique<MockHostResolver>();
1166 failing_resolver->set_ondemand_mode(true);
1167 failing_resolver->rules()->AddSimulatedFailure("*myproxy.org");
1168 session_deps_.host_resolver = std::move(failing_resolver);
1169
1170 UseAlternativeProxy(); 1120 UseAlternativeProxy();
1171 1121
1172 HttpRequestInfo request_info; 1122 HttpRequestInfo request_info;
1173 request_info.method = "GET"; 1123 request_info.method = "GET";
1174 request_info.url = GURL("http://mail.example.org/"); 1124 request_info.url = GURL("http://mail.example.org/");
1175 Initialize(request_info); 1125 Initialize(request_info);
1176 1126
1127 /**
1128 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
1129 session_->quic_stream_factory(),
1130 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_IO_PENDING));
1131 */
1132
1177 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); 1133 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic());
1178 1134
1179 // Enable delayed TCP and set time delay for waiting job. 1135 // Enable delayed TCP and set time delay for waiting job.
1180 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); 1136 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
1181 quic_stream_factory->set_require_confirmation(false); 1137 quic_stream_factory->set_require_confirmation(false);
1182 ServerNetworkStats stats1; 1138 ServerNetworkStats stats1;
1183 stats1.srtt = base::TimeDelta::FromMicroseconds(10); 1139 stats1.srtt = base::TimeDelta::FromMicroseconds(10);
1184 session_->http_server_properties()->SetServerNetworkStats( 1140 session_->http_server_properties()->SetServerNetworkStats(
1185 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); 1141 url::SchemeHostPort(GURL("https://myproxy.org")), stats1);
1186 1142
1187 request_.reset( 1143 request_.reset(
1188 job_controller_->Start(request_info, &request_delegate_, nullptr, 1144 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1189 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1145 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
1190 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1191 EXPECT_TRUE(job_controller_->main_job()); 1146 EXPECT_TRUE(job_controller_->main_job());
1192 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 1147 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
1193 EXPECT_TRUE(job_controller_->alternative_job()); 1148 EXPECT_TRUE(job_controller_->alternative_job());
1194 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_)); 1149 EXPECT_TRUE(JobControllerPeer::main_job_is_blocked(job_controller_));
1195 1150
1196 // Alternative proxy server job will start in the next message loop. 1151 // Move forward the delay and verify the main job is resumed.
1197 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 1152 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
1198
1199 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
1200 // Run tasks with no remaining delay, this will start the alternative proxy 1153 // Run tasks with no remaining delay, this will start the alternative proxy
1201 // server job. The alternative proxy server job stalls when connecting to the 1154 // server job. The alternative proxy server job stalls when connecting to the
1202 // alternative proxy server, and should schedule a task to resume the main job 1155 // alternative proxy server, and should schedule a task to resume the main job
1203 // after delay. That task will be queued. 1156 // after delay. That task will be queued.
1204 test_task_runner->RunUntilIdle();
1205 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 1157 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1206
1207 // Move forward the delay and verify the main job is resumed.
1208 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
1209 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); 1158 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15));
1210 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); 1159 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
1211 1160
1212 test_task_runner->RunUntilIdle(); 1161 test_task_runner->RunUntilIdle();
1213 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid()); 1162 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid());
1214 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); 1163 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations());
1215 EXPECT_FALSE(test_task_runner->HasPendingTask()); 1164 EXPECT_FALSE(test_task_runner->HasPendingTask());
1216 1165
1217 // Now unblock Resolver so that alternate job (and QuicStreamFactory::Job) can 1166 // Resume() function is mocked, so we will still have main job around.
1218 // be cleaned up. 1167 EXPECT_TRUE(job_controller_->main_job());
1219 session_deps_.host_resolver->ResolveAllPending(); 1168 EXPECT_TRUE(job_controller_->alternative_job());
1220 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1221 test_task_runner->FastForwardUntilNoTasksRemain();
1222 EXPECT_FALSE(job_controller_->alternative_job());
1223 } 1169 }
1224 1170
1225 // Verifies that the alternative proxy server job fails immediately, and the 1171 // Verifies that if the alternative proxy server job fails immediately, the
1226 // main job is not blocked. 1172 // main job is not blocked.
1227 TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) { 1173 TEST_F(HttpStreamFactoryImplJobControllerTest, FailAlternativeProxy) {
1228 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; 1174 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
1229 // Using failing resolver will cause the alternative job to fail.
1230 FailingHostResolver* resolver = new FailingHostResolver();
1231 session_deps_.host_resolver.reset(resolver);
1232
1233 UseAlternativeProxy(); 1175 UseAlternativeProxy();
1234 1176
1235 HttpRequestInfo request_info; 1177 HttpRequestInfo request_info;
1236 request_info.method = "GET"; 1178 request_info.method = "GET";
1237 request_info.url = GURL("http://mail.example.org/"); 1179 request_info.url = GURL("http://mail.example.org/");
1238 Initialize(request_info); 1180 Initialize(request_info);
1239 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); 1181 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic());
1240 1182
1241 // Enable delayed TCP and set time delay for waiting job. 1183 // Enable delayed TCP and set time delay for waiting job.
1242 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); 1184 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
1243 quic_stream_factory->set_require_confirmation(false); 1185 quic_stream_factory->set_require_confirmation(false);
1244 ServerNetworkStats stats1; 1186 ServerNetworkStats stats1;
1245 stats1.srtt = base::TimeDelta::FromMicroseconds(300 * 1000); 1187 stats1.srtt = base::TimeDelta::FromMicroseconds(300 * 1000);
1246 session_->http_server_properties()->SetServerNetworkStats( 1188 session_->http_server_properties()->SetServerNetworkStats(
1247 url::SchemeHostPort(GURL("https://myproxy.org")), stats1); 1189 url::SchemeHostPort(GURL("https://myproxy.org")), stats1);
1190 /**
1191 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
1192 session_->quic_stream_factory(),
1193 base::MakeUnique<MockQuicStreamRequestFactory>(ERR_FAILED));
1194 */
1248 1195
1249 request_.reset( 1196 request_.reset(
1250 job_controller_->Start(request_info, &request_delegate_, nullptr, 1197 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1251 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1198 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
1252 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1253 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 1199 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
1254 EXPECT_TRUE(job_controller_->alternative_job()); 1200 EXPECT_TRUE(job_controller_->alternative_job());
1255 1201
1256 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); 1202 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1257 1203
1258 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)).Times(0); 1204 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _)).Times(0);
1259 1205
1260 // Since the alternative proxy server job is started in the next message loop, 1206 // Since the alternative proxy server job is started in the next message loop,
1261 // the main job would remain blocked until the alternative proxy starts, and 1207 // the main job would remain blocked until the alternative proxy starts, and
1262 // fails. 1208 // fails.
1263 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); 1209 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
1264 1210
1265 // Run tasks with no remaining delay. 1211 // Run tasks with no remaining delay.
1266 test_task_runner->RunUntilIdle(); 1212 test_task_runner->RunUntilIdle();
1267 1213
1268 EXPECT_FALSE(job_controller_->alternative_job()); 1214 EXPECT_FALSE(job_controller_->alternative_job());
1269 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 1215 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
1270 // Since the main job did not complete successfully, the alternative proxy 1216 // The alternative proxy server should be marked as bad.
1271 // server should not be marked as bad. 1217 EXPECT_FALSE(test_proxy_delegate()->alternative_proxy_server().is_valid());
1272 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_valid());
1273 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations()); 1218 EXPECT_EQ(1, test_proxy_delegate()->get_alternative_proxy_invocations());
1274 EXPECT_FALSE(test_task_runner->HasPendingTask()); 1219 EXPECT_FALSE(test_task_runner->HasPendingTask());
1275 } 1220 }
1276 1221
1277 TEST_F(HttpStreamFactoryImplJobControllerTest, 1222 TEST_F(HttpStreamFactoryImplJobControllerTest,
1278 AlternativeProxyServerJobFailsAfterMainJobSucceeds) { 1223 AlternativeProxyServerJobFailsAfterMainJobSucceeds) {
1279 base::HistogramTester histogram_tester; 1224 base::HistogramTester histogram_tester;
1280 1225
1281 UseAlternativeProxy(); 1226 UseAlternativeProxy();
1282 1227
1283 HttpRequestInfo request_info; 1228 HttpRequestInfo request_info;
1284 request_info.method = "GET"; 1229 request_info.method = "GET";
1285 request_info.url = GURL("http://www.google.com"); 1230 request_info.url = GURL("http://www.google.com");
1286 Initialize(request_info); 1231 Initialize(request_info);
1287 1232
1288 url::SchemeHostPort server(request_info.url); 1233 url::SchemeHostPort server(request_info.url);
1289 1234
1290 request_.reset( 1235 request_.reset(
1291 job_controller_->Start(request_info, &request_delegate_, nullptr, 1236 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1292 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1237 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
1293 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1294 EXPECT_TRUE(job_controller_->main_job()); 1238 EXPECT_TRUE(job_controller_->main_job());
1295 EXPECT_TRUE(job_controller_->alternative_job()); 1239 EXPECT_TRUE(job_controller_->alternative_job());
1296 1240
1297 // Main job succeeds, starts serving Request and it should report status 1241 // Main job succeeds, starts serving Request and it should report status
1298 // to Request. The alternative job will mark the main job complete and gets 1242 // to Request. The alternative job will mark the main job complete and gets
1299 // orphaned. 1243 // orphaned.
1300 HttpStream* http_stream = 1244 HttpStream* http_stream =
1301 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false); 1245 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
1302 job_factory_.main_job()->SetStream(http_stream); 1246 job_factory_.main_job()->SetStream(http_stream);
1303 1247
(...skipping 12 matching lines...) Expand all
1316 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 1260 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
1317 1261
1318 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage", 1262 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage",
1319 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */, 1263 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */,
1320 1); 1264 1);
1321 } 1265 }
1322 1266
1323 // When preconnect to a H2 supported server, only 1 connection is opened. 1267 // When preconnect to a H2 supported server, only 1 connection is opened.
1324 TEST_F(HttpStreamFactoryImplJobControllerTest, 1268 TEST_F(HttpStreamFactoryImplJobControllerTest,
1325 PreconnectMultipleStreamsToH2Server) { 1269 PreconnectMultipleStreamsToH2Server) {
1326 MockRead reads[] = {MockRead(ASYNC, OK)}; 1270 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
1327 SequencedSocketData data(reads, arraysize(reads), nullptr, 0); 1271 tcp_data_->set_connect_data(MockConnect(ASYNC, OK));
1328 session_deps_.socket_factory->AddSocketDataProvider(&data);
1329
1330 SetPreconnect(); 1272 SetPreconnect();
1331 1273
1332 HttpRequestInfo request_info; 1274 HttpRequestInfo request_info;
1333 request_info.method = "GET"; 1275 request_info.method = "GET";
1334 request_info.url = GURL("http://www.example.com"); 1276 request_info.url = GURL("http://www.example.com");
1335 Initialize(request_info); 1277 Initialize(request_info);
1336 1278
1337 url::SchemeHostPort server(request_info.url); 1279 url::SchemeHostPort server(request_info.url);
1338 1280
1339 // Sets server support Http/2. 1281 // Sets server support Http/2.
1340 session_->http_server_properties()->SetSupportsSpdy(server, true); 1282 session_->http_server_properties()->SetSupportsSpdy(server, true);
1341 1283
1342 job_controller_->Preconnect(/*num_streams=*/5, request_info, SSLConfig(), 1284 job_controller_->Preconnect(/*num_streams=*/5);
1343 SSLConfig());
1344 // Only one job is started. 1285 // Only one job is started.
1345 EXPECT_TRUE(job_controller_->main_job()); 1286 EXPECT_TRUE(job_controller_->main_job());
1346 EXPECT_FALSE(job_controller_->alternative_job()); 1287 EXPECT_FALSE(job_controller_->alternative_job());
1347 // There is only 1 connect even though multiple streams were requested. 1288 // There is only 1 connect even though multiple streams were requested.
1348 EXPECT_EQ(1, HttpStreamFactoryImplJobPeer::GetNumStreams( 1289 EXPECT_EQ(1, HttpStreamFactoryImplJobPeer::GetNumStreams(
1349 job_controller_->main_job())); 1290 job_controller_->main_job()));
1350 1291
1351 base::RunLoop().RunUntilIdle(); 1292 base::RunLoop().RunUntilIdle();
1352 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 1293 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
1353 } 1294 }
1354 1295
1355 class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry 1296 class HttpStreamFactoryImplJobControllerMisdirectedRequestRetry
1356 : public HttpStreamFactoryImplJobControllerTest, 1297 : public HttpStreamFactoryImplJobControllerTest,
1357 public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {}; 1298 public ::testing::WithParamInterface<::testing::tuple<bool, bool>> {};
1358 1299
1359 INSTANTIATE_TEST_CASE_P( 1300 INSTANTIATE_TEST_CASE_P(
1360 /* no prefix */, 1301 /* no prefix */,
1361 HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, 1302 HttpStreamFactoryImplJobControllerMisdirectedRequestRetry,
1362 ::testing::Combine(::testing::Bool(), ::testing::Bool())); 1303 ::testing::Combine(::testing::Bool(), ::testing::Bool()));
1363 1304
1364 TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry, 1305 TEST_P(HttpStreamFactoryImplJobControllerMisdirectedRequestRetry,
1365 DisableIPBasedPoolingAndAlternativeServices) { 1306 DisableIPBasedPoolingAndAlternativeServices) {
1366 const bool enable_ip_based_pooling = ::testing::get<0>(GetParam()); 1307 const bool enable_ip_based_pooling = ::testing::get<0>(GetParam());
1367 const bool enable_alternative_services = ::testing::get<1>(GetParam()); 1308 const bool enable_alternative_services = ::testing::get<1>(GetParam());
1368 1309
1369 ProxyConfig proxy_config; 1310 tcp_data_ = base::MakeUnique<SequencedSocketData>(nullptr, 0, nullptr, 0);
1370 proxy_config.set_auto_detect(true); 1311 tcp_data_->set_connect_data(MockConnect(SYNCHRONOUS, OK));
1371 // Use asynchronous proxy resolver. 1312 auto ssl_data = base::MakeUnique<SSLSocketDataProvider>(ASYNC, OK);
1372 MockAsyncProxyResolverFactory* proxy_resolver_factory = 1313 session_deps_.socket_factory->AddSSLSocketDataProvider(ssl_data.get());
1373 new MockAsyncProxyResolverFactory(false); 1314 test::MockQuicData mock_quic_data;
1374 session_deps_.proxy_service.reset( 1315 if (enable_alternative_services) {
1375 new ProxyService(base::MakeUnique<ProxyConfigServiceFixed>(proxy_config), 1316 mock_quic_data.AddWrite(
1376 base::WrapUnique(proxy_resolver_factory), nullptr)); 1317 client_maker_.MakeInitialSettingsPacket(1, nullptr));
xunjieli 2017/04/27 18:15:54 Ryan: so I tried your suggestion. However, I think
Ryan Hamilton 2017/04/27 21:52:47 The connection ID is generated "randomly" each tim
1318 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1319 mock_quic_data.AddRead(ASYNC, OK);
1320 mock_quic_data.AddSocketDataToFactory(session_deps_.socket_factory.get());
1321 }
1322
1377 HttpRequestInfo request_info; 1323 HttpRequestInfo request_info;
1378 request_info.method = "GET"; 1324 request_info.method = "GET";
1379 request_info.url = GURL("https://www.google.com"); 1325 request_info.url = GURL("https://www.google.com");
1380 1326
1381 if (!enable_ip_based_pooling) 1327 if (!enable_ip_based_pooling)
1382 DisableIPBasedPooling(); 1328 DisableIPBasedPooling();
1383 if (!enable_alternative_services) 1329 if (!enable_alternative_services) {
1384 DisableAlternativeServices(); 1330 DisableAlternativeServices();
1331 }
1385 1332
1386 Initialize(request_info); 1333 Initialize(request_info);
1387 1334
1388 url::SchemeHostPort server(request_info.url); 1335 url::SchemeHostPort server(request_info.url);
1389 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 1336 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
1390 SetAlternativeService(request_info, alternative_service); 1337 SetAlternativeService(request_info, alternative_service);
1338 /**
1339 if (enable_alternative_services) {
1340 // Mock out Quic request
1341 test::QuicStreamFactoryPeer::SetStreamRequestFactory(
1342 session_->quic_stream_factory(),
1343 base::MakeUnique<MockQuicStreamRequestFactory>(OK));
1344 }
1345 */
1391 1346
1392 request_.reset( 1347 request_.reset(
1393 job_controller_->Start(request_info, &request_delegate_, nullptr, 1348 job_controller_->Start(&request_delegate_, nullptr, NetLogWithSource(),
1394 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1349 HttpStreamRequest::HTTP_STREAM, DEFAULT_PRIORITY));
1395 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
1396 EXPECT_TRUE(job_controller_->main_job()); 1350 EXPECT_TRUE(job_controller_->main_job());
1397 if (enable_alternative_services) { 1351 if (enable_alternative_services) {
1398 EXPECT_TRUE(job_controller_->alternative_job()); 1352 EXPECT_TRUE(job_controller_->alternative_job());
1399 } else { 1353 } else {
1400 EXPECT_FALSE(job_controller_->alternative_job()); 1354 EXPECT_FALSE(job_controller_->alternative_job());
1401 } 1355 }
1402 1356
1403 // |main_job| succeeds and should report status to Request. 1357 // |main_job| succeeds and should report status to Request.
1404 HttpStream* http_stream = 1358 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, _))
1405 new HttpBasicStream(base::MakeUnique<ClientSocketHandle>(), false, false);
1406 job_factory_.main_job()->SetStream(http_stream);
1407
1408 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
1409 .WillOnce(Invoke(DeleteHttpStreamPointer)); 1359 .WillOnce(Invoke(DeleteHttpStreamPointer));
1410 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig()); 1360 base::RunLoop().RunUntilIdle();
1411 } 1361 }
1412 1362
1413 class HttpStreamFactoryImplJobControllerPreconnectTest 1363 class HttpStreamFactoryImplJobControllerPreconnectTest
1414 : public HttpStreamFactoryImplJobControllerTest, 1364 : public HttpStreamFactoryImplJobControllerTest,
1415 public ::testing::WithParamInterface<bool> { 1365 public ::testing::WithParamInterface<bool> {
1416 protected: 1366 protected:
1417 void SetUp() override { 1367 void SetUp() override {
1418 if (GetParam()) { 1368 if (GetParam()) {
1419 scoped_feature_list_.InitFromCommandLine("LimitEarlyPreconnects", 1369 scoped_feature_list_.InitFromCommandLine("LimitEarlyPreconnects",
1420 std::string()); 1370 std::string());
1421 } 1371 }
1422 } 1372 }
1423 1373
1424 void Initialize() { 1374 void Initialize() {
1425 session_deps_.http_server_properties = 1375 session_deps_.http_server_properties =
1426 base::MakeUnique<MockHttpServerProperties>(); 1376 base::MakeUnique<MockHttpServerProperties>();
1427 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); 1377 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
1428 factory_ = 1378 factory_ =
1429 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory()); 1379 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory());
1430 request_info_.method = "GET"; 1380 request_info_.method = "GET";
1431 request_info_.url = GURL("https://www.example.com"); 1381 request_info_.url = GURL("https://www.example.com");
1432 job_controller_ = new HttpStreamFactoryImpl::JobController( 1382 job_controller_ = new HttpStreamFactoryImpl::JobController(
1433 factory_, &request_delegate_, session_.get(), &job_factory_, 1383 factory_, &request_delegate_, session_.get(), &job_factory_,
1434 request_info_, /* is_preconnect = */ true, 1384 request_info_, /* is_preconnect = */ true,
1435 /* enable_ip_based_pooling = */ true, 1385 /* enable_ip_based_pooling = */ true,
1436 /* enable_alternative_services = */ true); 1386 /* enable_alternative_services = */ true, SSLConfig(), SSLConfig());
1437 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_); 1387 HttpStreamFactoryImplPeer::AddJobController(factory_, job_controller_);
1438 } 1388 }
1439 1389
1440 protected: 1390 protected:
1441 void Preconnect(int num_streams) { 1391 void Preconnect(int num_streams) {
1442 job_controller_->Preconnect(num_streams, request_info_, SSLConfig(), 1392 job_controller_->Preconnect(num_streams);
1443 SSLConfig());
1444 // Only one job is started. 1393 // Only one job is started.
1445 EXPECT_TRUE(job_controller_->main_job()); 1394 EXPECT_TRUE(job_controller_->main_job());
1446 EXPECT_FALSE(job_controller_->alternative_job()); 1395 EXPECT_FALSE(job_controller_->alternative_job());
1447 } 1396 }
1448 1397
1449 private: 1398 private:
1450 base::test::ScopedFeatureList scoped_feature_list_; 1399 base::test::ScopedFeatureList scoped_feature_list_;
1451 HttpRequestInfo request_info_; 1400 HttpRequestInfo request_info_;
1452 }; 1401 };
1453 1402
(...skipping 23 matching lines...) Expand all
1477 Preconnect(kNumPreconects); 1426 Preconnect(kNumPreconects);
1478 // If experiment is enabled, only 1 stream is requested. 1427 // If experiment is enabled, only 1 stream is requested.
1479 EXPECT_EQ( 1428 EXPECT_EQ(
1480 (int)actual_num_connects, 1429 (int)actual_num_connects,
1481 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); 1430 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job()));
1482 base::RunLoop().RunUntilIdle(); 1431 base::RunLoop().RunUntilIdle();
1483 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 1432 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
1484 } 1433 }
1485 1434
1486 } // namespace net 1435 } // 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