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

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

Issue 1941083002: JobController 1: Adding a new class HttpStreamFactoryImpl::JobController (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: add JobFactory interface in JobController, remove JobControllerPeer Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "net/http/http_stream_factory_impl_job_controller.h"
6
7 #include <memory>
8
9 #include "net/http/http_basic_stream.h"
10 #include "net/http/http_stream_factory_impl_job.h"
11 #include "net/http/http_stream_factory_impl_request.h"
12 #include "net/http/http_stream_factory_test_util.h"
13 #include "net/proxy/proxy_info.h"
14 #include "net/proxy/proxy_service.h"
15 #include "net/spdy/spdy_test_util_common.h"
16 #include "net/ssl/ssl_failure_state.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 using ::testing::_;
20 using ::testing::Invoke;
21
22 namespace net {
23
24 void DeleteHttpStreamPointer(const SSLConfig& used_ssl_config,
25 const ProxyInfo& used_proxy_info,
26 HttpStream* stream) {
27 delete stream;
28 }
29
30 class HttpStreamFactoryImplJobControllerTest
31 : public ::testing::Test,
32 public ::testing::WithParamInterface<NextProto> {
33 public:
34 HttpStreamFactoryImplJobControllerTest()
35 : session_deps_(GetParam(), ProxyService::CreateDirect()) {
36 session_deps_.enable_quic = true;
37 session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_);
38 factory_ =
39 static_cast<HttpStreamFactoryImpl*>(session_->http_stream_factory());
40 job_controller_ = new HttpStreamFactoryImpl::JobController(
41 factory_, &request_delegate_, session_.get(), &job_factory_);
42 factory_->job_controller_set_.insert(base::WrapUnique(job_controller_));
43 }
44
45 ~HttpStreamFactoryImplJobControllerTest() {}
46
47 void SetAlternativeService(const HttpRequestInfo& request_info,
48 AlternativeService alternative_service) {
49 HostPortPair host_port_pair = HostPortPair::FromURL(request_info.url);
50 GURL original_url = job_controller_->ApplyHostMappingRules(request_info.url,
51 &host_port_pair);
Ryan Hamilton 2016/06/06 17:57:31 nit: Is this line needed? I'm guessing not, becaus
Zhongyi Shi 2016/06/06 22:50:55 Removed.
52 url::SchemeHostPort server(request_info.url);
53 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
54 session_->http_server_properties()->SetAlternativeService(
55 server, alternative_service, expiration);
56 }
57
58 // Set stream to job for test purpose so that job will have stream ready for
59 // Request it's serving.
60 void SetStreamToJob(HttpStream* http_stream,
61 HttpStreamFactoryImpl::Job* job) {
62 job->SetStream(http_stream);
Ryan Hamilton 2016/06/06 17:57:31 nit: Any reason not to simply inline the call to S
Zhongyi Shi 2016/06/06 22:50:56 Done.
63 }
64
65 bool IsJobControllerDeleted() {
66 return factory_->job_controller_set_.empty();
67 }
68
69 TestJobFactory job_factory_;
70 TestHttpStreamRequestDelegate request_delegate_;
71 SpdySessionDependencies session_deps_;
72 std::unique_ptr<HttpNetworkSession> session_;
73 HttpStreamFactoryImpl* factory_;
74 HttpStreamFactoryImpl::JobController* job_controller_;
75 std::unique_ptr<HttpStreamFactoryImpl::Request> request_;
76
77 DISALLOW_COPY_AND_ASSIGN(HttpStreamFactoryImplJobControllerTest);
78 };
79
80 INSTANTIATE_TEST_CASE_P(NextProto,
81 HttpStreamFactoryImplJobControllerTest,
82 testing::Values(kProtoSPDY31, kProtoHTTP2));
83
84 TEST_P(HttpStreamFactoryImplJobControllerTest,
85 OnStreamFailedWithNoAlternativeJob) {
86 HttpRequestInfo request_info;
87 request_info.method = "GET";
88 request_info.url = GURL("http://www.google.com");
89
90 request_.reset(
91 job_controller_->Start(request_info, &request_delegate_, nullptr,
92 BoundNetLog(), HttpStreamRequest::HTTP_STREAM,
93 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
94
95 EXPECT_TRUE(job_controller_->main_job());
96
97 // There's no other alternative job. Thus when stream failed, it should
98 // notify Request of the stream failure.
99 EXPECT_CALL(request_delegate_,
100 OnStreamFailed(ERR_FAILED, _, SSL_FAILURE_NONE))
101 .Times(1);
102 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED,
103 SSLConfig(), SSL_FAILURE_NONE);
104 }
105
106 TEST_P(HttpStreamFactoryImplJobControllerTest,
107 OnStreamReadyWithNoAlternativeJob) {
108 HttpRequestInfo request_info;
109 request_info.method = "GET";
110 request_info.url = GURL("http://www.google.com");
111
112 request_.reset(
113 job_controller_->Start(request_info, &request_delegate_, nullptr,
114 BoundNetLog(), HttpStreamRequest::HTTP_STREAM,
115 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
116 EXPECT_TRUE(job_controller_->main_job());
117
118 // There's no other alternative job. Thus when stream is ready, it should
119 // notify Request.
120 HttpStream* http_stream =
121 new HttpBasicStream(new ClientSocketHandle(), false);
122
123 SetStreamToJob(http_stream, job_factory_.main_job());
124
125 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
126 .WillOnce(Invoke(DeleteHttpStreamPointer));
127 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig(),
128 ProxyInfo());
129 }
130
131 // Test we cancel Jobs correctly when the Request is explicitly canceled
132 // before any Job is bound to Request.
133 TEST_P(HttpStreamFactoryImplJobControllerTest, CancelJobsBeforeBinding) {
134 HttpRequestInfo request_info;
135 request_info.method = "GET";
136 request_info.url = GURL("https://www.google.com");
137
138 url::SchemeHostPort server(request_info.url);
139 AlternativeService alternative_service(QUIC, server.host(), 443);
140 SetAlternativeService(request_info, alternative_service);
141
142 request_.reset(
143 job_controller_->Start(request_info, &request_delegate_, nullptr,
144 BoundNetLog(), HttpStreamRequest::HTTP_STREAM,
145 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
146 EXPECT_TRUE(job_controller_->main_job());
147 EXPECT_TRUE(job_controller_->alternative_job());
148
149 // Reset the Request will cancel all the Jobs since there's no Job determined
150 // to serve Request yet and JobController will notify the factory to delete
151 // itself upon completion.
152 request_.reset();
153 EXPECT_TRUE(IsJobControllerDeleted());
154 }
155
156 TEST_P(HttpStreamFactoryImplJobControllerTest, OnStreamFailedForBothJobs) {
157 HttpRequestInfo request_info;
158 request_info.method = "GET";
159 request_info.url = GURL("https://www.google.com");
160
161 url::SchemeHostPort server(request_info.url);
162 AlternativeService alternative_service(QUIC, server.host(), 443);
163 SetAlternativeService(request_info, alternative_service);
164
165 request_.reset(
166 job_controller_->Start(request_info, &request_delegate_, nullptr,
167 BoundNetLog(), HttpStreamRequest::HTTP_STREAM,
168 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
169 EXPECT_TRUE(job_controller_->main_job());
170 EXPECT_TRUE(job_controller_->alternative_job());
171
172 // We have |main_job| with unknown status when |alternative_job| is failed
Ryan Hamilton 2016/06/06 17:57:31 nit: In the comments, instead of |main_job| and |a
Zhongyi Shi 2016/06/06 22:50:56 Done.
173 // thus should not notify Request of |alternative_job|'s failure. But should
174 // notify |main_job| to mark |alternative_job| failed.
175 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _)).Times(0);
176 EXPECT_CALL(*job_factory_.main_job(), MarkOtherJobComplete(_)).Times(1);
177 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED,
178 SSLConfig(), SSL_FAILURE_NONE);
179 EXPECT_TRUE(!job_controller_->alternative_job());
180 EXPECT_TRUE(job_controller_->main_job());
181
182 // The failure of second Job should be reported to Request as there's no more
183 // pending Job to serve the Request.
184 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _)).Times(1);
185 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED,
186 SSLConfig(), SSL_FAILURE_NONE);
Ryan Hamilton 2016/06/06 17:57:31 It would be good to use a different error code her
Zhongyi Shi 2016/06/06 22:50:56 Done.
187 }
188
189 TEST_P(HttpStreamFactoryImplJobControllerTest,
190 SecondJobFailsAfterFirstJobSucceeds) {
191 HttpRequestInfo request_info;
192 request_info.method = "GET";
193 request_info.url = GURL("https://www.google.com");
194
195 url::SchemeHostPort server(request_info.url);
196 AlternativeService alternative_service(QUIC, server.host(), 443);
197 SetAlternativeService(request_info, alternative_service);
198
199 request_.reset(
200 job_controller_->Start(request_info, &request_delegate_, nullptr,
201 BoundNetLog(), HttpStreamRequest::HTTP_STREAM,
202 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
203 EXPECT_TRUE(job_controller_->main_job());
204 EXPECT_TRUE(job_controller_->alternative_job());
205
206 // Main job succeeds, starts serving Request and it should report status
207 // to Request. The alternative job will mark the main job complete and gets
208 // orphaned.
209 HttpStream* http_stream =
210 new HttpBasicStream(new ClientSocketHandle(), false);
211 SetStreamToJob(http_stream, job_factory_.main_job());
212
213 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
214 .WillOnce(Invoke(DeleteHttpStreamPointer));
215 EXPECT_CALL(*job_factory_.alternative_job(), MarkOtherJobComplete(_))
216 .Times(1);
217 job_controller_->OnStreamReady(job_factory_.main_job(), SSLConfig(),
218 ProxyInfo());
219
220 // Reset the request as it's been successfully served.
221 request_.reset();
Ryan Hamilton 2016/06/06 17:57:31 If request_ is reset, then there's no way the cont
Zhongyi Shi 2016/06/06 22:50:56 The test will also pass if we don't reset the requ
Zhongyi Shi 2016/06/06 22:50:56 The test will also pass if we don't reset the requ
222
223 // JobController shouldn't report the status of second job as request
224 // is gone served.
225 job_controller_->OnStreamFailed(job_factory_.alternative_job(), ERR_FAILED,
226 SSLConfig(), SSL_FAILURE_NONE);
227 EXPECT_TRUE(IsJobControllerDeleted());
228 }
229
230 TEST_P(HttpStreamFactoryImplJobControllerTest,
231 SecondJobSucceedsAfterFirstJobFailed) {
232 HttpRequestInfo request_info;
233 request_info.method = "GET";
234 request_info.url = GURL("https://www.google.com");
235
236 url::SchemeHostPort server(request_info.url);
237 AlternativeService alternative_service(QUIC, server.host(), 443);
238 SetAlternativeService(request_info, alternative_service);
239
240 request_.reset(
241 job_controller_->Start(request_info, &request_delegate_, nullptr,
242 BoundNetLog(), HttpStreamRequest::HTTP_STREAM,
243 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
244 EXPECT_TRUE(job_controller_->main_job());
245 EXPECT_TRUE(job_controller_->alternative_job());
246
247 // |main_job| fails but should not report status to Request.
248 // The alternative job will mark the main job complete.
249 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _, _)).Times(0);
250 EXPECT_CALL(*job_factory_.alternative_job(), MarkOtherJobComplete(_))
251 .Times(1);
252
253 job_controller_->OnStreamFailed(job_factory_.main_job(), ERR_FAILED,
254 SSLConfig(), SSL_FAILURE_NONE);
255
256 // |alternative_job| succeeds and should report status to Request.
257 HttpStream* http_stream =
258 new HttpBasicStream(new ClientSocketHandle(), false);
259 SetStreamToJob(http_stream, job_factory_.alternative_job());
260
261 EXPECT_CALL(request_delegate_, OnStreamReady(_, _, http_stream))
262 .WillOnce(Invoke(DeleteHttpStreamPointer));
263 job_controller_->OnStreamReady(job_factory_.alternative_job(), SSLConfig(),
264 ProxyInfo());
265 }
Ryan Hamilton 2016/06/06 17:57:31 Woo hoo!
266
267 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698