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