OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <set> | 5 #include <set> |
6 #include <utility> | 6 #include <utility> |
7 | 7 |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 int route_id_; | 80 int route_id_; |
81 }; | 81 }; |
82 | 82 |
83 class TestPrerenderManager : public PrerenderManager { | 83 class TestPrerenderManager : public PrerenderManager { |
84 public: | 84 public: |
85 explicit TestPrerenderManager(PrerenderTracker* prerender_tracker) : | 85 explicit TestPrerenderManager(PrerenderTracker* prerender_tracker) : |
86 PrerenderManager(NULL, prerender_tracker) { | 86 PrerenderManager(NULL, prerender_tracker) { |
87 mutable_config().rate_limit_enabled = false; | 87 mutable_config().rate_limit_enabled = false; |
88 } | 88 } |
89 | 89 |
90 virtual void DestroyPrerenderForRenderView( | |
91 int process_id, int view_id, FinalStatus final_status) OVERRIDE { | |
92 cancelled_id_pairs_.insert(std::make_pair(process_id, view_id)); | |
93 } | |
94 | |
95 // We never allocate our PrerenderContents in PrerenderManager, so we don't | 90 // We never allocate our PrerenderContents in PrerenderManager, so we don't |
96 // ever want the default pending delete behaviour. | 91 // ever want the default pending delete behaviour. |
97 virtual void MoveEntryToPendingDelete(PrerenderContents* entry, | 92 virtual void MoveEntryToPendingDelete(PrerenderContents* entry, |
98 FinalStatus final_status) OVERRIDE { | 93 FinalStatus final_status) OVERRIDE { |
99 } | 94 } |
100 | |
101 bool WasPrerenderCancelled(int child_id, int route_id) { | |
102 std::pair<int, int> child_route_id_pair(child_id, route_id); | |
103 return cancelled_id_pairs_.count(child_route_id_pair) != 0; | |
104 } | |
105 | |
106 // Set of all the RenderViews that have been cancelled. | |
107 std::set<std::pair<int, int> > cancelled_id_pairs_; | |
108 }; | 95 }; |
109 | 96 |
110 class DeferredRedirectDelegate : public net::URLRequest::Delegate, | 97 class DeferredRedirectDelegate : public net::URLRequest::Delegate, |
111 public content::ResourceController { | 98 public content::ResourceController { |
112 public: | 99 public: |
113 DeferredRedirectDelegate() | 100 DeferredRedirectDelegate() |
114 : throttle_(NULL), | 101 : throttle_(NULL), |
115 was_deferred_(false), | 102 was_deferred_(false), |
116 cancel_called_(false), | 103 cancel_called_(false), |
117 resume_called_(false) { | 104 resume_called_(false) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 } | 192 } |
206 | 193 |
207 TestPrerenderManager* prerender_manager() { | 194 TestPrerenderManager* prerender_manager() { |
208 return &prerender_manager_; | 195 return &prerender_manager_; |
209 } | 196 } |
210 | 197 |
211 TestPrerenderContents* test_contents() { | 198 TestPrerenderContents* test_contents() { |
212 return &test_contents_; | 199 return &test_contents_; |
213 } | 200 } |
214 | 201 |
215 int GetCurrentStatus(int child_id, int route_id) { | |
216 FinalStatus final_status; | |
217 if (!prerender_tracker()->GetFinalStatus(child_id, route_id, | |
218 &final_status)) { | |
219 return -1; | |
220 } | |
221 return final_status; | |
222 } | |
223 | |
224 // Runs any tasks queued on either thread. | 202 // Runs any tasks queued on either thread. |
225 void RunEvents() { | 203 void RunEvents() { |
226 message_loop_.RunUntilIdle(); | 204 message_loop_.RunUntilIdle(); |
227 } | 205 } |
228 | 206 |
229 private: | 207 private: |
230 base::MessageLoopForIO message_loop_; | 208 base::MessageLoopForIO message_loop_; |
231 content::TestBrowserThread ui_thread_; | 209 content::TestBrowserThread ui_thread_; |
232 content::TestBrowserThread io_thread_; | 210 content::TestBrowserThread io_thread_; |
233 | 211 |
234 TestPrerenderManager prerender_manager_; | 212 TestPrerenderManager prerender_manager_; |
235 TestPrerenderContents test_contents_; | 213 TestPrerenderContents test_contents_; |
236 }; | 214 }; |
237 | 215 |
238 // Check that a non-existant RenderView is handled correctly. | 216 TEST_F(PrerenderTrackerTest, IsPrerenderingOnIOThread) { |
239 TEST_F(PrerenderTrackerTest, PrerenderTrackerNull) { | |
240 EXPECT_FALSE(prerender_tracker()->TryUse(kDefaultChildId, kDefaultRouteId)); | |
241 EXPECT_FALSE(prerender_tracker()->TryCancel( | |
242 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
243 EXPECT_FALSE(prerender_tracker()->TryCancelOnIOThread( | |
244 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
245 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread( | 217 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread( |
246 kDefaultChildId, kDefaultRouteId)); | 218 kDefaultChildId, kDefaultRouteId)); |
247 FinalStatus final_status; | |
248 EXPECT_FALSE(prerender_tracker()->GetFinalStatus( | |
249 kDefaultChildId, kDefaultRouteId, &final_status)); | |
250 EXPECT_FALSE(prerender_manager()->WasPrerenderCancelled( | |
251 kDefaultChildId, kDefaultRouteId)); | |
252 } | |
253 | 219 |
254 // Check that a page that is used is handled correctly. | |
255 TEST_F(PrerenderTrackerTest, PrerenderTrackerUsed) { | |
256 test_contents()->Start(); | 220 test_contents()->Start(); |
257 | |
258 EXPECT_EQ(FINAL_STATUS_MAX, | |
259 GetCurrentStatus(kDefaultChildId, kDefaultRouteId)); | |
260 | |
261 // This calls AddPrerenderOnIOThreadTask(). | |
262 RunEvents(); | |
263 | |
264 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread( | |
265 kDefaultChildId, kDefaultRouteId)); | |
266 EXPECT_EQ(FINAL_STATUS_MAX, | |
267 GetCurrentStatus(kDefaultChildId, kDefaultRouteId)); | |
268 | |
269 // Display the prerendered RenderView. | |
270 EXPECT_TRUE(prerender_tracker()->TryUse(kDefaultChildId, kDefaultRouteId)); | |
271 | |
272 // Make sure the page can't be destroyed or claim it was destroyed after | |
273 // it's been used. | |
274 EXPECT_FALSE(prerender_tracker()->TryCancel( | |
275 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
276 EXPECT_FALSE(prerender_tracker()->TryCancelOnIOThread( | |
277 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_TIMED_OUT)); | |
278 EXPECT_EQ(FINAL_STATUS_USED, | |
279 GetCurrentStatus(kDefaultChildId, kDefaultRouteId)); | |
280 | |
281 // This would call DestroyPrerenderForChildRouteIdPair(), if the prerender | |
282 // were cancelled. | |
283 RunEvents(); | |
284 | |
285 // These functions should all behave as before. | |
286 EXPECT_FALSE(prerender_tracker()->TryCancel( | |
287 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
288 EXPECT_FALSE(prerender_tracker()->TryCancelOnIOThread( | |
289 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_TIMED_OUT)); | |
290 EXPECT_EQ(FINAL_STATUS_USED, GetCurrentStatus( | |
291 kDefaultChildId, kDefaultRouteId)); | |
292 | |
293 // This calls DestroyPrerenderForChildRouteIdPair(). | |
294 test_contents()->Use(); | |
295 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread( | |
296 kDefaultChildId, kDefaultRouteId)); | |
297 | |
298 // This calls RemovePrerenderOnIOThreadTask(). | |
299 RunEvents(); | |
300 | |
301 FinalStatus final_status; | |
302 EXPECT_FALSE(prerender_tracker()->GetFinalStatus( | |
303 kDefaultChildId, kDefaultRouteId, &final_status)); | |
304 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread( | |
305 kDefaultChildId, kDefaultRouteId)); | |
306 EXPECT_FALSE(prerender_tracker()->TryCancel( | |
307 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
308 EXPECT_FALSE(prerender_manager()->WasPrerenderCancelled( | |
309 kDefaultChildId, kDefaultRouteId)); | |
310 } | |
311 | |
312 // Check that a prerendered page cancelled by TryCancel() is handled correctly. | |
313 TEST_F(PrerenderTrackerTest, PrerenderTrackerCancelled) { | |
314 test_contents()->Start(); | |
315 EXPECT_EQ(FINAL_STATUS_MAX, | |
316 GetCurrentStatus(kDefaultChildId, kDefaultRouteId)); | |
317 | |
318 // This calls AddPrerenderOnIOThreadTask(). | |
319 RunEvents(); | |
320 | |
321 // Cancel the prerender. | |
322 EXPECT_TRUE(prerender_tracker()->TryCancel( | |
323 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
324 | |
325 EXPECT_FALSE(prerender_tracker()->TryUse(kDefaultChildId, kDefaultRouteId)); | |
326 EXPECT_TRUE(prerender_tracker()->TryCancel( | |
327 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_TIMED_OUT)); | |
328 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
329 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_TIMED_OUT)); | |
330 EXPECT_EQ(FINAL_STATUS_CANCELLED, | |
331 GetCurrentStatus(kDefaultChildId, kDefaultRouteId)); | |
332 | |
333 // This calls DestroyPrerenderForChildRouteIdPair(). | |
334 RunEvents(); | |
335 EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled( | |
336 kDefaultChildId, kDefaultRouteId)); | |
337 | |
338 // These should all work until the prerendering RenderViewHost is destroyed. | |
339 EXPECT_TRUE(prerender_tracker()->TryCancel( | |
340 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_TIMED_OUT)); | |
341 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
342 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_TIMED_OUT)); | |
343 EXPECT_EQ(FINAL_STATUS_CANCELLED, | |
344 GetCurrentStatus(kDefaultChildId, kDefaultRouteId)); | |
345 | |
346 test_contents()->Cancel(); | |
347 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread( | |
348 kDefaultChildId, kDefaultRouteId)); | |
349 | |
350 // This calls RemovePrerenderOnIOThreadTask(). | |
351 RunEvents(); | |
352 | |
353 FinalStatus final_status; | |
354 EXPECT_FALSE(prerender_tracker()->GetFinalStatus( | |
355 kDefaultChildId, kDefaultRouteId, &final_status)); | |
356 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread( | |
357 kDefaultChildId, kDefaultRouteId)); | |
358 } | |
359 | |
360 // Check that a prerendered page cancelled on the IO thread by | |
361 // TryCancelOnIOThread() is handled correctly. | |
362 TEST_F(PrerenderTrackerTest, PrerenderTrackerCancelledOnIO) { | |
363 test_contents()->Start(); | |
364 EXPECT_EQ(FINAL_STATUS_MAX, | |
365 GetCurrentStatus(kDefaultChildId, kDefaultRouteId)); | |
366 | |
367 // This calls AddPrerenderOnIOThreadTask(). | |
368 RunEvents(); | |
369 | |
370 // Cancel the prerender. | |
371 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
372 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_TIMED_OUT)); | |
373 | |
374 EXPECT_FALSE(prerender_tracker()->TryUse(kDefaultChildId, kDefaultRouteId)); | |
375 EXPECT_TRUE(prerender_tracker()->TryCancel(kDefaultChildId, kDefaultRouteId, | |
376 FINAL_STATUS_CANCELLED)); | |
377 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
378 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
379 EXPECT_EQ(FINAL_STATUS_TIMED_OUT, | |
380 GetCurrentStatus(kDefaultChildId, kDefaultRouteId)); | |
381 | |
382 // This calls DestroyPrerenderForChildRouteIdPair(). | |
383 RunEvents(); | |
384 EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled( | |
385 kDefaultChildId, kDefaultRouteId)); | |
386 | |
387 // These should all work until the prerendering RenderViewHost is destroyed. | |
388 EXPECT_TRUE(prerender_tracker()->TryCancel( | |
389 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
390 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
391 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
392 EXPECT_EQ(FINAL_STATUS_TIMED_OUT, | |
393 GetCurrentStatus(kDefaultChildId, kDefaultRouteId)); | |
394 | |
395 test_contents()->Cancel(); | |
396 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread( | |
397 kDefaultChildId, kDefaultRouteId)); | |
398 | |
399 // This calls RemovePrerenderOnIOThreadTask(). | |
400 RunEvents(); | |
401 | |
402 FinalStatus final_status; | |
403 EXPECT_FALSE(prerender_tracker()->GetFinalStatus( | |
404 kDefaultChildId, kDefaultRouteId, &final_status)); | |
405 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread( | |
406 kDefaultChildId, kDefaultRouteId)); | |
407 } | |
408 | |
409 // Check that a prerendered page cancelled before it reaches the IO thread is | |
410 // handled correctly. | |
411 TEST_F(PrerenderTrackerTest, PrerenderTrackerCancelledFast) { | |
412 test_contents()->Start(); | |
413 | |
414 // Cancel the prerender. | |
415 EXPECT_TRUE(prerender_tracker()->TryCancel( | |
416 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
417 | |
418 EXPECT_FALSE(prerender_tracker()->TryUse(kDefaultChildId, kDefaultRouteId)); | |
419 EXPECT_TRUE(prerender_tracker()->TryCancel( | |
420 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_TIMED_OUT)); | |
421 | |
422 // This calls AddPrerenderOnIOThreadTask() and | |
423 // DestroyPrerenderForChildRouteIdPair(). | |
424 RunEvents(); | |
425 EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled( | |
426 kDefaultChildId, kDefaultRouteId)); | |
427 | |
428 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
429 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_TIMED_OUT)); | |
430 EXPECT_TRUE(prerender_tracker()->TryCancel( | |
431 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_TIMED_OUT)); | |
432 EXPECT_EQ(FINAL_STATUS_CANCELLED, GetCurrentStatus( | |
433 kDefaultChildId, kDefaultRouteId)); | |
434 | |
435 test_contents()->Cancel(); | |
436 | |
437 // This calls RemovePrerenderOnIOThreadTask(). | |
438 RunEvents(); | |
439 | |
440 FinalStatus final_status; | |
441 EXPECT_FALSE(prerender_tracker()->GetFinalStatus( | |
442 kDefaultChildId, kDefaultRouteId, &final_status)); | |
443 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread( | |
444 kDefaultChildId, kDefaultRouteId)); | |
445 } | |
446 | |
447 // Check that handling two pages at once works. | |
448 TEST_F(PrerenderTrackerTest, PrerenderTrackerMultiple) { | |
449 test_contents()->Start(); | |
450 | |
451 // This calls AddPrerenderOnIOThreadTask(). | 221 // This calls AddPrerenderOnIOThreadTask(). |
452 RunEvents(); | 222 RunEvents(); |
453 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread( | 223 EXPECT_TRUE(prerender_tracker()->IsPrerenderingOnIOThread( |
454 kDefaultChildId, kDefaultRouteId)); | 224 kDefaultChildId, kDefaultRouteId)); |
455 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread( | |
456 kDefaultChildId + 1, kDefaultRouteId + 1)); | |
457 EXPECT_FALSE(prerender_tracker()->TryUse( | |
458 kDefaultChildId + 1, kDefaultRouteId + 1)); | |
459 EXPECT_FALSE(prerender_tracker()->TryCancel( | |
460 kDefaultChildId + 1, kDefaultRouteId + 1, FINAL_STATUS_CANCELLED)); | |
461 | |
462 // Start second prerender. | |
463 TestPrerenderContents second_test_contents(prerender_manager(), | |
464 kDefaultChildId + 1, | |
465 kDefaultRouteId + 1); | |
466 | |
467 second_test_contents.Start(); | |
468 // This calls AddPrerenderOnIOThreadTask(). | |
469 RunEvents(); | |
470 | |
471 // Use (kDefaultChildId, kDefaultRouteId). | |
472 EXPECT_TRUE(prerender_tracker()->TryUse(kDefaultChildId, kDefaultRouteId)); | |
473 EXPECT_EQ(FINAL_STATUS_USED, GetCurrentStatus( | |
474 kDefaultChildId, kDefaultRouteId)); | |
475 EXPECT_EQ(FINAL_STATUS_MAX, | |
476 GetCurrentStatus(kDefaultChildId + 1, kDefaultRouteId + 1)); | |
477 | |
478 // Cancel (kDefaultChildId + 1, kDefaultRouteId + 1). | |
479 EXPECT_TRUE(prerender_tracker()->TryCancelOnIOThread( | |
480 kDefaultChildId + 1, kDefaultRouteId + 1, FINAL_STATUS_CANCELLED)); | |
481 | |
482 EXPECT_FALSE(prerender_tracker()->TryCancel( | |
483 kDefaultChildId, kDefaultRouteId, FINAL_STATUS_CANCELLED)); | |
484 EXPECT_EQ(FINAL_STATUS_USED, | |
485 GetCurrentStatus(kDefaultChildId, kDefaultRouteId)); | |
486 | |
487 EXPECT_FALSE(prerender_tracker()->TryUse( | |
488 kDefaultChildId + 1, kDefaultRouteId + 1)); | |
489 EXPECT_TRUE(prerender_tracker()->TryCancel( | |
490 kDefaultChildId + 1, kDefaultRouteId + 1, FINAL_STATUS_CANCELLED)); | |
491 EXPECT_EQ(FINAL_STATUS_CANCELLED, | |
492 GetCurrentStatus(kDefaultChildId + 1, kDefaultRouteId + 1)); | |
493 | |
494 // This calls DestroyPrerenderForChildRouteIdPair(). | |
495 RunEvents(); | |
496 EXPECT_FALSE(prerender_manager()->WasPrerenderCancelled(kDefaultChildId, | |
497 kDefaultRouteId)); | |
498 EXPECT_TRUE(prerender_manager()->WasPrerenderCancelled(kDefaultChildId + 1, | |
499 kDefaultRouteId + 1)); | |
500 | 225 |
501 test_contents()->Cancel(); | 226 test_contents()->Cancel(); |
502 second_test_contents.Cancel(); | |
503 | |
504 // This calls RemovePrerenderOnIOThreadTask(). | 227 // This calls RemovePrerenderOnIOThreadTask(). |
505 RunEvents(); | 228 RunEvents(); |
506 | |
507 FinalStatus final_status; | |
508 EXPECT_FALSE(prerender_tracker()->GetFinalStatus( | |
509 kDefaultChildId, kDefaultRouteId, &final_status)); | |
510 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread( | 229 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread( |
511 kDefaultChildId, kDefaultRouteId)); | 230 kDefaultChildId, kDefaultRouteId)); |
512 | |
513 EXPECT_FALSE(prerender_tracker()->GetFinalStatus( | |
514 kDefaultChildId + 1, kDefaultRouteId + 1, &final_status)); | |
515 EXPECT_FALSE(prerender_tracker()->IsPrerenderingOnIOThread( | |
516 kDefaultChildId + 1, kDefaultRouteId + 1)); | |
517 } | 231 } |
518 | 232 |
519 // Checks that deferred redirects are throttled and resumed correctly. | 233 // Checks that deferred redirects are throttled and resumed correctly. |
520 TEST_F(PrerenderTrackerTest, PrerenderThrottledRedirectResume) { | 234 TEST_F(PrerenderTrackerTest, PrerenderThrottledRedirectResume) { |
521 const base::FilePath::CharType kRedirectPath[] = | 235 const base::FilePath::CharType kRedirectPath[] = |
522 FILE_PATH_LITERAL("prerender/image-deferred.png"); | 236 FILE_PATH_LITERAL("prerender/image-deferred.png"); |
523 | 237 |
524 test_contents()->Start(); | 238 test_contents()->Start(); |
525 // This calls AddPrerenderOnIOThreadTask(). | 239 // This calls AddPrerenderOnIOThreadTask(). |
526 RunEvents(); | 240 RunEvents(); |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 // We should have cancelled the prerender. | 390 // We should have cancelled the prerender. |
677 EXPECT_EQ(FINAL_STATUS_BAD_DEFERRED_REDIRECT, | 391 EXPECT_EQ(FINAL_STATUS_BAD_DEFERRED_REDIRECT, |
678 test_contents()->final_status()); | 392 test_contents()->final_status()); |
679 | 393 |
680 // Cleanup work so the prerender is gone. | 394 // Cleanup work so the prerender is gone. |
681 test_contents()->Cancel(); | 395 test_contents()->Cancel(); |
682 RunEvents(); | 396 RunEvents(); |
683 } | 397 } |
684 | 398 |
685 } // namespace prerender | 399 } // namespace prerender |
OLD | NEW |