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

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

Powered by Google App Engine
This is Rietveld 408576698