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

Side by Side Diff: content/browser/loader/async_revalidation_manager_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_manager.h"
6
7 #include <queue>
8 #include <set>
9 #include <utility>
10
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/macros.h"
14 #include "base/memory/shared_memory_handle.h"
15 #include "base/pickle.h"
16 #include "base/run_loop.h"
17 #include "content/browser/child_process_security_policy_impl.h"
18 #include "content/browser/loader/resource_dispatcher_host_impl.h"
19 #include "content/browser/loader/resource_message_filter.h"
20 #include "content/common/child_process_host_impl.h"
21 #include "content/common/resource_messages.h"
22 #include "content/public/browser/resource_context.h"
23 #include "content/public/common/appcache_info.h"
24 #include "content/public/common/process_type.h"
25 #include "content/public/common/resource_type.h"
26 #include "content/public/test/test_browser_context.h"
27 #include "content/public/test/test_browser_thread_bundle.h"
28 #include "ipc/ipc_param_traits.h"
29 #include "net/base/load_flags.h"
30 #include "net/base/network_delegate.h"
31 #include "net/http/http_util.h"
32 #include "net/url_request/url_request.h"
33 #include "net/url_request/url_request_job.h"
34 #include "net/url_request/url_request_job_factory.h"
35 #include "net/url_request/url_request_test_job.h"
36 #include "net/url_request/url_request_test_util.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 #include "ui/base/page_transition_types.h"
39 #include "url/gurl.h"
40
41 namespace content {
42
43 namespace {
44
45 // This class is a variation on URLRequestTestJob that
46 // returns ERR_IO_PENDING before every read, not just the first one.
47 class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
48 public:
49 URLRequestTestDelayedCompletionJob(net::URLRequest* request,
50 net::NetworkDelegate* network_delegate,
51 const std::string& response_headers,
52 const std::string& response_data)
53 : net::URLRequestTestJob(request,
54 network_delegate,
55 response_headers,
56 response_data,
57 false) {}
58
59 private:
60 ~URLRequestTestDelayedCompletionJob() override {}
61
62 bool NextReadAsync() override { return true; }
63
64 DISALLOW_COPY_AND_ASSIGN(URLRequestTestDelayedCompletionJob);
65 };
66
67 class TestURLRequestJobFactory : public net::URLRequestJobFactory {
68 public:
69 TestURLRequestJobFactory() = default;
70
71 void HandleScheme(const std::string& scheme) {
72 supported_schemes_.insert(scheme);
73 }
74
75 // Sets the contents of the response. |headers| should have "\n" as line
76 // breaks and end in "\n\n".
77 void SetResponse(const std::string& headers, const std::string& data) {
78 response_headers_ = headers;
79 response_data_ = data;
80 }
81
82 using URLRequestJobCreateCallback =
83 base::Callback<net::URLRequestJob*(net::URLRequest*,
kinuko 2015/12/03 07:51:41 nit: using/typedef's at the beginning of declarati
Adam Rice 2015/12/03 14:20:43 Done.
84 net::NetworkDelegate*)>;
85
86 void SetCustomURLRequestJobCreateCallback(
87 const URLRequestJobCreateCallback& callback) {
88 custom_url_request_job_create_callback_ = callback;
89 }
90
91 net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
92 const std::string& scheme,
93 net::URLRequest* request,
94 net::NetworkDelegate* network_delegate) const override {
95 if (!custom_url_request_job_create_callback_.is_null()) {
96 return custom_url_request_job_create_callback_.Run(request,
97 network_delegate);
98 }
99
100 return new URLRequestTestDelayedCompletionJob(
101 request, network_delegate, response_headers_, response_data_);
102 }
103
104 net::URLRequestJob* MaybeInterceptRedirect(
105 net::URLRequest* request,
106 net::NetworkDelegate* network_delegate,
107 const GURL& location) const override {
108 return nullptr;
109 }
110
111 net::URLRequestJob* MaybeInterceptResponse(
112 net::URLRequest* request,
113 net::NetworkDelegate* network_delegate) const override {
114 return nullptr;
115 }
116
117 bool IsHandledProtocol(const std::string& scheme) const override {
118 return supported_schemes_.count(scheme) > 0;
119 }
120
121 bool IsHandledURL(const GURL& url) const override {
122 return supported_schemes_.count(url.scheme()) > 0;
123 }
124
125 bool IsSafeRedirectTarget(const GURL& location) const override {
126 return false;
127 }
128
129 private:
130 std::string response_headers_;
131 std::string response_data_;
132 std::set<std::string> supported_schemes_;
133 URLRequestJobCreateCallback custom_url_request_job_create_callback_;
134
135 DISALLOW_COPY_AND_ASSIGN(TestURLRequestJobFactory);
136 };
137
138 // On Windows, ResourceMsg_SetDataBuffer supplies a HANDLE which is not
139 // automatically released.
140 //
141 // See ResourceDispatcher::ReleaseResourcesInDataMessage.
142 //
143 // TODO(ricea): Maybe share this implementation with
144 // resource_dispatcher_host_unittest.cc
145 void ReleaseHandlesInMessage(const IPC::Message& message) {
146 if (message.type() == ResourceMsg_SetDataBuffer::ID) {
147 base::PickleIterator iter(message);
148 int request_id;
149 CHECK(iter.ReadInt(&request_id));
150 base::SharedMemoryHandle shm_handle;
151 if (IPC::ParamTraits<base::SharedMemoryHandle>::Read(&message, &iter,
152 &shm_handle)) {
153 if (base::SharedMemory::IsHandleValid(shm_handle))
154 base::SharedMemory::CloseHandle(shm_handle);
155 }
156 }
157 }
158
159 // This filter just deletes any messages that are sent through it.
160 class BlackholeFilter : public ResourceMessageFilter {
161 public:
162 explicit BlackholeFilter(ResourceContext* resource_context)
163 : ResourceMessageFilter(
164 ChildProcessHostImpl::GenerateChildProcessUniqueId(),
165 PROCESS_TYPE_RENDERER,
166 nullptr,
167 nullptr,
168 nullptr,
169 nullptr,
170 nullptr,
171 base::Bind(&BlackholeFilter::GetContexts, base::Unretained(this))),
172 resource_context_(resource_context) {
173 ChildProcessSecurityPolicyImpl::GetInstance()->Add(child_id());
174 }
175
176 bool Send(IPC::Message* msg) override {
177 ReleaseHandlesInMessage(*msg);
178 delete msg;
kinuko 2015/12/03 07:51:41 nit: receive msg as scoped_ptr and let it delete,
Adam Rice 2015/12/03 14:20:43 Done.
179 return true;
180 }
181
182 private:
183 ~BlackholeFilter() override {
184 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(child_id());
185 }
186
187 void GetContexts(ResourceType resource_type,
188 int origin_pid,
189 ResourceContext** resource_context,
190 net::URLRequestContext** request_context) {
191 *resource_context = resource_context_;
192 *request_context = resource_context_->GetRequestContext();
193 }
194
195 ResourceContext* resource_context_;
196
197 DISALLOW_COPY_AND_ASSIGN(BlackholeFilter);
198 };
199
200 ResourceHostMsg_Request CreateResourceRequest(const char* method,
201 ResourceType type,
202 const GURL& url) {
203 ResourceHostMsg_Request request;
204 request.method = std::string(method);
205 request.url = url;
206 request.first_party_for_cookies = url; // bypass third-party cookie blocking
207 request.referrer_policy = blink::WebReferrerPolicyDefault;
208 request.load_flags = 0;
209 request.origin_pid = 0;
210 request.resource_type = type;
211 request.request_context = 0;
212 request.appcache_host_id = kAppCacheNoHostId;
213 request.download_to_file = false;
214 request.should_reset_appcache = false;
215 request.is_main_frame = true;
216 request.parent_is_main_frame = false;
217 request.parent_render_frame_id = -1;
218 request.transition_type = ui::PAGE_TRANSITION_LINK;
219 request.allow_download = true;
220 return request;
221 }
222
223 } // namespace
224
225 class AsyncRevalidationManagerTest : public ::testing::Test {
226 protected:
227 AsyncRevalidationManagerTest(
228 scoped_ptr<net::TestNetworkDelegate> network_delegate)
229 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
230 network_delegate_(std::move(network_delegate)) {
231 browser_context_.reset(new TestBrowserContext());
232 BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
233 base::RunLoop().RunUntilIdle();
234 ResourceContext* resource_context = browser_context_->GetResourceContext();
235 filter_ = new BlackholeFilter(resource_context);
236 net::URLRequestContext* request_context =
237 resource_context->GetRequestContext();
238 job_factory_.reset(new TestURLRequestJobFactory);
239 request_context->set_job_factory(job_factory_.get());
240 request_context->set_network_delegate(network_delegate_.get());
241 host_.EnableStaleWhileRevalidateForTesting();
242 }
243
244 AsyncRevalidationManagerTest()
245 : AsyncRevalidationManagerTest(
246 make_scoped_ptr(new net::TestNetworkDelegate)) {}
247
248 void TearDown() override {
249 host_.CancelRequestsForProcess(filter_->child_id());
250 host_.Shutdown();
251 host_.CancelRequestsForContext(browser_context_->GetResourceContext());
252 browser_context_.reset();
253 base::RunLoop().RunUntilIdle();
254 }
255
256 void HandleScheme(const std::string& scheme) {
kinuko 2015/12/03 07:51:41 If we only test "http" (and it looks like the case
Adam Rice 2015/12/03 14:20:43 Thanks. This saves a lot of code.
257 job_factory_->HandleScheme(scheme);
258 EnsureSchemeIsAllowed(scheme);
259 }
260
261 void SetResponse(const std::string& headers, const std::string& data) {
262 job_factory_->SetResponse(headers, data);
263 }
264
265 void SetCustomURLRequestJobCreateCallback(
266 const TestURLRequestJobFactory::URLRequestJobCreateCallback& callback) {
267 job_factory_->SetCustomURLRequestJobCreateCallback(callback);
268 }
269
270 // Creates a request using the current test object as the filter and
271 // SubResource as the resource type.
272 void MakeTestRequest(int render_view_id, int request_id, const GURL& url) {
273 ResourceHostMsg_Request request =
274 CreateResourceRequest("GET", RESOURCE_TYPE_SUB_RESOURCE, url);
275 ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
276 host_.OnMessageReceived(msg, filter_.get());
277 base::RunLoop().RunUntilIdle();
278 }
279
280 void EnsureSchemeIsAllowed(const std::string& scheme) {
281 ChildProcessSecurityPolicyImpl* policy =
282 ChildProcessSecurityPolicyImpl::GetInstance();
283 if (!policy->IsWebSafeScheme(scheme))
284 policy->RegisterWebSafeScheme(scheme);
kinuko 2015/12/03 07:51:41 Feels a bit overkill for testing where 'scheme' is
Adam Rice 2015/12/03 14:20:43 No, you are correct. Removed.
285 }
286
287 net::TestNetworkDelegate* network_delegate() {
kinuko 2015/12/03 07:51:41 not used?
Adam Rice 2015/12/03 14:20:43 Removed.
288 return network_delegate_.get();
289 }
290
291 content::TestBrowserThreadBundle thread_bundle_;
292 scoped_ptr<TestBrowserContext> browser_context_;
293 scoped_ptr<TestURLRequestJobFactory> job_factory_;
294 scoped_refptr<BlackholeFilter> filter_;
295 scoped_ptr<net::TestNetworkDelegate> network_delegate_;
296 ResourceDispatcherHostImpl host_;
297 };
298
299 TEST_F(AsyncRevalidationManagerTest, SupportsAsyncRevalidation) {
300 // Scheme has to be HTTP or HTTPS to support async revalidation.
301 HandleScheme("http");
302 SetResponse(net::URLRequestTestJob::test_headers(), "delay complete");
303 MakeTestRequest(0, 1, GURL("http://example.com/baz"));
304
305 net::URLRequest* url_request(
306 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
307 ASSERT_TRUE(url_request);
308
309 EXPECT_TRUE(url_request->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION);
310 }
311
312 TEST_F(AsyncRevalidationManagerTest, AsyncRevalidationNotSupportedForPOST) {
313 // Scheme has to be HTTP or HTTPS to support async revalidation.
314 HandleScheme("http");
315 SetResponse(net::URLRequestTestJob::test_headers(), "delay complete");
316 // Create POST request.
317 ResourceHostMsg_Request request = CreateResourceRequest(
318 "POST", RESOURCE_TYPE_SUB_RESOURCE, GURL("http://example.com/baz.php"));
319 ResourceHostMsg_RequestResource msg(0, 1, request);
320 host_.OnMessageReceived(msg, filter_.get());
321 base::RunLoop().RunUntilIdle();
322
323 net::URLRequest* url_request(
324 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
325 ASSERT_TRUE(url_request);
326
327 EXPECT_FALSE(url_request->load_flags() &
328 net::LOAD_SUPPORT_ASYNC_REVALIDATION);
329 }
330
331 TEST_F(AsyncRevalidationManagerTest,
332 AsyncRevalidationNotSupportedAfterRedirect) {
333 static const char kRedirectHeaders[] =
334 "HTTP/1.1 302 MOVED\n"
335 "Location: http://example.com/var\n"
336 "\n";
337 // Scheme has to be HTTP or HTTPS to support async revalidation.
338 HandleScheme("http");
339 SetResponse(kRedirectHeaders, "");
340
341 MakeTestRequest(0, 1, GURL("http://example.com/baz"));
342
343 net::URLRequest* url_request(
344 host_.GetURLRequest(GlobalRequestID(filter_->child_id(), 1)));
345 ASSERT_TRUE(url_request);
346
347 EXPECT_FALSE(url_request->load_flags() &
348 net::LOAD_SUPPORT_ASYNC_REVALIDATION);
349 }
350
351 // A URLRequestJob implementation which sets the |async_revalidation_required|
352 // flag on the HttpResponseInfo object to true if the request has the
353 // LOAD_SUPPORT_ASYNC_REVALIDATION flag.
354 class AsyncRevalidationRequiredURLRequestTestJob
355 : public net::URLRequestTestJob {
356 public:
357 // The Create() method is useful for wrapping the construction of the object
358 // in a Callback.
359 static net::URLRequestJob* Create(net::URLRequest* request,
360 net::NetworkDelegate* network_delegate) {
361 return new AsyncRevalidationRequiredURLRequestTestJob(request,
362 network_delegate);
363 }
364
365 void GetResponseInfo(net::HttpResponseInfo* info) override {
366 URLRequestTestJob::GetResponseInfo(info);
367 if (request()->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION)
368 info->async_revalidation_required = true;
369 }
370
371 private:
372 AsyncRevalidationRequiredURLRequestTestJob(
373 net::URLRequest* request,
374 net::NetworkDelegate* network_delegate)
375 : URLRequestTestJob(request,
376 network_delegate,
377 net::URLRequestTestJob::test_headers(),
378 std::string(),
379 false) {}
380
381 ~AsyncRevalidationRequiredURLRequestTestJob() override {}
382
383 DISALLOW_COPY_AND_ASSIGN(AsyncRevalidationRequiredURLRequestTestJob);
384 };
385
386 // A URLRequestJob implementation which serves a redirect and sets the
387 // |async_revalidation_required| flag on the HttpResponseInfo object to true if
388 // the request has the LOAD_SUPPORT_ASYNC_REVALIDATION flag.
389 class RedirectAndRevalidateURLRequestTestJob : public net::URLRequestTestJob {
390 public:
391 // This Create() method returns a redirecting job if the URL contains the
392 // string "redirect", otherwise a AsyncRevalidationRequiredURLRequestTestJob.
393 static net::URLRequestJob* Create(net::URLRequest* request,
394 net::NetworkDelegate* network_delegate) {
395 if (request->url().spec().find("redirect") != std::string::npos) {
396 return new RedirectAndRevalidateURLRequestTestJob(request,
397 network_delegate);
398 }
399 return AsyncRevalidationRequiredURLRequestTestJob::Create(request,
400 network_delegate);
401 }
402
403 void GetResponseInfo(net::HttpResponseInfo* info) override {
404 URLRequestTestJob::GetResponseInfo(info);
405 if (request()->load_flags() & net::LOAD_SUPPORT_ASYNC_REVALIDATION)
406 info->async_revalidation_required = true;
407 }
408
409 private:
410 RedirectAndRevalidateURLRequestTestJob(net::URLRequest* request,
411 net::NetworkDelegate* network_delegate)
412 : URLRequestTestJob(request,
413 network_delegate,
414 std::string(CreateRedirectHeaders()),
415 std::string(),
416 false) {}
417
418 ~RedirectAndRevalidateURLRequestTestJob() override {}
419
420 static std::string CreateRedirectHeaders() {
421 static const char kRedirectHeaders[] =
422 "HTTP/1.1 302 MOVED\n"
423 "Location: http://example.com/var\n"
424 "\n";
425 return std::string(kRedirectHeaders, arraysize(kRedirectHeaders));
426 }
427
428 DISALLOW_COPY_AND_ASSIGN(RedirectAndRevalidateURLRequestTestJob);
429 };
430
431 // A NetworkDelegate that records the URLRequests as they are created.
432 class URLRequestRecordingNetworkDelegate : public net::TestNetworkDelegate {
433 public:
434 URLRequestRecordingNetworkDelegate() : requests_() {}
435
436 net::URLRequest* NextRequest() {
437 if (requests_.empty())
438 return nullptr;
439 net::URLRequest* request = requests_.front();
440 requests_.pop();
441 return request;
442 }
443
444 bool IsEmpty() { return requests_.empty(); }
kinuko 2015/12/03 07:51:41 nit: could be a const method
Adam Rice 2015/12/03 14:20:43 Done.
445
446 int OnBeforeURLRequest(net::URLRequest* request,
447 const net::CompletionCallback& callback,
448 GURL* new_url) override {
449 requests_.push(request);
450 return TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url);
451 }
452
453 private:
454 std::queue<net::URLRequest*> requests_;
455
456 DISALLOW_COPY_AND_ASSIGN(URLRequestRecordingNetworkDelegate);
457 };
458
459 class AsyncRevalidationManagerRecordingTest
460 : public AsyncRevalidationManagerTest {
461 public:
462 AsyncRevalidationManagerRecordingTest()
463 : AsyncRevalidationManagerTest(
464 make_scoped_ptr(new URLRequestRecordingNetworkDelegate)) {
465 // Scheme has to be HTTP or HTTPS to support async revalidation.
466 HandleScheme("http");
467 // Use the AsyncRevalidationRequiredURLRequestTestJob.
468 SetCustomURLRequestJobCreateCallback(
469 base::Bind(&AsyncRevalidationRequiredURLRequestTestJob::Create));
470 }
471
472 URLRequestRecordingNetworkDelegate* recording_network_delegate() {
473 return static_cast<URLRequestRecordingNetworkDelegate*>(network_delegate());
474 }
475
476 net::URLRequest* NextRequest() {
477 return recording_network_delegate()->NextRequest();
478 }
479
480 bool IsEmpty() { return recording_network_delegate()->IsEmpty(); }
481 };
482
483 // Verify that an async revalidation is actually created when needed.
484 TEST_F(AsyncRevalidationManagerRecordingTest, Issued) {
485 // Create the original request.
486 MakeTestRequest(0, 1, GURL("http://example.com/baz"));
487
488 net::URLRequest* initial_request = NextRequest();
489 ASSERT_TRUE(initial_request);
490 EXPECT_TRUE(initial_request->load_flags() &
491 net::LOAD_SUPPORT_ASYNC_REVALIDATION);
492
493 net::URLRequest* async_request = NextRequest();
494 ASSERT_TRUE(async_request);
495 }
496
497 // Verify the the URL of the async revalidation matches the original request.
498 TEST_F(AsyncRevalidationManagerRecordingTest, URLMatches) {
499 // Create the original request.
500 MakeTestRequest(0, 1, GURL("http://example.com/special-baz"));
501
502 // Discard the original request.
503 NextRequest();
504
505 net::URLRequest* async_request = NextRequest();
506 ASSERT_TRUE(async_request);
507 EXPECT_EQ(GURL("http://example.com/special-baz"), async_request->url());
508 }
509
510 TEST_F(AsyncRevalidationManagerRecordingTest,
511 AsyncRevalidationsDoNotSupportAsyncRevalidation) {
512 // Create the original request.
513 MakeTestRequest(0, 1, GURL("http://example.com/baz"));
514
515 // Discard the original request.
516 NextRequest();
517
518 // Get the async revalidation request.
519 net::URLRequest* async_request = NextRequest();
520 ASSERT_TRUE(async_request);
521 EXPECT_FALSE(async_request->load_flags() &
522 net::LOAD_SUPPORT_ASYNC_REVALIDATION);
523 }
524
525 TEST_F(AsyncRevalidationManagerRecordingTest, AsyncRevalidationsNotDuplicated) {
526 // Create the original request.
527 MakeTestRequest(0, 1, GURL("http://example.com/baz"));
528
529 // Discard the original request.
530 NextRequest();
531
532 // Get the async revalidation request.
533 net::URLRequest* async_request = NextRequest();
534 EXPECT_TRUE(async_request);
535
536 // Start a second request to the same URL.
537 MakeTestRequest(0, 2, GURL("http://example.com/baz"));
538
539 // Discard the second request.
540 NextRequest();
541
542 // There should not be another async revalidation request.
543 EXPECT_TRUE(IsEmpty());
544 }
545
546 // Async revalidation to different URLs should not be treated as duplicates.
547 TEST_F(AsyncRevalidationManagerRecordingTest,
548 AsyncRevalidationsToSeparateURLsAreSeparate) {
549 // Create two requests to two URLs.
550 MakeTestRequest(0, 1, GURL("http://example.com/baz"));
551 MakeTestRequest(0, 2, GURL("http://example.com/far"));
552
553 net::URLRequest* initial_request = NextRequest();
554 ASSERT_TRUE(initial_request);
555 net::URLRequest* initial_async_revalidation = NextRequest();
556 ASSERT_TRUE(initial_async_revalidation);
557 net::URLRequest* second_request = NextRequest();
558 ASSERT_TRUE(second_request);
559 net::URLRequest* second_async_revalidation = NextRequest();
560 ASSERT_TRUE(second_async_revalidation);
561
562 EXPECT_EQ("http://example.com/baz", initial_request->url().spec());
563 EXPECT_EQ("http://example.com/baz", initial_async_revalidation->url().spec());
564 EXPECT_EQ("http://example.com/far", second_request->url().spec());
565 EXPECT_EQ("http://example.com/far", second_async_revalidation->url().spec());
566 }
567
568 // A stale-while-revalidate applicable redirect response should not result in an
569 // async revalidation.
570 TEST_F(AsyncRevalidationManagerRecordingTest, InitialRedirectLegRevalidated) {
571 // Use the appropriate URLRequestJob for the test.
572 SetCustomURLRequestJobCreateCallback(
573 base::Bind(&RedirectAndRevalidateURLRequestTestJob::Create));
574 MakeTestRequest(0, 1, GURL("http://example.com/redirect"));
575
576 net::URLRequest* initial_request = NextRequest();
577 EXPECT_TRUE(initial_request);
578
579 // There should be an async revalidation request.
580 ASSERT_TRUE(NextRequest());
581 }
582
583 // Nothing after the first redirect leg has stale-while-revalidate applied.
584 // TODO(ricea): s-w-r should work with redirects. Change this test when it does.
585 TEST_F(AsyncRevalidationManagerRecordingTest, NoSWRAfterFirstRedirectLeg) {
586 SetCustomURLRequestJobCreateCallback(
587 base::Bind(&RedirectAndRevalidateURLRequestTestJob::Create));
588 MakeTestRequest(0, 1, GURL("http://example.com/redirect"));
589
590 net::URLRequest* initial_request = NextRequest();
591 EXPECT_TRUE(initial_request);
592
593 EXPECT_FALSE(initial_request->load_flags() &
594 net::LOAD_SUPPORT_ASYNC_REVALIDATION);
595
596 // An async revalidation happens for the redirect.
597 EXPECT_TRUE(NextRequest());
598
599 // But no others.
600 EXPECT_TRUE(IsEmpty());
601 }
602
603 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698