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 "base/callback.h" | 5 #include "base/callback.h" |
6 #include "base/feature_list.h" | 6 #include "base/feature_list.h" |
7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "base/threading/thread.h" | 9 #include "base/threading/thread.h" |
10 #include "content/browser/byte_stream.h" | 10 #include "content/browser/byte_stream.h" |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 } | 284 } |
285 | 285 |
286 // Cleanup a download item (specifically get rid of the DownloadFile on it). | 286 // Cleanup a download item (specifically get rid of the DownloadFile on it). |
287 // The item must be in the expected state. | 287 // The item must be in the expected state. |
288 void CleanupItem(DownloadItemImpl* item, | 288 void CleanupItem(DownloadItemImpl* item, |
289 MockDownloadFile* download_file, | 289 MockDownloadFile* download_file, |
290 DownloadItem::DownloadState expected_state) { | 290 DownloadItem::DownloadState expected_state) { |
291 EXPECT_EQ(expected_state, item->GetState()); | 291 EXPECT_EQ(expected_state, item->GetState()); |
292 | 292 |
293 if (expected_state == DownloadItem::IN_PROGRESS) { | 293 if (expected_state == DownloadItem::IN_PROGRESS) { |
294 if (download_file) | 294 EXPECT_CALL(*download_file, Cancel()); |
295 EXPECT_CALL(*download_file, Cancel()); | |
296 item->Cancel(true); | 295 item->Cancel(true); |
297 loop_.RunUntilIdle(); | 296 loop_.RunUntilIdle(); |
298 } | 297 } |
299 } | 298 } |
300 | 299 |
301 // Destroy a previously created download item. | 300 // Destroy a previously created download item. |
302 void DestroyDownloadItem(DownloadItem* item) { | 301 void DestroyDownloadItem(DownloadItem* item) { |
303 allocated_downloads_.erase(item); | 302 allocated_downloads_.erase(item); |
304 delete item; | 303 delete item; |
305 } | 304 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 // Interrupt the download, using a continuable interrupt. | 413 // Interrupt the download, using a continuable interrupt. |
415 EXPECT_CALL(*download_file, FullPath()) | 414 EXPECT_CALL(*download_file, FullPath()) |
416 .WillOnce(Return(base::FilePath())); | 415 .WillOnce(Return(base::FilePath())); |
417 EXPECT_CALL(*download_file, Detach()); | 416 EXPECT_CALL(*download_file, Detach()); |
418 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | 417 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
419 .WillRepeatedly(Return(&test_browser_context)); | 418 .WillRepeatedly(Return(&test_browser_context)); |
420 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1); | 419 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1); |
421 item->DestinationObserverAsWeakPtr()->DestinationError( | 420 item->DestinationObserverAsWeakPtr()->DestinationError( |
422 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 421 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
423 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 422 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
424 // Since the download is resumed automatically, the interrupt count doesn't | 423 ASSERT_EQ(1, observer.interrupt_count()); |
425 // increase. | |
426 ASSERT_EQ(0, observer.interrupt_count()); | |
427 | 424 |
428 // Test expectations verify that ResumeInterruptedDownload() is called (by way | 425 // Test expectations verify that ResumeInterruptedDownload() is called (by way |
429 // of MockResumeInterruptedDownload) after the download is interrupted. But | 426 // of MockResumeInterruptedDownload) after the download is interrupted. But |
430 // the mock doesn't follow through with the resumption. | 427 // the mock doesn't follow through with the resumption. |
431 // ResumeInterruptedDownload() being called is sufficient for verifying that | 428 // ResumeInterruptedDownload() being called is sufficient for verifying that |
432 // the automatic resumption was triggered. | 429 // the automatic resumption was triggered. |
433 RunAllPendingInMessageLoops(); | 430 RunAllPendingInMessageLoops(); |
434 | 431 |
435 // The download item is currently in RESUMING_INTERNAL state, which maps to | 432 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); |
436 // IN_PROGRESS. | |
437 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); | |
438 } | 433 } |
439 | 434 |
440 // Same as above, but with a non-continuable interrupt. | 435 // Same as above, but with a non-continuable interrupt. |
441 TEST_F(DownloadItemTest, RestartAfterInterrupted) { | 436 TEST_F(DownloadItemTest, RestartAfterInterrupted) { |
442 DownloadItemImpl* item = CreateDownloadItem(); | 437 DownloadItemImpl* item = CreateDownloadItem(); |
443 TestDownloadItemObserver observer(item); | 438 TestDownloadItemObserver observer(item); |
444 MockDownloadFile* download_file = | 439 MockDownloadFile* download_file = |
445 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 440 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
446 | 441 |
447 // Interrupt the download, using a restartable interrupt. | 442 // Interrupt the download, using a restartable interrupt. |
448 EXPECT_CALL(*download_file, Cancel()); | 443 EXPECT_CALL(*download_file, Cancel()); |
449 item->DestinationObserverAsWeakPtr()->DestinationError( | 444 item->DestinationObserverAsWeakPtr()->DestinationError( |
450 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 445 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
451 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 446 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
452 // Should not try to auto-resume. | 447 // Should not try to auto-resume. |
453 ASSERT_EQ(1, observer.interrupt_count()); | 448 ASSERT_EQ(1, observer.interrupt_count()); |
454 ASSERT_EQ(0, observer.resume_count()); | 449 ASSERT_EQ(0, observer.resume_count()); |
455 RunAllPendingInMessageLoops(); | 450 RunAllPendingInMessageLoops(); |
456 | 451 |
457 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); | 452 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); |
458 } | 453 } |
459 | 454 |
460 // Check we do correct cleanup for RESUME_MODE_INVALID interrupts. | 455 // Check we do correct cleanup for RESUME_MODE_INVALID interrupts. |
461 TEST_F(DownloadItemTest, UnresumableInterrupt) { | 456 TEST_F(DownloadItemTest, UnresumableInterrupt) { |
462 DownloadItemImpl* item = CreateDownloadItem(); | 457 DownloadItemImpl* item = CreateDownloadItem(); |
463 TestDownloadItemObserver observer(item); | 458 TestDownloadItemObserver observer(item); |
464 MockDownloadFile* download_file = | 459 MockDownloadFile* download_file = |
465 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 460 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
466 | 461 |
467 // Fail final rename with unresumable reason. | 462 // Fail final rename with unresumable reason. |
468 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) | 463 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
469 .WillOnce(Return(true)); | 464 .WillOnce(Return(true)); |
470 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) | 465 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) |
471 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, | 466 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, |
472 base::FilePath(kDummyPath))); | 467 base::FilePath(kDummyPath))); |
473 EXPECT_CALL(*download_file, Cancel()); | 468 EXPECT_CALL(*download_file, Cancel()); |
474 | 469 |
475 // Complete download to trigger final rename. | 470 // Complete download to trigger final rename. |
476 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); | 471 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); |
477 RunAllPendingInMessageLoops(); | 472 RunAllPendingInMessageLoops(); |
478 | 473 |
479 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 474 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
480 // Should not try to auto-resume. | 475 // Should not try to auto-resume. |
481 ASSERT_EQ(1, observer.interrupt_count()); | 476 ASSERT_EQ(1, observer.interrupt_count()); |
482 ASSERT_EQ(0, observer.resume_count()); | 477 ASSERT_EQ(0, observer.resume_count()); |
483 | 478 |
484 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); | 479 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); |
485 } | 480 } |
486 | 481 |
487 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) { | 482 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) { |
488 TestBrowserContext test_browser_context; | 483 TestBrowserContext test_browser_context; |
489 DownloadItemImpl* item = CreateDownloadItem(); | 484 DownloadItemImpl* item = CreateDownloadItem(); |
490 base::WeakPtr<DownloadDestinationObserver> as_observer( | 485 base::WeakPtr<DownloadDestinationObserver> as_observer( |
491 item->DestinationObserverAsWeakPtr()); | 486 item->DestinationObserverAsWeakPtr()); |
492 TestDownloadItemObserver observer(item); | 487 TestDownloadItemObserver observer(item); |
493 MockDownloadFile* mock_download_file(NULL); | 488 MockDownloadFile* mock_download_file(NULL); |
494 scoped_ptr<DownloadFile> download_file; | 489 scoped_ptr<DownloadFile> download_file; |
(...skipping 27 matching lines...) Expand all Loading... |
522 base::FilePath target_path(kDummyPath); | 517 base::FilePath target_path(kDummyPath); |
523 base::FilePath intermediate_path( | 518 base::FilePath intermediate_path( |
524 target_path.InsertBeforeExtensionASCII("x")); | 519 target_path.InsertBeforeExtensionASCII("x")); |
525 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) | 520 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) |
526 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 521 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
527 intermediate_path)); | 522 intermediate_path)); |
528 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 523 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
529 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); | 524 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); |
530 RunAllPendingInMessageLoops(); | 525 RunAllPendingInMessageLoops(); |
531 } | 526 } |
| 527 ASSERT_EQ(i, observer.resume_count()); |
532 | 528 |
533 // Use a continuable interrupt. | 529 // Use a continuable interrupt. |
534 item->DestinationObserverAsWeakPtr()->DestinationError( | 530 item->DestinationObserverAsWeakPtr()->DestinationError( |
535 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 531 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
536 | 532 |
| 533 ASSERT_EQ(i + 1, observer.interrupt_count()); |
537 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); | 534 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); |
538 } | 535 } |
539 | 536 |
540 EXPECT_EQ(1, observer.interrupt_count()); | 537 CleanupItem(item, mock_download_file, DownloadItem::INTERRUPTED); |
541 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); | |
542 } | 538 } |
543 | 539 |
544 // Test that resumption uses the final URL in a URL chain when resuming. | 540 // Test that resumption uses the final URL in a URL chain when resuming. |
545 TEST_F(DownloadItemTest, ResumeUsingFinalURL) { | 541 TEST_F(DownloadItemTest, ResumeUsingFinalURL) { |
546 TestBrowserContext test_browser_context; | 542 TestBrowserContext test_browser_context; |
547 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo); | 543 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo); |
548 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); | 544 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); |
549 create_info->save_info->prompt_for_save_location = false; | 545 create_info->save_info->prompt_for_save_location = false; |
550 create_info->etag = "SomethingToSatisfyResumption"; | 546 create_info->etag = "SomethingToSatisfyResumption"; |
551 create_info->url_chain.push_back(GURL("http://example.com/a")); | 547 create_info->url_chain.push_back(GURL("http://example.com/a")); |
(...skipping 10 matching lines...) Expand all Loading... |
562 EXPECT_CALL(*download_file, Detach()); | 558 EXPECT_CALL(*download_file, Detach()); |
563 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | 559 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
564 .WillRepeatedly(Return(&test_browser_context)); | 560 .WillRepeatedly(Return(&test_browser_context)); |
565 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( | 561 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( |
566 Property(&DownloadUrlParameters::url, | 562 Property(&DownloadUrlParameters::url, |
567 GURL("http://example.com/c")), | 563 GURL("http://example.com/c")), |
568 _)) | 564 _)) |
569 .Times(1); | 565 .Times(1); |
570 item->DestinationObserverAsWeakPtr()->DestinationError( | 566 item->DestinationObserverAsWeakPtr()->DestinationError( |
571 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 567 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
| 568 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 569 ASSERT_EQ(1, observer.interrupt_count()); |
572 | 570 |
573 // Test expectations verify that ResumeInterruptedDownload() is called (by way | 571 // Test expectations verify that ResumeInterruptedDownload() is called (by way |
574 // of MockResumeInterruptedDownload) after the download is interrupted. But | 572 // of MockResumeInterruptedDownload) after the download is interrupted. But |
575 // the mock doesn't follow through with the resumption. | 573 // the mock doesn't follow through with the resumption. |
576 // ResumeInterruptedDownload() being called is sufficient for verifying that | 574 // ResumeInterruptedDownload() being called is sufficient for verifying that |
577 // the resumption was triggered. | 575 // the resumption was triggered. |
578 RunAllPendingInMessageLoops(); | 576 RunAllPendingInMessageLoops(); |
579 | 577 |
580 // The download is currently in RESUMING_INTERNAL, which maps to IN_PROGRESS. | 578 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); |
581 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); | |
582 } | 579 } |
583 | 580 |
584 TEST_F(DownloadItemTest, NotificationAfterRemove) { | 581 TEST_F(DownloadItemTest, NotificationAfterRemove) { |
585 DownloadItemImpl* item = CreateDownloadItem(); | 582 DownloadItemImpl* item = CreateDownloadItem(); |
586 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL); | 583 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL); |
587 EXPECT_CALL(*download_file, Cancel()); | 584 EXPECT_CALL(*download_file, Cancel()); |
588 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); | 585 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); |
589 TestDownloadItemObserver observer(item); | 586 TestDownloadItemObserver observer(item); |
590 | 587 |
591 item->Remove(); | 588 item->Remove(); |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1312 base::Unretained(&returned_path))); | 1309 base::Unretained(&returned_path))); |
1313 RunAllPendingInMessageLoops(); | 1310 RunAllPendingInMessageLoops(); |
1314 EXPECT_TRUE(returned_path.empty()); | 1311 EXPECT_TRUE(returned_path.empty()); |
1315 } | 1312 } |
1316 | 1313 |
1317 TEST(MockDownloadItem, Compiles) { | 1314 TEST(MockDownloadItem, Compiles) { |
1318 MockDownloadItem mock_item; | 1315 MockDownloadItem mock_item; |
1319 } | 1316 } |
1320 | 1317 |
1321 } // namespace content | 1318 } // namespace content |
OLD | NEW |