| 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/command_line.h" | 6 #include "base/command_line.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" |
| 11 #include "content/browser/download/download_create_info.h" | 11 #include "content/browser/download/download_create_info.h" |
| 12 #include "content/browser/download/download_file_factory.h" | 12 #include "content/browser/download/download_file_factory.h" |
| 13 #include "content/browser/download/download_item_impl.h" | 13 #include "content/browser/download/download_item_impl.h" |
| 14 #include "content/browser/download/download_item_impl_delegate.h" | 14 #include "content/browser/download/download_item_impl_delegate.h" |
| 15 #include "content/browser/download/download_request_handle.h" | 15 #include "content/browser/download/download_request_handle.h" |
| 16 #include "content/browser/download/mock_download_file.h" | 16 #include "content/browser/download/mock_download_file.h" |
| 17 #include "content/public/browser/download_destination_observer.h" | 17 #include "content/public/browser/download_destination_observer.h" |
| 18 #include "content/public/browser/download_interrupt_reasons.h" | 18 #include "content/public/browser/download_interrupt_reasons.h" |
| 19 #include "content/public/browser/download_url_parameters.h" | 19 #include "content/public/browser/download_url_parameters.h" |
| 20 #include "content/public/common/content_switches.h" | 20 #include "content/public/common/content_switches.h" |
| 21 #include "content/public/test/mock_download_item.h" | 21 #include "content/public/test/mock_download_item.h" |
| 22 #include "content/public/test/test_browser_context.h" |
| 22 #include "content/public/test/test_browser_thread.h" | 23 #include "content/public/test/test_browser_thread.h" |
| 23 #include "testing/gmock/include/gmock/gmock.h" | 24 #include "testing/gmock/include/gmock/gmock.h" |
| 24 #include "testing/gtest/include/gtest/gtest.h" | 25 #include "testing/gtest/include/gtest/gtest.h" |
| 25 | 26 |
| 26 using ::testing::_; | 27 using ::testing::_; |
| 27 using ::testing::NiceMock; | 28 using ::testing::NiceMock; |
| 28 using ::testing::Property; | 29 using ::testing::Property; |
| 29 using ::testing::Return; | 30 using ::testing::Return; |
| 30 using ::testing::SaveArg; | 31 using ::testing::SaveArg; |
| 31 using ::testing::StrictMock; | 32 using ::testing::StrictMock; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 53 MOCK_METHOD1(ShouldOpenFileBasedOnExtension, bool(const base::FilePath&)); | 54 MOCK_METHOD1(ShouldOpenFileBasedOnExtension, bool(const base::FilePath&)); |
| 54 MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*)); | 55 MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*)); |
| 55 | 56 |
| 56 void ResumeInterruptedDownload( | 57 void ResumeInterruptedDownload( |
| 57 scoped_ptr<DownloadUrlParameters> params, uint32 id) override { | 58 scoped_ptr<DownloadUrlParameters> params, uint32 id) override { |
| 58 MockResumeInterruptedDownload(params.get(), id); | 59 MockResumeInterruptedDownload(params.get(), id); |
| 59 } | 60 } |
| 60 MOCK_METHOD2(MockResumeInterruptedDownload, | 61 MOCK_METHOD2(MockResumeInterruptedDownload, |
| 61 void(DownloadUrlParameters* params, uint32 id)); | 62 void(DownloadUrlParameters* params, uint32 id)); |
| 62 | 63 |
| 63 BrowserContext* GetBrowserContext() const override { return nullptr; } | 64 MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*()); |
| 64 MOCK_METHOD1(UpdatePersistence, void(DownloadItemImpl*)); | 65 MOCK_METHOD1(UpdatePersistence, void(DownloadItemImpl*)); |
| 65 MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*)); | 66 MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*)); |
| 66 MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*)); | 67 MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*)); |
| 67 MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*)); | 68 MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*)); |
| 68 | 69 |
| 69 void VerifyAndClearExpectations() { | 70 void VerifyAndClearExpectations() { |
| 70 ::testing::Mock::VerifyAndClearExpectations(this); | 71 ::testing::Mock::VerifyAndClearExpectations(this); |
| 71 SetDefaultExpectations(); | 72 SetDefaultExpectations(); |
| 72 } | 73 } |
| 73 | 74 |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 MockObserver observer(item); | 405 MockObserver observer(item); |
| 405 | 406 |
| 406 DestroyDownloadItem(item); | 407 DestroyDownloadItem(item); |
| 407 ASSERT_TRUE(observer.CheckDestroyed()); | 408 ASSERT_TRUE(observer.CheckDestroyed()); |
| 408 } | 409 } |
| 409 | 410 |
| 410 TEST_F(DownloadItemTest, ContinueAfterInterrupted) { | 411 TEST_F(DownloadItemTest, ContinueAfterInterrupted) { |
| 411 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 412 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 412 switches::kEnableDownloadResumption); | 413 switches::kEnableDownloadResumption); |
| 413 | 414 |
| 415 TestBrowserContext test_browser_context; |
| 414 DownloadItemImpl* item = CreateDownloadItem(); | 416 DownloadItemImpl* item = CreateDownloadItem(); |
| 415 MockObserver observer(item); | 417 MockObserver observer(item); |
| 416 DownloadItemImplDelegate::DownloadTargetCallback callback; | 418 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 417 MockDownloadFile* download_file = | 419 MockDownloadFile* download_file = |
| 418 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 420 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 419 | 421 |
| 420 // Interrupt the download, using a continuable interrupt. | 422 // Interrupt the download, using a continuable interrupt. |
| 421 EXPECT_CALL(*download_file, FullPath()) | 423 EXPECT_CALL(*download_file, FullPath()) |
| 422 .WillOnce(Return(base::FilePath())); | 424 .WillOnce(Return(base::FilePath())); |
| 423 EXPECT_CALL(*download_file, Detach()); | 425 EXPECT_CALL(*download_file, Detach()); |
| 426 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
| 427 .WillRepeatedly(Return(&test_browser_context)); |
| 428 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1); |
| 424 item->DestinationObserverAsWeakPtr()->DestinationError( | 429 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 425 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 430 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
| 426 ASSERT_TRUE(observer.CheckUpdated()); | 431 ASSERT_TRUE(observer.CheckUpdated()); |
| 427 // Should attempt to auto-resume. Because we don't have a mock WebContents, | |
| 428 // ResumeInterruptedDownload() will abort early, with another interrupt, | |
| 429 // which will be ignored. | |
| 430 ASSERT_EQ(1, observer.GetInterruptCount()); | 432 ASSERT_EQ(1, observer.GetInterruptCount()); |
| 431 ASSERT_EQ(0, observer.GetResumeCount()); | 433 |
| 434 // Test expectations verify that ResumeInterruptedDownload() is called (by way |
| 435 // of MockResumeInterruptedDownload) after the download is interrupted. But |
| 436 // the mock doesn't follow through with the resumption. |
| 437 // ResumeInterruptedDownload() being called is sufficient for verifying that |
| 438 // the automatic resumption was triggered. |
| 432 RunAllPendingInMessageLoops(); | 439 RunAllPendingInMessageLoops(); |
| 433 | 440 |
| 434 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); | 441 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); |
| 435 } | 442 } |
| 436 | 443 |
| 437 // Same as above, but with a non-continuable interrupt. | 444 // Same as above, but with a non-continuable interrupt. |
| 438 TEST_F(DownloadItemTest, RestartAfterInterrupted) { | 445 TEST_F(DownloadItemTest, RestartAfterInterrupted) { |
| 439 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 446 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 440 switches::kEnableDownloadResumption); | 447 switches::kEnableDownloadResumption); |
| 441 | 448 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 ASSERT_EQ(1, observer.GetInterruptCount()); | 493 ASSERT_EQ(1, observer.GetInterruptCount()); |
| 487 ASSERT_EQ(0, observer.GetResumeCount()); | 494 ASSERT_EQ(0, observer.GetResumeCount()); |
| 488 | 495 |
| 489 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); | 496 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); |
| 490 } | 497 } |
| 491 | 498 |
| 492 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) { | 499 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) { |
| 493 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 500 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 494 switches::kEnableDownloadResumption); | 501 switches::kEnableDownloadResumption); |
| 495 | 502 |
| 503 TestBrowserContext test_browser_context; |
| 496 DownloadItemImpl* item = CreateDownloadItem(); | 504 DownloadItemImpl* item = CreateDownloadItem(); |
| 497 base::WeakPtr<DownloadDestinationObserver> as_observer( | 505 base::WeakPtr<DownloadDestinationObserver> as_observer( |
| 498 item->DestinationObserverAsWeakPtr()); | 506 item->DestinationObserverAsWeakPtr()); |
| 499 MockObserver observer(item); | 507 MockObserver observer(item); |
| 500 MockDownloadFile* mock_download_file(NULL); | 508 MockDownloadFile* mock_download_file(NULL); |
| 501 scoped_ptr<DownloadFile> download_file; | 509 scoped_ptr<DownloadFile> download_file; |
| 502 MockRequestHandle* mock_request_handle(NULL); | 510 MockRequestHandle* mock_request_handle(NULL); |
| 503 scoped_ptr<DownloadRequestHandleInterface> request_handle; | 511 scoped_ptr<DownloadRequestHandleInterface> request_handle; |
| 504 DownloadItemImplDelegate::DownloadTargetCallback callback; | 512 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 505 | 513 |
| 506 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) | 514 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) |
| 507 .WillRepeatedly(SaveArg<1>(&callback)); | 515 .WillRepeatedly(SaveArg<1>(&callback)); |
| 516 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
| 517 .WillRepeatedly(Return(&test_browser_context)); |
| 518 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)) |
| 519 .Times(DownloadItemImpl::kMaxAutoResumeAttempts); |
| 508 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { | 520 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { |
| 509 DVLOG(20) << "Loop iteration " << i; | 521 DVLOG(20) << "Loop iteration " << i; |
| 510 | 522 |
| 511 mock_download_file = new NiceMock<MockDownloadFile>; | 523 mock_download_file = new NiceMock<MockDownloadFile>; |
| 512 download_file.reset(mock_download_file); | 524 download_file.reset(mock_download_file); |
| 513 mock_request_handle = new NiceMock<MockRequestHandle>; | 525 mock_request_handle = new NiceMock<MockRequestHandle>; |
| 514 request_handle.reset(mock_request_handle); | 526 request_handle.reset(mock_request_handle); |
| 515 | 527 |
| 516 ON_CALL(*mock_download_file, FullPath()) | 528 ON_CALL(*mock_download_file, FullPath()) |
| 517 .WillByDefault(Return(base::FilePath())); | 529 .WillByDefault(Return(base::FilePath())); |
| 518 | 530 |
| 519 // It's too complicated to set up a WebContents instance that would cause | |
| 520 // the MockDownloadItemDelegate's ResumeInterruptedDownload() function | |
| 521 // to be callled, so we simply verify that GetWebContents() is called. | |
| 522 if (i < (DownloadItemImpl::kMaxAutoResumeAttempts - 1)) { | |
| 523 EXPECT_CALL(*mock_request_handle, GetWebContents()) | |
| 524 .WillRepeatedly(Return(static_cast<WebContents*>(NULL))); | |
| 525 } | |
| 526 | |
| 527 // Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem | 531 // Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem |
| 528 // to allow for holding onto the request handle. | 532 // to allow for holding onto the request handle. |
| 529 item->Start(download_file.Pass(), request_handle.Pass()); | 533 item->Start(download_file.Pass(), request_handle.Pass()); |
| 530 RunAllPendingInMessageLoops(); | 534 RunAllPendingInMessageLoops(); |
| 531 if (i == 0) { | 535 if (i == 0) { |
| 532 // Target determination is only done the first time through. | 536 // Target determination is only done the first time through. |
| 533 base::FilePath target_path(kDummyPath); | 537 base::FilePath target_path(kDummyPath); |
| 534 base::FilePath intermediate_path( | 538 base::FilePath intermediate_path( |
| 535 target_path.InsertBeforeExtensionASCII("x")); | 539 target_path.InsertBeforeExtensionASCII("x")); |
| 536 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) | 540 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) |
| (...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1292 base::Unretained(&returned_path))); | 1296 base::Unretained(&returned_path))); |
| 1293 RunAllPendingInMessageLoops(); | 1297 RunAllPendingInMessageLoops(); |
| 1294 EXPECT_TRUE(returned_path.empty()); | 1298 EXPECT_TRUE(returned_path.empty()); |
| 1295 } | 1299 } |
| 1296 | 1300 |
| 1297 TEST(MockDownloadItem, Compiles) { | 1301 TEST(MockDownloadItem, Compiles) { |
| 1298 MockDownloadItem mock_item; | 1302 MockDownloadItem mock_item; |
| 1299 } | 1303 } |
| 1300 | 1304 |
| 1301 } // namespace content | 1305 } // namespace content |
| OLD | NEW |