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

Side by Side Diff: content/browser/loader/async_revalidation_driver_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698