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

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

Powered by Google App Engine
This is Rietveld 408576698