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

Side by Side Diff: content/browser/loader/async_revalidation_driver_unittest.cc

Issue 1041993004: content::ResourceDispatcherHostImpl changes for stale-while-revalidate (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@s-w-r-yhirano-patch
Patch Set: Workaround iwyu bug in prerender_resource Created 5 years, 4 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 2015 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 "content/browser/loader/async_revalidation_driver.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/location.h"
12 #include "base/macros.h"
13 #include "base/run_loop.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "ipc/ipc_message.h"
16 #include "net/base/io_buffer.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/request_priority.h"
19 #include "net/ssl/ssl_cert_request_info.h"
20 #include "net/url_request/url_request.h"
21 #include "net/url_request/url_request_job_factory.h"
22 #include "net/url_request/url_request_job_factory_impl.h"
23 #include "net/url_request/url_request_status.h"
24 #include "net/url_request/url_request_test_job.h"
25 #include "net/url_request/url_request_test_util.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 namespace content {
29 namespace {
30
31 // A mock URLRequestJob which simulates an SSL client auth request.
32 class MockClientCertURLRequestJob : public net::URLRequestTestJob {
33 public:
34 MockClientCertURLRequestJob(net::URLRequest* request,
35 net::NetworkDelegate* network_delegate)
36 : net::URLRequestTestJob(request, network_delegate, true) {}
37
38 static std::vector<std::string> test_authorities() {
39 return std::vector<std::string>(1, "dummy");
40 }
41
42 // net::URLRequestTestJob:
43 void Start() override {
44 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
45 new net::SSLCertRequestInfo);
46 cert_request_info->cert_authorities = test_authorities();
47 base::ThreadTaskRunnerHandle::Get()->PostTask(
48 FROM_HERE,
49 base::Bind(&MockClientCertURLRequestJob::NotifyCertificateRequested,
50 this, cert_request_info));
51 }
52
53 void ContinueWithCertificate(net::X509Certificate* cert) override {
54 ADD_FAILURE() << "Certificate supplied";
55 }
56
57 private:
58 ~MockClientCertURLRequestJob() override {}
59
60 DISALLOW_COPY_AND_ASSIGN(MockClientCertURLRequestJob);
61 };
62
63 class MockClientCertJobProtocolHandler
64 : public net::URLRequestJobFactory::ProtocolHandler {
65 public:
66 // URLRequestJobFactory::ProtocolHandler implementation:
67 net::URLRequestJob* MaybeCreateJob(
68 net::URLRequest* request,
69 net::NetworkDelegate* network_delegate) const override {
70 return new MockClientCertURLRequestJob(request, network_delegate);
71 }
72 };
73
74 // A mock URLRequestJob which simulates an SSL certificate error.
75 class MockSSLErrorURLRequestJob : public net::URLRequestTestJob {
76 public:
77 MockSSLErrorURLRequestJob(net::URLRequest* request,
78 net::NetworkDelegate* network_delegate)
79 : net::URLRequestTestJob(request, network_delegate, true) {}
80
81 // net::URLRequestTestJob:
82 void Start() override {
83 // This SSLInfo isn't really valid, but it is good enough for testing.
84 net::SSLInfo ssl_info;
85 ssl_info.SetCertError(net::ERR_CERT_DATE_INVALID);
86 base::ThreadTaskRunnerHandle::Get()->PostTask(
87 FROM_HERE,
88 base::Bind(&MockSSLErrorURLRequestJob::NotifySSLCertificateError, this,
89 ssl_info, false));
90 }
91
92 void ContinueDespiteLastError() override {
93 ADD_FAILURE() << "ContinueDespiteLastError called";
94 }
95
96 private:
97 ~MockSSLErrorURLRequestJob() override {}
98
99 DISALLOW_COPY_AND_ASSIGN(MockSSLErrorURLRequestJob);
100 };
101
102 class MockSSLErrorJobProtocolHandler
103 : public net::URLRequestJobFactory::ProtocolHandler {
104 public:
105 // URLRequestJobFactory::ProtocolHandler implementation:
106 net::URLRequestJob* MaybeCreateJob(
107 net::URLRequest* request,
108 net::NetworkDelegate* network_delegate) const override {
109 return new MockSSLErrorURLRequestJob(request, network_delegate);
110 }
111 };
112
113 // Dummy implementation of ResourceThrottle, an instance of which is needed to
114 // initialize AsyncRevalidationDriver.
115 class ResourceThrottleStub : public ResourceThrottle {
116 public:
117 ResourceThrottleStub() {}
118
119 // If true, defers the request in WillStartRequest.
120 void set_defer_request_on_will_start_request(
121 bool defer_request_on_will_start_request) {
122 defer_request_on_will_start_request_ = defer_request_on_will_start_request;
123 }
124
125 // If true, defers the request in WillStartUsingNetwork.
126 void set_defer_request_on_will_start_using_network(
127 bool defer_request_on_will_start_using_network) {
128 defer_request_on_will_start_using_network_ =
129 defer_request_on_will_start_using_network;
130 }
131
132 // If true, defers the request in WillProcessResponse.
133 void set_defer_request_on_will_process_response(
134 bool defer_request_on_will_process_response) {
135 defer_request_on_will_process_response_ =
136 defer_request_on_will_process_response;
137 }
138
139 bool will_redirect_request_called() const {
140 return will_redirect_request_called_;
141 }
142
143 // ResourceThrottler implementation:
144 void WillStartRequest(bool* defer) override {
145 *defer = defer_request_on_will_start_request_;
146 }
147
148 void WillStartUsingNetwork(bool* defer) override {
149 *defer = defer_request_on_will_start_using_network_;
150 }
151
152 void WillRedirectRequest(const net::RedirectInfo& redirect_info,
153 bool* defer) override {
154 will_redirect_request_called_ = true;
155 }
156
157 void WillProcessResponse(bool* defer) override {
158 *defer = defer_request_on_will_process_response_;
159 }
160
161 // Returns the name of the throttle, as a UTF-8 C-string, for logging
162 // purposes. nullptr is not allowed. Caller does *not* take ownership of the
163 // returned string.
164 const char* GetNameForLogging() const override {
165 return "ResourceThrottleStub";
166 }
167
168 private:
169 bool defer_request_on_will_start_request_ = false;
170 bool defer_request_on_will_start_using_network_ = false;
171 bool will_redirect_request_called_ = false;
172 bool defer_request_on_will_process_response_ = false;
173
174 DISALLOW_COPY_AND_ASSIGN(ResourceThrottleStub);
175 };
176
177 // This class is a variation on URLRequestTestJob that will call
178 // URLRequest::WillStartUsingNetwork before starting.
179 class URLRequestTestDelayedNetworkJob : public net::URLRequestTestJob {
180 public:
181 URLRequestTestDelayedNetworkJob(net::URLRequest* request,
182 net::NetworkDelegate* network_delegate)
183 : net::URLRequestTestJob(request, network_delegate, true) {}
184
185 // Only start if not deferred for network start.
186 void Start() override {
187 bool defer = false;
188 NotifyBeforeNetworkStart(&defer);
189 if (defer)
190 return;
191 net::URLRequestTestJob::Start();
192 }
193
194 void ResumeNetworkStart() override { net::URLRequestTestJob::StartAsync(); }
195
196 private:
197 ~URLRequestTestDelayedNetworkJob() override {}
198
199 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob);
200 };
201
202 class MockDelayedNetworkJobProtocolHandler
203 : public net::URLRequestJobFactory::ProtocolHandler {
204 public:
205 // URLRequestJobFactory::ProtocolHandler implementation:
206 net::URLRequestJob* MaybeCreateJob(
207 net::URLRequest* request,
208 net::NetworkDelegate* network_delegate) const override {
209 return new URLRequestTestDelayedNetworkJob(request, network_delegate);
210 }
211 };
212
213 } // namespace
214
215 class AsyncRevalidationDriverTest : public testing::Test {
216 protected:
217 AsyncRevalidationDriverTest()
218 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
219 raw_ptr_resource_throttle_(nullptr),
220 raw_ptr_to_request_(nullptr) {
221 test_url_request_context_.set_job_factory(&job_factory_);
222 }
223
224 GURL test_url() const { return net::URLRequestTestJob::test_url_1(); }
225
226 std::string test_data() const {
227 return net::URLRequestTestJob::test_data_1();
228 }
229
230 bool async_revalidation_complete_called() const {
231 return async_revalidation_complete_called_;
232 }
233
234 virtual net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() {
235 return net::URLRequestTestJob::CreateProtocolHandler();
236 }
237
238 void SetUpAsyncRevalidationDriverWithRequest(
239 scoped_ptr<net::URLRequest> request) {
240 raw_ptr_to_request_ = request.get();
241
242 scoped_ptr<ResourceThrottleStub> resource_throttle(
243 new ResourceThrottleStub());
244 raw_ptr_resource_throttle_ = resource_throttle.get();
245 // This use of base::Unretained() is safe because |driver_|, and the closure
246 // passed to it, will be destroyed before this object is.
247 driver_.reset(new AsyncRevalidationDriver(
248 request.Pass(), resource_throttle.Pass(),
249 base::Bind(&AsyncRevalidationDriverTest::OnAsyncRevalidationComplete,
250 base::Unretained(this))));
251 }
252
253 void SetUp() override {
254 job_factory_.SetProtocolHandler("test", CreateProtocolHandler());
255
256 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
257 test_url(), net::DEFAULT_PRIORITY, nullptr /* delegate */));
258 SetUpAsyncRevalidationDriverWithRequest(request.Pass());
259 }
260
261 void OnAsyncRevalidationComplete() {
262 EXPECT_FALSE(async_revalidation_complete_called_);
263 async_revalidation_complete_called_ = true;
264 }
265
266 TestBrowserThreadBundle thread_bundle_;
267 net::URLRequestJobFactoryImpl job_factory_;
268 net::TestURLRequestContext test_url_request_context_;
269
270 // The AsyncRevalidationDriver owns the URLRequest and the ResourceThrottle.
271 ResourceThrottleStub* raw_ptr_resource_throttle_;
272 net::URLRequest* raw_ptr_to_request_;
273 scoped_ptr<AsyncRevalidationDriver> driver_;
274 bool async_revalidation_complete_called_ = false;
275 };
276
277 TEST_F(AsyncRevalidationDriverTest, NormalRequestCompletes) {
278 driver_->StartRequest();
279 base::RunLoop().RunUntilIdle();
280 EXPECT_TRUE(async_revalidation_complete_called());
281 }
282
283 class AsyncRevalidationDriverClientCertTest
284 : public AsyncRevalidationDriverTest {
285 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override {
286 return new MockClientCertJobProtocolHandler();
287 }
288 };
289
290 // Verifies that async revalidation requests do not attempt to provide client
291 // certificates.
292 TEST_F(AsyncRevalidationDriverClientCertTest, RequestRejected) {
293 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
294 test_url(), net::LOW, nullptr /* delegate */));
295
296 SetUpAsyncRevalidationDriverWithRequest(request.Pass());
297
298 // Start the request and wait for it to pause.
299 driver_->StartRequest();
300 base::RunLoop().RunUntilIdle();
301
302 // Check that SelectClientCertificate wasn't called and the request aborted.
303 const net::URLRequestStatus& status = raw_ptr_to_request_->status();
304 EXPECT_FALSE(status.is_success());
305 EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, status.error());
306 EXPECT_TRUE(async_revalidation_complete_called());
307 }
308
309 class AsyncRevalidationDriverSSLErrorTest : public AsyncRevalidationDriverTest {
310 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override {
311 return new MockSSLErrorJobProtocolHandler();
312 }
313 };
314
315 // Verifies that async revalidation requests do not attempt to recover from SSL
316 // certificate errors.
317 TEST_F(AsyncRevalidationDriverSSLErrorTest, RequestWithSSLErrorRejected) {
318 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
319 test_url(), net::LOW, nullptr /* delegate */));
320
321 SetUpAsyncRevalidationDriverWithRequest(request.Pass());
322
323 // Start the request and wait for it to pause.
324 driver_->StartRequest();
325 base::RunLoop().RunUntilIdle();
326
327 // Check that the request has been aborted.
328 const net::URLRequestStatus& status = raw_ptr_to_request_->status();
329 EXPECT_FALSE(status.is_success());
330 EXPECT_EQ(net::ERR_CERT_DATE_INVALID, status.error());
331 EXPECT_TRUE(async_revalidation_complete_called());
332 }
333
334 // Verifies that resuming a cancelled request does not start it again.
335 TEST_F(AsyncRevalidationDriverTest, ResumeCancelledRequest) {
336 raw_ptr_resource_throttle_->set_defer_request_on_will_start_request(true);
337
338 driver_->StartRequest();
339 driver_->CancelRequest();
340 implicit_cast<ResourceController*>(driver_.get())->Resume();
341 base::RunLoop().RunUntilIdle();
342 EXPECT_TRUE(async_revalidation_complete_called());
343 EXPECT_FALSE(raw_ptr_to_request_->status().is_success());
344 }
345
346 // Verify that a cancelled request calls |completion_callback|.
347 TEST_F(AsyncRevalidationDriverTest, CancelledRequestCallsCompleteCallback) {
348 driver_->StartRequest();
349 driver_->CancelRequest();
350 base::RunLoop().RunUntilIdle();
351 EXPECT_TRUE(async_revalidation_complete_called());
352 }
353
354 // Verifies that request that should be deferred at start is deferred.
355 TEST_F(AsyncRevalidationDriverTest, DeferOnStart) {
356 raw_ptr_resource_throttle_->set_defer_request_on_will_start_request(true);
357
358 driver_->StartRequest();
359 base::RunLoop().RunUntilIdle();
360 EXPECT_FALSE(raw_ptr_to_request_->is_pending());
361 EXPECT_FALSE(async_revalidation_complete_called());
362 }
363
364 class AsyncRevalidationDriverNetworkStartTest
365 : public AsyncRevalidationDriverTest {
366 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override {
367 return new MockDelayedNetworkJobProtocolHandler();
368 }
369 };
370
371 // Verifies that request that should be deferred on network start is deferred.
372 TEST_F(AsyncRevalidationDriverNetworkStartTest, DeferOnNetworkStart) {
373 raw_ptr_resource_throttle_->set_defer_request_on_will_start_request(true);
374
375 driver_->StartRequest();
376 base::RunLoop().RunUntilIdle();
377 EXPECT_FALSE(raw_ptr_to_request_->is_pending());
378 EXPECT_FALSE(async_revalidation_complete_called());
379 }
380
381 // Verifies that request that should be deferred on response start is deferred.
382 TEST_F(AsyncRevalidationDriverTest, DeferOnResponseStart) {
383 raw_ptr_resource_throttle_->set_defer_request_on_will_process_response(true);
384
385 driver_->StartRequest();
386 base::RunLoop().RunUntilIdle();
387 EXPECT_FALSE(async_revalidation_complete_called());
388 }
389
390 // Verifies that redirects are not followed.
391 TEST_F(AsyncRevalidationDriverTest, RedirectsAreNotFollowed) {
392 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
393 net::URLRequestTestJob::test_url_redirect_to_url_2(),
394 net::DEFAULT_PRIORITY, nullptr /* delegate */));
395 SetUpAsyncRevalidationDriverWithRequest(request.Pass());
396
397 driver_->StartRequest();
398 while (net::URLRequestTestJob::ProcessOnePendingMessage())
399 base::RunLoop().RunUntilIdle();
400 base::RunLoop().RunUntilIdle();
401 const net::URLRequestStatus& status = raw_ptr_to_request_->status();
402 EXPECT_FALSE(status.is_success());
403 EXPECT_EQ(net::ERR_ABORTED, status.error());
404 EXPECT_TRUE(async_revalidation_complete_called());
405 }
406
407 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698