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

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

Powered by Google App Engine
This is Rietveld 408576698