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

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: Rebase. Created 5 years 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 <utility>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/location.h"
13 #include "base/macros.h"
14 #include "base/run_loop.h"
15 #include "content/public/common/content_client.h"
16 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "content/test/test_content_browser_client.h"
18 #include "ipc/ipc_message.h"
19 #include "net/base/net_errors.h"
20 #include "net/base/request_priority.h"
21 #include "net/ssl/ssl_cert_request_info.h"
22 #include "net/url_request/url_request_job_factory.h"
23 #include "net/url_request/url_request_job_factory_impl.h"
24 #include "net/url_request/url_request_status.h"
25 #include "net/url_request/url_request_test_job.h"
26 #include "net/url_request/url_request_test_util.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28
29 namespace content {
30 namespace {
31
32 // A mock URLRequestJob which simulates an SSL client auth request.
33 class MockClientCertURLRequestJob : public net::URLRequestTestJob {
34 public:
35 MockClientCertURLRequestJob(net::URLRequest* request,
36 net::NetworkDelegate* network_delegate)
37 : net::URLRequestTestJob(request, network_delegate, true),
38 weak_factory_(this) {}
39
40 // net::URLRequestTestJob implementation:
41 void Start() override {
42 scoped_refptr<net::SSLCertRequestInfo> cert_request_info(
43 new net::SSLCertRequestInfo);
44 base::ThreadTaskRunnerHandle::Get()->PostTask(
45 FROM_HERE,
46 base::Bind(&MockClientCertURLRequestJob::NotifyCertificateRequested,
47 weak_factory_.GetWeakPtr(), cert_request_info));
48 }
49
50 void ContinueWithCertificate(
51 net::X509Certificate* cert,
52 net::SSLPrivateKey* client_private_key) override {
53 ADD_FAILURE() << "Certificate supplied.";
54 }
55
56 void Kill() override {
57 weak_factory_.InvalidateWeakPtrs();
58 URLRequestJob::Kill();
59 }
60
61 private:
62 ~MockClientCertURLRequestJob() override {}
63
64 base::WeakPtrFactory<MockClientCertURLRequestJob> weak_factory_;
65
66 DISALLOW_COPY_AND_ASSIGN(MockClientCertURLRequestJob);
67 };
68
69 class MockClientCertJobProtocolHandler
70 : public net::URLRequestJobFactory::ProtocolHandler {
71 public:
72 // URLRequestJobFactory::ProtocolHandler implementation:
73 net::URLRequestJob* MaybeCreateJob(
74 net::URLRequest* request,
75 net::NetworkDelegate* network_delegate) const override {
76 return new MockClientCertURLRequestJob(request, network_delegate);
77 }
78 };
79
80 // A mock URLRequestJob which simulates an SSL certificate error.
81 class MockSSLErrorURLRequestJob : public net::URLRequestTestJob {
82 public:
83 MockSSLErrorURLRequestJob(net::URLRequest* request,
84 net::NetworkDelegate* network_delegate)
85 : net::URLRequestTestJob(request, network_delegate, true) {}
86
87 // net::URLRequestTestJob implementation:
88 void Start() override {
89 // This SSLInfo isn't really valid, but it is good enough for testing.
90 net::SSLInfo ssl_info;
91 ssl_info.SetCertError(net::ERR_CERT_DATE_INVALID);
92 base::ThreadTaskRunnerHandle::Get()->PostTask(
93 FROM_HERE,
94 base::Bind(&MockSSLErrorURLRequestJob::NotifySSLCertificateError, this,
95 ssl_info, false));
96 }
97
98 void ContinueDespiteLastError() override {
99 ADD_FAILURE() << "ContinueDespiteLastError called.";
100 }
101
102 private:
103 ~MockSSLErrorURLRequestJob() override {}
104
105 DISALLOW_COPY_AND_ASSIGN(MockSSLErrorURLRequestJob);
106 };
107
108 class MockSSLErrorJobProtocolHandler
109 : public net::URLRequestJobFactory::ProtocolHandler {
110 public:
111 // URLRequestJobFactory::ProtocolHandler implementation:
112 net::URLRequestJob* MaybeCreateJob(
113 net::URLRequest* request,
114 net::NetworkDelegate* network_delegate) const override {
115 return new MockSSLErrorURLRequestJob(request, network_delegate);
116 }
117 };
118
119 // Dummy implementation of ResourceThrottle, an instance of which is needed to
120 // initialize AsyncRevalidationDriver.
121 class ResourceThrottleStub : public ResourceThrottle {
122 public:
123 ResourceThrottleStub() {}
124
125 // If true, defers the request in WillStartRequest.
126 void set_defer_request_on_will_start_request(
127 bool defer_request_on_will_start_request) {
128 defer_request_on_will_start_request_ = defer_request_on_will_start_request;
129 }
130
131 // ResourceThrottler implementation:
132 void WillStartRequest(bool* defer) override {
133 *defer = defer_request_on_will_start_request_;
134 }
135
136 const char* GetNameForLogging() const override {
137 return "ResourceThrottleStub";
138 }
139
140 private:
141 bool defer_request_on_will_start_request_ = false;
142
143 DISALLOW_COPY_AND_ASSIGN(ResourceThrottleStub);
144 };
145
146 class AsyncRevalidationDriverTest : public testing::Test {
147 protected:
148 AsyncRevalidationDriverTest()
149 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
150 raw_ptr_resource_throttle_(nullptr),
151 raw_ptr_request_(nullptr) {
152 test_url_request_context_.set_job_factory(&job_factory_);
153 }
154
155 GURL test_url() const { return net::URLRequestTestJob::test_url_1(); }
156
157 std::string test_data() const {
158 return net::URLRequestTestJob::test_data_1();
159 }
160
161 bool async_revalidation_complete_called() const {
162 return async_revalidation_complete_called_;
163 }
164
165 virtual scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
166 CreateProtocolHandler() {
167 return net::URLRequestTestJob::CreateProtocolHandler();
168 }
169
170 void SetUpAsyncRevalidationDriverWithRequest(
171 scoped_ptr<net::URLRequest> request) {
172 raw_ptr_request_ = request.get();
173 raw_ptr_resource_throttle_ = new ResourceThrottleStub();
174 // This use of base::Unretained() is safe because |driver_|, and the closure
175 // passed to it, will be destroyed before this object is.
176 driver_.reset(new AsyncRevalidationDriver(
177 std::move(request), make_scoped_ptr(raw_ptr_resource_throttle_),
178 base::Bind(&AsyncRevalidationDriverTest::OnAsyncRevalidationComplete,
179 base::Unretained(this))));
180 }
181
182 void SetUp() override {
183 job_factory_.SetProtocolHandler("test", CreateProtocolHandler());
184
185 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
186 test_url(), net::DEFAULT_PRIORITY, nullptr /* delegate */));
187 SetUpAsyncRevalidationDriverWithRequest(std::move(request));
188 }
189
190 void OnAsyncRevalidationComplete() {
191 EXPECT_FALSE(async_revalidation_complete_called_);
192 async_revalidation_complete_called_ = true;
193 }
194
195 TestBrowserThreadBundle thread_bundle_;
196 net::URLRequestJobFactoryImpl job_factory_;
197 net::TestURLRequestContext test_url_request_context_;
198
199 // The AsyncRevalidationDriver owns the URLRequest and the ResourceThrottle.
200 ResourceThrottleStub* raw_ptr_resource_throttle_;
201 net::URLRequest* raw_ptr_request_;
202 scoped_ptr<AsyncRevalidationDriver> driver_;
203 bool async_revalidation_complete_called_ = false;
204 };
205
206 TEST_F(AsyncRevalidationDriverTest, NormalRequestCompletes) {
207 driver_->StartRequest();
208 base::RunLoop().RunUntilIdle();
209 EXPECT_TRUE(async_revalidation_complete_called());
210 }
211
212 class AsyncRevalidationDriverClientCertTest
213 : public AsyncRevalidationDriverTest {
214 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> CreateProtocolHandler()
215 override {
216 return make_scoped_ptr(new MockClientCertJobProtocolHandler());
217 }
218 };
219
220 // Test browser client that causes the test to fail if SelectClientCertificate()
221 // is called. Automatically sets itself as the browser client when constructed
222 // and restores the old browser client in the destructor.
223 class ScopedDontSelectCertificateBrowserClient
224 : public TestContentBrowserClient {
225 public:
226 ScopedDontSelectCertificateBrowserClient() {
227 old_client_ = SetBrowserClientForTesting(this);
228 }
229
230 ~ScopedDontSelectCertificateBrowserClient() override {
231 SetBrowserClientForTesting(old_client_);
232 }
233
234 void SelectClientCertificate(
235 WebContents* web_contents,
236 net::SSLCertRequestInfo* cert_request_info,
237 scoped_ptr<ClientCertificateDelegate> delegate) override {
kinuko 2015/12/03 07:51:41 This seems to require including client_certificate
Adam Rice 2015/12/03 14:20:43 Sorry I missed that. Fixed.
238 ADD_FAILURE() << "SelectClientCertificate was called.";
239 }
240
241 private:
242 ContentBrowserClient* old_client_;
243
244 DISALLOW_COPY_AND_ASSIGN(ScopedDontSelectCertificateBrowserClient);
245 };
246
247 // Verifies that async revalidation requests do not attempt to provide client
248 // certificates.
249 TEST_F(AsyncRevalidationDriverClientCertTest, RequestRejected) {
250 // Ensure that SelectClientCertificate is not called during this test.
251 ScopedDontSelectCertificateBrowserClient test_client;
252 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
253 test_url(), net::LOW, nullptr /* delegate */));
254
255 SetUpAsyncRevalidationDriverWithRequest(std::move(request));
256
257 // Start the request and wait for it to pause.
258 driver_->StartRequest();
259
260 // Because TestBrowserThreadBundle only uses one real thread, this is
261 // sufficient to ensure that tasks posted to the "UI thread" have run.
262 base::RunLoop().RunUntilIdle();
263
264 // Check that the request aborted.
265 const net::URLRequestStatus& status = raw_ptr_request_->status();
266 EXPECT_FALSE(status.is_success());
267 EXPECT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, status.error());
268 EXPECT_TRUE(async_revalidation_complete_called());
269 }
270
271 class AsyncRevalidationDriverSSLErrorTest : public AsyncRevalidationDriverTest {
272 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> CreateProtocolHandler()
273 override {
274 return make_scoped_ptr(new MockSSLErrorJobProtocolHandler());
275 }
276 };
277
278 // Verifies that async revalidation requests do not attempt to recover from SSL
279 // certificate errors.
280 TEST_F(AsyncRevalidationDriverSSLErrorTest, RequestWithSSLErrorRejected) {
281 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
282 test_url(), net::LOW, nullptr /* delegate */));
283
284 SetUpAsyncRevalidationDriverWithRequest(std::move(request));
285
286 // Start the request and wait for it to pause.
287 driver_->StartRequest();
288 base::RunLoop().RunUntilIdle();
289
290 // Check that the request has been aborted.
291 const net::URLRequestStatus& status = raw_ptr_request_->status();
292 EXPECT_FALSE(status.is_success());
293 EXPECT_EQ(net::ERR_ABORTED, status.error());
294 EXPECT_TRUE(async_revalidation_complete_called());
295 }
296
297 // Verifies that resuming a cancelled request does not start it again.
298 TEST_F(AsyncRevalidationDriverTest, ResumeCancelledRequest) {
299 raw_ptr_resource_throttle_->set_defer_request_on_will_start_request(true);
300
301 driver_->StartRequest();
302 driver_->CancelRequest();
303 ResourceController* driver_as_resource_controller = driver_.get();
304 driver_as_resource_controller->Resume();
305 base::RunLoop().RunUntilIdle();
306 EXPECT_TRUE(async_revalidation_complete_called());
307 EXPECT_FALSE(raw_ptr_request_->status().is_success());
308 }
309
310 // Verify that a cancelled request calls |completion_callback|.
kinuko 2015/12/03 07:51:41 nit: Verify -> Verifies
Adam Rice 2015/12/03 14:20:43 Done.
311 TEST_F(AsyncRevalidationDriverTest, CancelledRequestCallsCompleteCallback) {
312 driver_->StartRequest();
313 driver_->CancelRequest();
314 base::RunLoop().RunUntilIdle();
315 EXPECT_TRUE(async_revalidation_complete_called());
316 }
317
318 // Verifies that request that should be deferred at start is deferred.
319 TEST_F(AsyncRevalidationDriverTest, DeferOnStart) {
320 raw_ptr_resource_throttle_->set_defer_request_on_will_start_request(true);
321
322 driver_->StartRequest();
323 base::RunLoop().RunUntilIdle();
324 EXPECT_FALSE(raw_ptr_request_->is_pending());
325 EXPECT_FALSE(async_revalidation_complete_called());
326 }
327
328 // Verifies that resuming a deferred request works. Assumes that DeferOnStart
329 // passes.
330 TEST_F(AsyncRevalidationDriverTest, ResumeDeferredRequestWorks) {
331 raw_ptr_resource_throttle_->set_defer_request_on_will_start_request(true);
332
333 driver_->StartRequest();
334 base::RunLoop().RunUntilIdle();
335
336 ResourceController* driver_as_resource_controller = driver_.get();
337 driver_as_resource_controller->Resume();
338 base::RunLoop().RunUntilIdle();
339 EXPECT_TRUE(async_revalidation_complete_called());
340 }
341
342 // Verifies that redirects are not followed.
343 TEST_F(AsyncRevalidationDriverTest, RedirectsAreNotFollowed) {
344 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
345 net::URLRequestTestJob::test_url_redirect_to_url_2(),
346 net::DEFAULT_PRIORITY, nullptr /* delegate */));
347 SetUpAsyncRevalidationDriverWithRequest(std::move(request));
348
349 driver_->StartRequest();
350 while (net::URLRequestTestJob::ProcessOnePendingMessage())
351 base::RunLoop().RunUntilIdle();
352 base::RunLoop().RunUntilIdle();
353 const net::URLRequestStatus& status = raw_ptr_request_->status();
354 EXPECT_FALSE(status.is_success());
355 EXPECT_EQ(net::ERR_ABORTED, status.error());
356 EXPECT_TRUE(async_revalidation_complete_called());
357 }
358
359 // A URLRequestTestJob that sets |request_time| and |was_cached| on their
360 // response_info, and causes the test to fail if Read() is called.
361 class FromCacheURLRequestJob : public net::URLRequestTestJob {
362 public:
363 FromCacheURLRequestJob(net::URLRequest* request,
364 net::NetworkDelegate* network_delegate)
365 : net::URLRequestTestJob(request, network_delegate, true) {}
366
367 void GetResponseInfo(net::HttpResponseInfo* info) override {
368 URLRequestTestJob::GetResponseInfo(info);
369 info->request_time = base::Time::Now();
370 info->was_cached = true;
371 }
372
373 int ReadRawData(net::IOBuffer* buf, int buf_size) override {
374 ADD_FAILURE() << "ReadRawData() was called.";
375 return URLRequestTestJob::ReadRawData(buf, buf_size);
376 }
377
378 private:
379 ~FromCacheURLRequestJob() override {}
380
381 DISALLOW_COPY_AND_ASSIGN(FromCacheURLRequestJob);
382 };
383
384 class FromCacheProtocolHandler
385 : public net::URLRequestJobFactory::ProtocolHandler {
386 public:
387 // URLRequestJobFactory::ProtocolHandler implementation:
388 net::URLRequestJob* MaybeCreateJob(
389 net::URLRequest* request,
390 net::NetworkDelegate* network_delegate) const override {
391 return new FromCacheURLRequestJob(request, network_delegate);
392 }
393 };
394
395 class AsyncRevalidationDriverFromCacheTest
396 : public AsyncRevalidationDriverTest {
397 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> CreateProtocolHandler()
398 override {
399 return make_scoped_ptr(new FromCacheProtocolHandler());
400 }
401 };
402
403 TEST_F(AsyncRevalidationDriverFromCacheTest,
404 CacheNotReadOnSuccessfulRevalidation) {
405 scoped_ptr<net::URLRequest> request(test_url_request_context_.CreateRequest(
406 test_url(), net::LOW, nullptr /* delegate */));
407
408 SetUpAsyncRevalidationDriverWithRequest(std::move(request));
409
410 driver_->StartRequest();
411 base::RunLoop().RunUntilIdle();
412
413 EXPECT_TRUE(async_revalidation_complete_called());
414 }
415
416 } // namespace
417 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698