| Index: content/browser/download/download_item_impl_unittest.cc
|
| diff --git a/content/browser/download/download_item_impl_unittest.cc b/content/browser/download/download_item_impl_unittest.cc
|
| index a81c744202bee5a725b1b71e0e48153cc862d7d0..9e0ceae69fdd0404d77c1a387dfd6de51fafcfb6 100644
|
| --- a/content/browser/download/download_item_impl_unittest.cc
|
| +++ b/content/browser/download/download_item_impl_unittest.cc
|
| @@ -6,6 +6,7 @@
|
|
|
| #include <stdint.h>
|
|
|
| +#include <deque>
|
| #include <iterator>
|
| #include <map>
|
| #include <memory>
|
| @@ -13,6 +14,7 @@
|
| #include <utility>
|
|
|
| #include "base/callback.h"
|
| +#include "base/callback_helpers.h"
|
| #include "base/feature_list.h"
|
| #include "base/memory/ptr_util.h"
|
| #include "base/message_loop/message_loop.h"
|
| @@ -38,6 +40,8 @@
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| using ::testing::DoAll;
|
| +using ::testing::Invoke;
|
| +using ::testing::InvokeWithoutArgs;
|
| using ::testing::NiceMock;
|
| using ::testing::Property;
|
| using ::testing::Return;
|
| @@ -285,19 +289,14 @@ class DownloadItemTest : public testing::Test {
|
| return download;
|
| }
|
|
|
| - // Add DownloadFile to DownloadItem. Set |callback| to nullptr if a download
|
| - // target determination is not expected.
|
| + // Add DownloadFile to DownloadItem.
|
| MockDownloadFile* CallDownloadItemStart(
|
| DownloadItemImpl* item,
|
| DownloadItemImplDelegate::DownloadTargetCallback* callback) {
|
| MockDownloadFile* mock_download_file = nullptr;
|
| std::unique_ptr<DownloadFile> download_file;
|
| - if (callback) {
|
| - EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
|
| - .WillOnce(SaveArg<1>(callback));
|
| - } else {
|
| - EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)).Times(0);
|
| - }
|
| + EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
|
| + .WillOnce(SaveArg<1>(callback));
|
|
|
| // Only create a DownloadFile if the request was successful.
|
| if (create_info_->result == DOWNLOAD_INTERRUPT_REASON_NONE) {
|
| @@ -309,8 +308,8 @@ class DownloadItemTest : public testing::Test {
|
| .WillRepeatedly(ReturnRefOfCopy(base::FilePath()));
|
| }
|
|
|
| - std::unique_ptr<MockRequestHandle> request_handle(
|
| - new NiceMock<MockRequestHandle>);
|
| + std::unique_ptr<MockRequestHandle> request_handle =
|
| + base::MakeUnique<NiceMock<MockRequestHandle>>();
|
| item->Start(std::move(download_file), std::move(request_handle),
|
| *create_info_);
|
| RunAllPendingInMessageLoops();
|
| @@ -343,7 +342,8 @@ class DownloadItemTest : public testing::Test {
|
| .WillOnce(ScheduleRenameAndUniquifyCallback(
|
| DOWNLOAD_INTERRUPT_REASON_NONE, intermediate_path));
|
| callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - danger_type, intermediate_path);
|
| + danger_type, intermediate_path,
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| RunAllPendingInMessageLoops();
|
| return download_file;
|
| }
|
| @@ -476,8 +476,7 @@ TEST_F(DownloadItemTest, NotificationAfterInterrupted) {
|
| EXPECT_CALL(*download_file, Cancel());
|
| TestDownloadItemObserver observer(item);
|
|
|
| - EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_,_))
|
| - .Times(0);
|
| + EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(0);
|
|
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 0,
|
| @@ -577,7 +576,8 @@ TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) {
|
| // Currently, a notification would be generated if the danger type is anything
|
| // other than NOT_DANGEROUS.
|
| callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path,
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| EXPECT_FALSE(observer.CheckAndResetDownloadUpdated());
|
| RunAllPendingInMessageLoops();
|
| EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
|
| @@ -613,19 +613,32 @@ TEST_F(DownloadItemTest, NotificationAfterTogglePause) {
|
| }
|
|
|
| // Test that a download is resumed automatcially after a continuable interrupt.
|
| -TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
|
| +TEST_F(DownloadItemTest, AutomaticResumption_Continue) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| TestDownloadItemObserver observer(item);
|
| MockDownloadFile* download_file =
|
| DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
|
|
|
| - // Interrupt the download, using a continuable interrupt.
|
| + // Interrupt the download using a continuable interrupt after writing a single
|
| + // byte. An intermediate file with data shouldn't be discarding after a
|
| + // continuable interrupt.
|
| +
|
| + // The DownloadFile should be detached without discarding.
|
| EXPECT_CALL(*download_file, FullPath())
|
| .WillOnce(ReturnRefOfCopy(base::FilePath()));
|
| EXPECT_CALL(*download_file, Detach());
|
| - EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1);
|
| +
|
| + // Resumption attempt should pass the intermediate file along.
|
| + EXPECT_CALL(*mock_delegate(),
|
| + MockResumeInterruptedDownload(
|
| + AllOf(Property(&DownloadUrlParameters::file_path,
|
| + Property(&base::FilePath::value,
|
| + kDummyIntermediatePath)),
|
| + Property(&DownloadUrlParameters::offset, 1)),
|
| + _));
|
| +
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| - DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 0,
|
| + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1,
|
| std::unique_ptr<crypto::SecureHash>());
|
| ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
|
| // Since the download is resumed automatically, the interrupt count doesn't
|
| @@ -644,9 +657,9 @@ TEST_F(DownloadItemTest, ContinueAfterInterrupted) {
|
| CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS);
|
| }
|
|
|
| -// Test that automatic resumption doesn't happen after a non-continuable
|
| -// interrupt.
|
| -TEST_F(DownloadItemTest, RestartAfterInterrupted) {
|
| +// Automatic resumption should restart and discard the intermediate file if the
|
| +// interrupt reason requires it.
|
| +TEST_F(DownloadItemTest, AutomaticResumption_Restart) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| TestDownloadItemObserver observer(item);
|
| MockDownloadFile* download_file =
|
| @@ -654,8 +667,40 @@ TEST_F(DownloadItemTest, RestartAfterInterrupted) {
|
|
|
| // Interrupt the download, using a restartable interrupt.
|
| EXPECT_CALL(*download_file, Cancel());
|
| + EXPECT_EQ(kDummyIntermediatePath, item->GetFullPath().value());
|
| +
|
| + // Resumption attempt should have discarded intermediate file.
|
| + EXPECT_CALL(*mock_delegate(),
|
| + MockResumeInterruptedDownload(
|
| + Property(&DownloadUrlParameters::file_path,
|
| + Property(&base::FilePath::empty, true)),
|
| + _));
|
| +
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| - DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 0,
|
| + DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE, 1,
|
| + std::unique_ptr<crypto::SecureHash>());
|
| + ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
|
| +
|
| + // Since the download is resumed automatically, the interrupt count doesn't
|
| + // increase.
|
| + ASSERT_EQ(0, observer.interrupt_count());
|
| + RunAllPendingInMessageLoops();
|
| +
|
| + CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS);
|
| +}
|
| +
|
| +// Test that automatic resumption doesn't happen after an interrupt that
|
| +// requires user action to resolve.
|
| +TEST_F(DownloadItemTest, AutomaticResumption_NeedsUserAction) {
|
| + DownloadItemImpl* item = CreateDownloadItem();
|
| + TestDownloadItemObserver observer(item);
|
| + MockDownloadFile* download_file =
|
| + DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
|
| +
|
| + // Interrupt the download, using a restartable interrupt.
|
| + EXPECT_CALL(*download_file, Cancel());
|
| + item->DestinationObserverAsWeakPtr()->DestinationError(
|
| + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 1,
|
| std::unique_ptr<crypto::SecureHash>());
|
| ASSERT_TRUE(observer.CheckAndResetDownloadUpdated());
|
| // Should not try to auto-resume.
|
| @@ -695,59 +740,72 @@ TEST_F(DownloadItemTest, UnresumableInterrupt) {
|
| CleanupItem(item, nullptr, DownloadItem::INTERRUPTED);
|
| }
|
|
|
| -TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) {
|
| +TEST_F(DownloadItemTest, AutomaticResumption_AttemptLimit) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| base::WeakPtr<DownloadDestinationObserver> as_observer(
|
| item->DestinationObserverAsWeakPtr());
|
| TestDownloadItemObserver observer(item);
|
| - MockDownloadFile* mock_download_file(nullptr);
|
| - std::unique_ptr<DownloadFile> download_file;
|
| - MockRequestHandle* mock_request_handle(nullptr);
|
| - std::unique_ptr<DownloadRequestHandleInterface> request_handle;
|
| + MockDownloadFile* mock_download_file_ref = nullptr;
|
| + std::unique_ptr<MockDownloadFile> mock_download_file;
|
| + std::unique_ptr<MockRequestHandle> mock_request_handle;
|
| DownloadItemImplDelegate::DownloadTargetCallback callback;
|
|
|
| EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _))
|
| .WillRepeatedly(SaveArg<1>(&callback));
|
| - EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _))
|
| +
|
| + // All attempts at resumption should pass along the intermediate file.
|
| + EXPECT_CALL(*mock_delegate(),
|
| + MockResumeInterruptedDownload(
|
| + AllOf(Property(&DownloadUrlParameters::file_path,
|
| + Property(&base::FilePath::value,
|
| + kDummyIntermediatePath)),
|
| + Property(&DownloadUrlParameters::offset, 1)),
|
| + _))
|
| .Times(DownloadItemImpl::kMaxAutoResumeAttempts);
|
| for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) {
|
| SCOPED_TRACE(::testing::Message() << "Iteration " << i);
|
|
|
| - mock_download_file = new NiceMock<MockDownloadFile>;
|
| - download_file.reset(mock_download_file);
|
| - mock_request_handle = new NiceMock<MockRequestHandle>;
|
| - request_handle.reset(mock_request_handle);
|
| + mock_download_file = base::MakeUnique<NiceMock<MockDownloadFile>>();
|
| + mock_download_file_ref = mock_download_file.get();
|
| + mock_request_handle = base::MakeUnique<NiceMock<MockRequestHandle>>();
|
|
|
| - ON_CALL(*mock_download_file, FullPath())
|
| + ON_CALL(*mock_download_file_ref, FullPath())
|
| .WillByDefault(ReturnRefOfCopy(base::FilePath()));
|
|
|
| // Copied key parts of DoIntermediateRename & CallDownloadItemStart
|
| // to allow for holding onto the request handle.
|
| - item->Start(std::move(download_file), std::move(request_handle),
|
| + item->Start(std::move(mock_download_file), std::move(mock_request_handle),
|
| *create_info());
|
| RunAllPendingInMessageLoops();
|
|
|
| base::FilePath target_path(kDummyTargetPath);
|
| base::FilePath intermediate_path(kDummyIntermediatePath);
|
| - if (i == 0) {
|
| - // RenameAndUniquify is only called the first time. In all the subsequent
|
| - // iterations, the intermediate file already has the correct name, hence
|
| - // no rename is necessary.
|
| - EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _))
|
| - .WillOnce(ScheduleRenameAndUniquifyCallback(
|
| - DOWNLOAD_INTERRUPT_REASON_NONE, intermediate_path));
|
| - }
|
| - callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
|
| +
|
| + // Target of RenameAndUniquify is always the intermediate path.
|
| + ON_CALL(*mock_download_file_ref, RenameAndUniquify(_, _))
|
| + .WillByDefault(ScheduleRenameAndUniquifyCallback(
|
| + DOWNLOAD_INTERRUPT_REASON_NONE, intermediate_path));
|
| +
|
| + // RenameAndUniquify is only called the first time. In all the subsequent
|
| + // iterations, the intermediate file already has the correct name, hence no
|
| + // rename is necessary.
|
| + EXPECT_CALL(*mock_download_file_ref, RenameAndUniquify(_, _)).Times(i == 0);
|
| +
|
| + ASSERT_FALSE(callback.is_null());
|
| + base::ResetAndReturn(&callback).Run(
|
| + target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path,
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| RunAllPendingInMessageLoops();
|
|
|
| // Use a continuable interrupt.
|
| + EXPECT_CALL(*mock_download_file_ref, Cancel()).Times(0);
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| - DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 0,
|
| + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1,
|
| std::unique_ptr<crypto::SecureHash>());
|
|
|
| RunAllPendingInMessageLoops();
|
| - ::testing::Mock::VerifyAndClearExpectations(mock_download_file);
|
| + ::testing::Mock::VerifyAndClearExpectations(mock_download_file_ref);
|
| }
|
|
|
| EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
|
| @@ -779,10 +837,16 @@ TEST_F(DownloadItemTest, FailedResumptionDoesntUpdateOriginState) {
|
| EXPECT_EQ(kFirstURL, item->GetURL().spec());
|
| EXPECT_EQ(kMimeType, item->GetMimeType());
|
|
|
| - EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _));
|
| + EXPECT_CALL(*mock_delegate(),
|
| + MockResumeInterruptedDownload(
|
| + AllOf(Property(&DownloadUrlParameters::file_path,
|
| + Property(&base::FilePath::value,
|
| + kDummyIntermediatePath)),
|
| + Property(&DownloadUrlParameters::offset, 1)),
|
| + _));
|
| EXPECT_CALL(*download_file, Detach());
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| - DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 0,
|
| + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1,
|
| std::unique_ptr<crypto::SecureHash>());
|
| RunAllPendingInMessageLoops();
|
| EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
|
| @@ -801,10 +865,20 @@ TEST_F(DownloadItemTest, FailedResumptionDoesntUpdateOriginState) {
|
| create_info()->url_chain.push_back(GURL(kSecondURL));
|
| create_info()->mime_type = kSecondMimeType;
|
| create_info()->result = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED;
|
| + create_info()->save_info->file_path = base::FilePath(kDummyIntermediatePath);
|
| + create_info()->save_info->offset = 1;
|
|
|
| - // The following ends up calling DownloadItem::Start(), but shouldn't result
|
| - // in an origin update.
|
| - download_file = CallDownloadItemStart(item, nullptr);
|
| + // Calling Start() with a response indicating failure shouldn't cause a target
|
| + // update, nor should it result in discarding the intermediate file.
|
| + DownloadItemImplDelegate::DownloadTargetCallback target_callback;
|
| + download_file = CallDownloadItemStart(item, &target_callback);
|
| + ASSERT_FALSE(target_callback.is_null());
|
| + target_callback.Run(base::FilePath(kDummyTargetPath),
|
| + DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
| + base::FilePath(kDummyIntermediatePath),
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| + RunAllPendingInMessageLoops();
|
|
|
| EXPECT_EQ(kContentDisposition, item->GetContentDisposition());
|
| EXPECT_EQ(kFirstETag, item->GetETag());
|
| @@ -813,6 +887,8 @@ TEST_F(DownloadItemTest, FailedResumptionDoesntUpdateOriginState) {
|
| EXPECT_EQ(kMimeType, item->GetMimeType());
|
| EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
|
| EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason());
|
| + EXPECT_EQ(kDummyIntermediatePath, item->GetFullPath().value());
|
| + EXPECT_EQ(1, item->GetReceivedBytes());
|
| }
|
|
|
| // If the download resumption request succeeds, the origin state should be
|
| @@ -867,7 +943,7 @@ TEST_F(DownloadItemTest, SucceededResumptionUpdatesOriginState) {
|
| }
|
|
|
| // Test that resumption uses the final URL in a URL chain when resuming.
|
| -TEST_F(DownloadItemTest, ResumeUsingFinalURL) {
|
| +TEST_F(DownloadItemTest, ResumeUsesFinalURL) {
|
| create_info()->save_info->prompt_for_save_location = false;
|
| create_info()->url_chain.clear();
|
| create_info()->url_chain.push_back(GURL("http://example.com/a"));
|
| @@ -889,7 +965,7 @@ TEST_F(DownloadItemTest, ResumeUsingFinalURL) {
|
| _))
|
| .Times(1);
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| - DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 0,
|
| + DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, 1,
|
| std::unique_ptr<crypto::SecureHash>());
|
|
|
| // Test expectations verify that ResumeInterruptedDownload() is called (by way
|
| @@ -916,7 +992,8 @@ TEST_F(DownloadItemTest, DisplayName) {
|
| .WillOnce(ScheduleRenameAndUniquifyCallback(
|
| DOWNLOAD_INTERRUPT_REASON_NONE, intermediate_path));
|
| callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path,
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| RunAllPendingInMessageLoops();
|
| EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"),
|
| item->GetFileNameToReportUser().value());
|
| @@ -946,8 +1023,10 @@ TEST_F(DownloadItemTest, Start) {
|
| // file initialization failing.
|
| TEST_F(DownloadItemTest, InitDownloadFileFails) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| - std::unique_ptr<MockDownloadFile> file(new MockDownloadFile());
|
| - std::unique_ptr<MockRequestHandle> request_handle(new MockRequestHandle());
|
| + std::unique_ptr<MockDownloadFile> file = base::MakeUnique<MockDownloadFile>();
|
| + std::unique_ptr<MockRequestHandle> request_handle =
|
| + base::MakeUnique<MockRequestHandle>();
|
| +
|
| EXPECT_CALL(*file, Cancel());
|
| EXPECT_CALL(*request_handle, CancelRequest());
|
| EXPECT_CALL(*file, Initialize(_))
|
| @@ -966,12 +1045,15 @@ TEST_F(DownloadItemTest, InitDownloadFileFails) {
|
| download_target_callback.Run(base::FilePath(kDummyTargetPath),
|
| DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
| - base::FilePath(kDummyIntermediatePath));
|
| + base::FilePath(kDummyIntermediatePath),
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| RunAllPendingInMessageLoops();
|
|
|
| EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
|
| EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
|
| item->GetLastReason());
|
| + EXPECT_FALSE(item->GetTargetFilePath().empty());
|
| + EXPECT_TRUE(item->GetFullPath().empty());
|
| }
|
|
|
| // Handling of downloads initiated via a failed request. In this case, Start()
|
| @@ -999,7 +1081,8 @@ TEST_F(DownloadItemTest, StartFailedDownload) {
|
| base::FilePath target_path(FILE_PATH_LITERAL("foo"));
|
| download_target_callback.Run(target_path,
|
| DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, target_path);
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, target_path,
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| RunAllPendingInMessageLoops();
|
|
|
| EXPECT_EQ(target_path, item->GetTargetFilePath());
|
| @@ -1021,7 +1104,8 @@ TEST_F(DownloadItemTest, CallbackAfterRename) {
|
| DOWNLOAD_INTERRUPT_REASON_NONE, new_intermediate_path));
|
|
|
| callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path,
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| RunAllPendingInMessageLoops();
|
| // All the callbacks should have happened by now.
|
| ::testing::Mock::VerifyAndClearExpectations(download_file);
|
| @@ -1060,7 +1144,8 @@ TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) {
|
| .Times(1);
|
|
|
| callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path,
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| RunAllPendingInMessageLoops();
|
| // All the callbacks should have happened by now.
|
| ::testing::Mock::VerifyAndClearExpectations(download_file);
|
| @@ -1112,7 +1197,8 @@ TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) {
|
| .Times(1);
|
|
|
| callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path,
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| RunAllPendingInMessageLoops();
|
| // All the callbacks should have happened by now.
|
| ::testing::Mock::VerifyAndClearExpectations(download_file);
|
| @@ -1129,8 +1215,11 @@ TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| DownloadItemImplDelegate::DownloadTargetCallback callback;
|
| MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
|
| +
|
| + // Write some data and interrupt with NETWORK_FAILED. The download shouldn't
|
| + // transition to INTERRUPTED until the destination callback has been invoked.
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| - DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 0,
|
| + DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 1,
|
| std::unique_ptr<crypto::SecureHash>());
|
| ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());
|
|
|
| @@ -1147,7 +1236,8 @@ TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) {
|
| EXPECT_CALL(*download_file, Detach());
|
|
|
| callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path,
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| RunAllPendingInMessageLoops();
|
| // All the callbacks should have happened by now.
|
| ::testing::Mock::VerifyAndClearExpectations(download_file);
|
| @@ -1180,7 +1270,8 @@ TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) {
|
| .Times(1);
|
|
|
| callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path);
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path,
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| RunAllPendingInMessageLoops();
|
| // All the callbacks should have happened by now.
|
| ::testing::Mock::VerifyAndClearExpectations(download_file);
|
| @@ -1203,6 +1294,32 @@ TEST_F(DownloadItemTest, Canceled) {
|
| EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
|
| }
|
|
|
| +TEST_F(DownloadItemTest, DownloadTargetDetermined_Cancel) {
|
| + DownloadItemImpl* item = CreateDownloadItem();
|
| + DownloadItemImplDelegate::DownloadTargetCallback callback;
|
| + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
|
| +
|
| + EXPECT_CALL(*download_file, Cancel());
|
| + callback.Run(base::FilePath(FILE_PATH_LITERAL("foo")),
|
| + DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
| + base::FilePath(FILE_PATH_LITERAL("bar")),
|
| + DOWNLOAD_INTERRUPT_REASON_USER_CANCELED);
|
| + EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
|
| +}
|
| +
|
| +TEST_F(DownloadItemTest, DownloadTargetDetermined_CancelWithEmptyName) {
|
| + DownloadItemImpl* item = CreateDownloadItem();
|
| + DownloadItemImplDelegate::DownloadTargetCallback callback;
|
| + MockDownloadFile* download_file = CallDownloadItemStart(item, &callback);
|
| +
|
| + EXPECT_CALL(*download_file, Cancel());
|
| + callback.Run(base::FilePath(), DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath(),
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| + EXPECT_EQ(DownloadItem::CANCELLED, item->GetState());
|
| +}
|
| +
|
| TEST_F(DownloadItemTest, FileRemoved) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
|
|
| @@ -1263,8 +1380,8 @@ TEST_F(DownloadItemTest, DestinationError_NoRestartRequired) {
|
| hash->Update(kTestData1, sizeof(kTestData1));
|
|
|
| EXPECT_CALL(*download_file, Detach());
|
| - as_observer->DestinationError(
|
| - DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 0, std::move(hash));
|
| + as_observer->DestinationError(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 1,
|
| + std::move(hash));
|
| mock_delegate()->VerifyAndClearExpectations();
|
| EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
|
| EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
|
| @@ -1273,6 +1390,7 @@ TEST_F(DownloadItemTest, DestinationError_NoRestartRequired) {
|
| std::string(std::begin(kHashOfTestData1), std::end(kHashOfTestData1)),
|
| item->GetHash());
|
| }
|
| +
|
| TEST_F(DownloadItemTest, DestinationError_RestartRequired) {
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| MockDownloadFile* download_file =
|
| @@ -1290,8 +1408,8 @@ TEST_F(DownloadItemTest, DestinationError_RestartRequired) {
|
| hash->Update(kTestData1, sizeof(kTestData1));
|
|
|
| EXPECT_CALL(*download_file, Cancel());
|
| - as_observer->DestinationError(
|
| - DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 0, std::move(hash));
|
| + as_observer->DestinationError(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 1,
|
| + std::move(hash));
|
| mock_delegate()->VerifyAndClearExpectations();
|
| EXPECT_TRUE(observer.CheckAndResetDownloadUpdated());
|
| EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState());
|
| @@ -1643,7 +1761,7 @@ TEST_F(DownloadItemTest, StealDangerousDownloadAndKeep) {
|
| CleanupItem(item, download_file, DownloadItem::IN_PROGRESS);
|
| }
|
|
|
| -TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
|
| +TEST_F(DownloadItemTest, StealInterruptedContinuableDangerousDownload) {
|
| base::FilePath returned_path;
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| MockDownloadFile* download_file =
|
| @@ -1653,7 +1771,7 @@ TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
|
| EXPECT_CALL(*download_file, FullPath()).WillOnce(ReturnRefOfCopy(full_path));
|
| EXPECT_CALL(*download_file, Detach());
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| - DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 0,
|
| + DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, 1,
|
| std::unique_ptr<crypto::SecureHash>());
|
| ASSERT_TRUE(item->IsDangerous());
|
|
|
| @@ -1668,14 +1786,14 @@ TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) {
|
| EXPECT_EQ(full_path, returned_path);
|
| }
|
|
|
| -TEST_F(DownloadItemTest, StealInterruptedNonResumableDangerousDownload) {
|
| +TEST_F(DownloadItemTest, StealInterruptedNonContinuableDangerousDownload) {
|
| base::FilePath returned_path;
|
| DownloadItemImpl* item = CreateDownloadItem();
|
| MockDownloadFile* download_file =
|
| DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE);
|
| EXPECT_CALL(*download_file, Cancel());
|
| item->DestinationObserverAsWeakPtr()->DestinationError(
|
| - DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 0,
|
| + DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, 1,
|
| std::unique_ptr<crypto::SecureHash>());
|
| ASSERT_TRUE(item->IsDangerous());
|
|
|
| @@ -1962,7 +2080,8 @@ TEST_P(DownloadItemDestinationUpdateRaceTest, DownloadCancelledByUser) {
|
| destination_observer);
|
| target_callback.Run(base::FilePath(),
|
| DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| - DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath());
|
| + DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath(),
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
| EXPECT_EQ(DownloadItem::CANCELLED, item_->GetState());
|
| RunAllPendingInMessageLoops();
|
| }
|
| @@ -2015,7 +2134,8 @@ TEST_P(DownloadItemDestinationUpdateRaceTest, IntermediateRenameFails) {
|
| target_callback.Run(base::FilePath(kDummyTargetPath),
|
| DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
| - base::FilePath(kDummyIntermediatePath));
|
| + base::FilePath(kDummyIntermediatePath),
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
|
|
| intermediate_rename_loop.Run();
|
| ASSERT_FALSE(intermediate_rename_callback.is_null());
|
| @@ -2084,7 +2204,8 @@ TEST_P(DownloadItemDestinationUpdateRaceTest, IntermediateRenameSucceeds) {
|
| target_callback.Run(base::FilePath(kDummyTargetPath),
|
| DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
| DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
| - base::FilePath(kDummyIntermediatePath));
|
| + base::FilePath(kDummyIntermediatePath),
|
| + DOWNLOAD_INTERRUPT_REASON_NONE);
|
|
|
| intermediate_rename_loop.Run();
|
| ASSERT_FALSE(intermediate_rename_callback.is_null());
|
|
|