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

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: Remove unnecessary deferral logic from AsyncRevalidationDriver Created 5 years, 1 month 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"
Bence 2015/11/17 13:12:22 What do you need this include for?
Adam Rice 2015/11/17 17:45:52 For FROM_HERE. Comment added.
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"
Bence 2015/11/17 13:12:22 Please remove this include, because you have alrea
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"
Bence 2015/11/17 13:12:22 Please remove this include, because you have alrea
Adam Rice 2015/11/17 17:45:51 Thanks, done.
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:
Bence 2015/11/17 13:12:22 Add " implementation" right before colon.
Adam Rice 2015/11/17 17:45:52 Done.
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";
Bence 2015/11/17 13:12:22 Optional: consider adding a period to end this sen
Adam Rice 2015/11/17 17:45:52 Done.
55 }
56
57 private:
58 ~MockClientCertURLRequestJob() override {}
59
60 DISALLOW_COPY_AND_ASSIGN(MockClientCertURLRequestJob);
Bence 2015/11/17 13:12:22 This class does not have any members so it should
Adam Rice 2015/11/17 17:45:52 It's not actually copyable because of the base cla
Bence 2015/11/17 21:34:27 Oh okay, that makes sense. Thank you for clarifyi
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:
Bence 2015/11/17 13:12:22 Add " implementation" right before colon.
Adam Rice 2015/11/17 17:45:52 Done.
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";
Bence 2015/11/17 13:12:22 Optional: consider adding a full stop to end this
Adam Rice 2015/11/17 17:45:52 Done.
94 }
95
96 private:
97 ~MockSSLErrorURLRequestJob() override {}
98
99 DISALLOW_COPY_AND_ASSIGN(MockSSLErrorURLRequestJob);
Bence 2015/11/17 13:12:22 Why?
Adam Rice 2015/11/17 17:45:52 No particular reason, just making it explicit.
Bence 2015/11/17 21:34:27 Sounds good.
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
Bence 2015/11/17 13:12:22 Optional: consider writing |nullptr| to mitigate t
Adam Rice 2015/11/17 17:45:52 It appears for some reason I copied this comment v
Bence 2015/11/17 21:34:28 That would also be fine with me
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);
Bence 2015/11/17 13:12:22 Copying and assigning this class seems to be safe
Adam Rice 2015/11/17 17:45:51 I don't want to provide a guarantee that copying i
Bence 2015/11/17 21:34:27 Fair enough.
175 };
176
177 // This class is a variation on URLRequestTestJob that will call
178 // URLRequest::WillStartUsingNetwork before starting.
179 class URLRequestTestDelayedNetworkJob : public net::URLRequestTestJob {
Bence 2015/11/17 13:12:22 This class does not seem to be used anywhere. Ple
Adam Rice 2015/11/17 17:45:52 Ah, sorry, I failed to remove this. The history is
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();
Bence 2015/11/17 13:12:22 Early returns seems a bit contorted to me. Consid
Adam Rice 2015/11/17 17:45:52 Acknowledged.
192 }
193
194 void ResumeNetworkStart() override { net::URLRequestTestJob::StartAsync(); }
195
196 private:
197 ~URLRequestTestDelayedNetworkJob() override {}
198
199 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedNetworkJob);
Bence 2015/11/17 13:12:22 Why?
Adam Rice 2015/11/17 17:45:52 I like to be explicit.
200 };
201
202 } // namespace
203
204 class AsyncRevalidationDriverTest : public testing::Test {
205 protected:
206 AsyncRevalidationDriverTest()
207 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
208 raw_ptr_resource_throttle_(nullptr),
209 raw_ptr_to_request_(nullptr) {
210 test_url_request_context_.set_job_factory(&job_factory_);
211 }
212
213 GURL test_url() const { return net::URLRequestTestJob::test_url_1(); }
214
215 std::string test_data() const {
216 return net::URLRequestTestJob::test_data_1();
217 }
218
219 bool async_revalidation_complete_called() const {
220 return async_revalidation_complete_called_;
221 }
222
223 virtual net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() {
224 return net::URLRequestTestJob::CreateProtocolHandler();
225 }
226
227 void SetUpAsyncRevalidationDriverWithRequest(
228 scoped_ptr<net::URLRequest> request) {
229 raw_ptr_to_request_ = request.get();
230
231 scoped_ptr<ResourceThrottleStub> resource_throttle(
Bence 2015/11/17 13:12:22 Optional: throw away |resource_throttle| local var
Adam Rice 2015/11/17 17:45:52 Done.
232 new ResourceThrottleStub());
233 raw_ptr_resource_throttle_ = resource_throttle.get();
234 // This use of base::Unretained() is safe because |driver_|, and the closure
235 // passed to it, will be destroyed before this object is.
236 driver_.reset(new AsyncRevalidationDriver(
237 request.Pass(), resource_throttle.Pass(),
238 base::Bind(&AsyncRevalidationDriverTest::OnAsyncRevalidationComplete,
239 base::Unretained(this))));
240 }
241
242 void SetUp() override {
243 job_factory_.SetProtocolHandler("test", CreateProtocolHandler());
244
245 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
246 test_url(), net::DEFAULT_PRIORITY, nullptr /* delegate */));
247 SetUpAsyncRevalidationDriverWithRequest(request.Pass());
248 }
249
250 void OnAsyncRevalidationComplete() {
251 EXPECT_FALSE(async_revalidation_complete_called_);
252 async_revalidation_complete_called_ = true;
253 }
254
255 TestBrowserThreadBundle thread_bundle_;
256 net::URLRequestJobFactoryImpl job_factory_;
257 net::TestURLRequestContext test_url_request_context_;
258
259 // The AsyncRevalidationDriver owns the URLRequest and the ResourceThrottle.
260 ResourceThrottleStub* raw_ptr_resource_throttle_;
261 net::URLRequest* raw_ptr_to_request_;
Bence 2015/11/17 13:12:22 Please harmonise prefix: raw_ptr_ or raw_ptr_to_ f
Adam Rice 2015/11/17 17:45:52 Done.
262 scoped_ptr<AsyncRevalidationDriver> driver_;
263 bool async_revalidation_complete_called_ = false;
264 };
265
266 TEST_F(AsyncRevalidationDriverTest, NormalRequestCompletes) {
267 driver_->StartRequest();
268 base::RunLoop().RunUntilIdle();
269 EXPECT_TRUE(async_revalidation_complete_called());
270 }
271
272 class AsyncRevalidationDriverClientCertTest
273 : public AsyncRevalidationDriverTest {
274 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override {
275 return new MockClientCertJobProtocolHandler();
276 }
277 };
278
279 // Verifies that async revalidation requests do not attempt to provide client
280 // certificates.
281 TEST_F(AsyncRevalidationDriverClientCertTest, RequestRejected) {
282 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
283 test_url(), net::LOW, nullptr /* delegate */));
284
285 SetUpAsyncRevalidationDriverWithRequest(request.Pass());
286
287 // Start the request and wait for it to pause.
288 driver_->StartRequest();
289 base::RunLoop().RunUntilIdle();
290
291 // Check that SelectClientCertificate wasn't called and the request aborted.
292 const net::URLRequestStatus& status = raw_ptr_to_request_->status();
293 EXPECT_FALSE(status.is_success());
294 EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, status.error());
295 EXPECT_TRUE(async_revalidation_complete_called());
296 }
297
298 class AsyncRevalidationDriverSSLErrorTest : public AsyncRevalidationDriverTest {
299 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override {
300 return new MockSSLErrorJobProtocolHandler();
301 }
302 };
303
304 // Verifies that async revalidation requests do not attempt to recover from SSL
305 // certificate errors.
306 TEST_F(AsyncRevalidationDriverSSLErrorTest, RequestWithSSLErrorRejected) {
307 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
308 test_url(), net::LOW, nullptr /* delegate */));
309
310 SetUpAsyncRevalidationDriverWithRequest(request.Pass());
311
312 // Start the request and wait for it to pause.
313 driver_->StartRequest();
314 base::RunLoop().RunUntilIdle();
315
316 // Check that the request has been aborted.
317 const net::URLRequestStatus& status = raw_ptr_to_request_->status();
318 EXPECT_FALSE(status.is_success());
319 EXPECT_EQ(net::ERR_ABORTED, status.error());
320 EXPECT_TRUE(async_revalidation_complete_called());
321 }
322
323 // Verifies that resuming a cancelled request does not start it again.
324 TEST_F(AsyncRevalidationDriverTest, ResumeCancelledRequest) {
325 raw_ptr_resource_throttle_->set_defer_request_on_will_start_request(true);
326
327 driver_->StartRequest();
328 driver_->CancelRequest();
329 implicit_cast<ResourceController*>(driver_.get())->Resume();
Bence 2015/11/17 13:12:22 Please do not do implicit_cast, because it is used
Adam Rice 2015/11/17 17:45:52 Also, since I wrote this I accidentally got implic
330 base::RunLoop().RunUntilIdle();
331 EXPECT_TRUE(async_revalidation_complete_called());
332 EXPECT_FALSE(raw_ptr_to_request_->status().is_success());
333 }
334
335 // Verify that a cancelled request calls |completion_callback|.
336 TEST_F(AsyncRevalidationDriverTest, CancelledRequestCallsCompleteCallback) {
337 driver_->StartRequest();
338 driver_->CancelRequest();
339 base::RunLoop().RunUntilIdle();
340 EXPECT_TRUE(async_revalidation_complete_called());
341 }
342
343 // Verifies that request that should be deferred at start is deferred.
344 TEST_F(AsyncRevalidationDriverTest, DeferOnStart) {
345 raw_ptr_resource_throttle_->set_defer_request_on_will_start_request(true);
346
347 driver_->StartRequest();
348 base::RunLoop().RunUntilIdle();
349 EXPECT_FALSE(raw_ptr_to_request_->is_pending());
350 EXPECT_FALSE(async_revalidation_complete_called());
351 }
352
353 // Verifies that redirects are not followed.
354 TEST_F(AsyncRevalidationDriverTest, RedirectsAreNotFollowed) {
355 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
356 net::URLRequestTestJob::test_url_redirect_to_url_2(),
357 net::DEFAULT_PRIORITY, nullptr /* delegate */));
358 SetUpAsyncRevalidationDriverWithRequest(request.Pass());
359
360 driver_->StartRequest();
361 while (net::URLRequestTestJob::ProcessOnePendingMessage())
362 base::RunLoop().RunUntilIdle();
363 base::RunLoop().RunUntilIdle();
364 const net::URLRequestStatus& status = raw_ptr_to_request_->status();
365 EXPECT_FALSE(status.is_success());
366 EXPECT_EQ(net::ERR_ABORTED, status.error());
367 EXPECT_TRUE(async_revalidation_complete_called());
368 }
369
370 // A URLRequestTestJob that sets |request_time| and |was_cached| on their
371 // response_info, and causes the test to fail if Read() is called.
372 class FromCacheURLRequestJob : public net::URLRequestTestJob {
373 public:
374 FromCacheURLRequestJob(net::URLRequest* request,
375 net::NetworkDelegate* network_delegate)
376 : net::URLRequestTestJob(request, network_delegate, true) {}
377
378 void GetResponseInfo(net::HttpResponseInfo* info) override {
379 URLRequestTestJob::GetResponseInfo(info);
380 info->request_time = base::Time::Now();
381 info->was_cached = true;
382 }
383
384 bool ReadRawData(net::IOBuffer* buf, int buf_size, int* bytes_read) override {
385 ADD_FAILURE() << "ReadRawData() was called";
386 return URLRequestTestJob::ReadRawData(buf, buf_size, bytes_read);
387 }
388
389 private:
390 ~FromCacheURLRequestJob() override {}
391
392 DISALLOW_COPY_AND_ASSIGN(FromCacheURLRequestJob);
Bence 2015/11/17 13:12:22 Why bother?
Adam Rice 2015/11/17 17:45:52 It seems like the right thing to do.
Bence 2015/11/17 21:34:27 Okay then.
393 };
394
395 class FromCacheProtocolHandler
396 : public net::URLRequestJobFactory::ProtocolHandler {
397 public:
398 // URLRequestJobFactory::ProtocolHandler implementation:
399 net::URLRequestJob* MaybeCreateJob(
400 net::URLRequest* request,
401 net::NetworkDelegate* network_delegate) const override {
402 return new FromCacheURLRequestJob(request, network_delegate);
403 }
404 };
405
406 class AsyncRevalidationDriverFromCacheTest
407 : public AsyncRevalidationDriverTest {
408 net::URLRequestJobFactory::ProtocolHandler* CreateProtocolHandler() override {
409 return new FromCacheProtocolHandler();
410 }
411 };
412
413 TEST_F(AsyncRevalidationDriverFromCacheTest,
414 CacheNotReadOnSuccessfulRevalidation) {
415 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
416 test_url(), net::LOW, nullptr /* delegate */));
417
418 SetUpAsyncRevalidationDriverWithRequest(request.Pass());
419
420 driver_->StartRequest();
421 base::RunLoop().RunUntilIdle();
422
423 EXPECT_TRUE(async_revalidation_complete_called());
424 }
425
426 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698