| 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 "content/browser/download/download_item_impl.h" | 5 #include "content/browser/download/download_item_impl.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 |
| 9 #include <iterator> |
| 10 #include <queue> |
| 8 #include <utility> | 11 #include <utility> |
| 9 | 12 |
| 10 #include "base/callback.h" | 13 #include "base/callback.h" |
| 11 #include "base/feature_list.h" | 14 #include "base/feature_list.h" |
| 12 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/run_loop.h" |
| 13 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
| 14 #include "base/threading/thread.h" | 18 #include "base/threading/thread.h" |
| 15 #include "content/browser/byte_stream.h" | 19 #include "content/browser/byte_stream.h" |
| 16 #include "content/browser/download/download_create_info.h" | 20 #include "content/browser/download/download_create_info.h" |
| 17 #include "content/browser/download/download_file_factory.h" | 21 #include "content/browser/download/download_file_factory.h" |
| 18 #include "content/browser/download/download_item_impl_delegate.h" | 22 #include "content/browser/download/download_item_impl_delegate.h" |
| 19 #include "content/browser/download/download_request_handle.h" | 23 #include "content/browser/download/download_request_handle.h" |
| 20 #include "content/browser/download/mock_download_file.h" | 24 #include "content/browser/download/mock_download_file.h" |
| 25 #include "content/public/browser/browser_thread.h" |
| 21 #include "content/public/browser/download_destination_observer.h" | 26 #include "content/public/browser/download_destination_observer.h" |
| 22 #include "content/public/browser/download_interrupt_reasons.h" | 27 #include "content/public/browser/download_interrupt_reasons.h" |
| 23 #include "content/public/browser/download_url_parameters.h" | 28 #include "content/public/browser/download_url_parameters.h" |
| 24 #include "content/public/common/content_features.h" | 29 #include "content/public/common/content_features.h" |
| 25 #include "content/public/test/mock_download_item.h" | 30 #include "content/public/test/mock_download_item.h" |
| 26 #include "content/public/test/test_browser_context.h" | 31 #include "content/public/test/test_browser_context.h" |
| 27 #include "content/public/test/test_browser_thread.h" | 32 #include "content/public/test/test_browser_thread_bundle.h" |
| 28 #include "testing/gmock/include/gmock/gmock.h" | 33 #include "testing/gmock/include/gmock/gmock.h" |
| 29 #include "testing/gtest/include/gtest/gtest.h" | 34 #include "testing/gtest/include/gtest/gtest.h" |
| 30 | 35 |
| 31 using ::testing::_; | 36 using ::testing::DoAll; |
| 32 using ::testing::NiceMock; | 37 using ::testing::NiceMock; |
| 33 using ::testing::Property; | 38 using ::testing::Property; |
| 34 using ::testing::Return; | 39 using ::testing::Return; |
| 35 using ::testing::SaveArg; | 40 using ::testing::SaveArg; |
| 36 using ::testing::StrictMock; | 41 using ::testing::StrictMock; |
| 42 using ::testing::WithArg; |
| 43 using ::testing::_; |
| 37 | 44 |
| 38 const int kDownloadChunkSize = 1000; | 45 const int kDownloadChunkSize = 1000; |
| 39 const int kDownloadSpeed = 1000; | 46 const int kDownloadSpeed = 1000; |
| 40 const base::FilePath::CharType kDummyPath[] = FILE_PATH_LITERAL("/testpath"); | 47 const base::FilePath::CharType kDummyTargetPath[] = |
| 48 FILE_PATH_LITERAL("/testpath"); |
| 49 const base::FilePath::CharType kDummyIntermediatePath[] = |
| 50 FILE_PATH_LITERAL("/testpathx"); |
| 41 | 51 |
| 42 namespace content { | 52 namespace content { |
| 43 | 53 |
| 44 namespace { | 54 namespace { |
| 45 | 55 |
| 46 class MockDelegate : public DownloadItemImplDelegate { | 56 class MockDelegate : public DownloadItemImplDelegate { |
| 47 public: | 57 public: |
| 48 MockDelegate() : DownloadItemImplDelegate() { | 58 MockDelegate() : DownloadItemImplDelegate() { |
| 49 SetDefaultExpectations(); | 59 SetDefaultExpectations(); |
| 50 } | 60 } |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 void OnDownloadOpened(DownloadItem* download) override { | 162 void OnDownloadOpened(DownloadItem* download) override { |
| 153 DVLOG(20) << " " << __FUNCTION__ | 163 DVLOG(20) << " " << __FUNCTION__ |
| 154 << " download = " << download->DebugString(false); | 164 << " download = " << download->DebugString(false); |
| 155 } | 165 } |
| 156 | 166 |
| 157 void OnDownloadDestroyed(DownloadItem* download) override { | 167 void OnDownloadDestroyed(DownloadItem* download) override { |
| 158 DVLOG(20) << " " << __FUNCTION__ | 168 DVLOG(20) << " " << __FUNCTION__ |
| 159 << " download = " << download->DebugString(false); | 169 << " download = " << download->DebugString(false); |
| 160 destroyed_ = true; | 170 destroyed_ = true; |
| 161 item_->RemoveObserver(this); | 171 item_->RemoveObserver(this); |
| 162 item_ = NULL; | 172 item_ = nullptr; |
| 163 } | 173 } |
| 164 | 174 |
| 165 DownloadItem* item_; | 175 DownloadItem* item_; |
| 166 DownloadItem::DownloadState last_state_; | 176 DownloadItem::DownloadState last_state_; |
| 167 bool removed_; | 177 bool removed_; |
| 168 bool destroyed_; | 178 bool destroyed_; |
| 169 bool updated_; | 179 bool updated_; |
| 170 int interrupt_count_; | 180 int interrupt_count_; |
| 171 int resume_count_; | 181 int resume_count_; |
| 172 }; | 182 }; |
| 173 | 183 |
| 174 // Schedules a task to invoke the RenameCompletionCallback with |new_path| on | 184 // Schedules a task to invoke the RenameCompletionCallback with |new_path| on |
| 175 // the UI thread. Should only be used as the action for | 185 // the UI thread. Should only be used as the action for |
| 176 // MockDownloadFile::Rename as follows: | 186 // MockDownloadFile::Rename as follows: |
| 177 // EXPECT_CALL(download_file, Rename*(_,_)) | 187 // EXPECT_CALL(download_file, Rename*(_,_)) |
| 178 // .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 188 // .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 179 // new_path)); | 189 // new_path)); |
| 180 ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) { | 190 ACTION_P2(ScheduleRenameCallback, interrupt_reason, new_path) { |
| 181 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 191 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 182 base::Bind(arg1, interrupt_reason, new_path)); | 192 base::Bind(arg1, interrupt_reason, new_path)); |
| 183 } | 193 } |
| 184 | 194 |
| 195 // Schedules a task to invoke a callback that's bound to the specified |
| 196 // parameter. |
| 197 // E.g.: |
| 198 // |
| 199 // EXPECT_CALL(foo, Bar(1, _)) |
| 200 // .WithArg<1>(ScheduleCallbackWithParam(0)); |
| 201 // |
| 202 // .. will invoke the second argument to Bar with 0 as the parameter. |
| 203 ACTION_P(ScheduleCallbackWithParam, param) { |
| 204 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 205 base::Bind(arg0, param)); |
| 206 } |
| 207 |
| 208 ACTION_P(ScheduleClosure, closure) { |
| 209 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closure); |
| 210 } |
| 211 |
| 185 } // namespace | 212 } // namespace |
| 186 | 213 |
| 187 class DownloadItemTest : public testing::Test { | 214 class DownloadItemTest : public testing::Test { |
| 188 public: | 215 public: |
| 189 DownloadItemTest() | 216 DownloadItemTest() { |
| 190 : ui_thread_(BrowserThread::UI, &loop_), | |
| 191 file_thread_(BrowserThread::FILE, &loop_), | |
| 192 delegate_() { | |
| 193 } | |
| 194 | |
| 195 ~DownloadItemTest() { | |
| 196 } | |
| 197 | |
| 198 virtual void SetUp() { | |
| 199 base::FeatureList::ClearInstanceForTesting(); | 217 base::FeatureList::ClearInstanceForTesting(); |
| 200 scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); | 218 scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); |
| 201 feature_list->InitializeFromCommandLine(features::kDownloadResumption.name, | 219 feature_list->InitializeFromCommandLine(features::kDownloadResumption.name, |
| 202 std::string()); | 220 std::string()); |
| 203 base::FeatureList::SetInstance(std::move(feature_list)); | 221 base::FeatureList::SetInstance(std::move(feature_list)); |
| 204 } | 222 } |
| 205 | 223 |
| 206 virtual void TearDown() { | 224 ~DownloadItemTest() { |
| 207 ui_thread_.DeprecatedGetThreadObject()->message_loop()->RunUntilIdle(); | 225 RunAllPendingInMessageLoops(); |
| 208 STLDeleteElements(&allocated_downloads_); | 226 STLDeleteElements(&allocated_downloads_); |
| 209 } | 227 } |
| 210 | 228 |
| 229 DownloadItemImpl* CreateDownloadItemWithCreateInfo( |
| 230 scoped_ptr<DownloadCreateInfo> info) { |
| 231 DownloadItemImpl* download = new DownloadItemImpl( |
| 232 &delegate_, next_download_id_++, *(info.get()), net::BoundNetLog()); |
| 233 allocated_downloads_.insert(download); |
| 234 return download; |
| 235 } |
| 236 |
| 211 // This class keeps ownership of the created download item; it will | 237 // This class keeps ownership of the created download item; it will |
| 212 // be torn down at the end of the test unless DestroyDownloadItem is | 238 // be torn down at the end of the test unless DestroyDownloadItem is |
| 213 // called. | 239 // called. |
| 214 DownloadItemImpl* CreateDownloadItem() { | 240 DownloadItemImpl* CreateDownloadItem() { |
| 215 scoped_ptr<DownloadCreateInfo> info; | 241 scoped_ptr<DownloadCreateInfo> info; |
| 216 | 242 |
| 217 info.reset(new DownloadCreateInfo()); | 243 info.reset(new DownloadCreateInfo()); |
| 218 info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); | 244 info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); |
| 219 info->save_info->prompt_for_save_location = false; | 245 info->save_info->prompt_for_save_location = false; |
| 220 info->url_chain.push_back(GURL()); | 246 info->url_chain.push_back(GURL("http://example.com/download")); |
| 221 info->etag = "SomethingToSatisfyResumption"; | 247 info->etag = "SomethingToSatisfyResumption"; |
| 222 | 248 |
| 223 return CreateDownloadItemWithCreateInfo(std::move(info)); | 249 return CreateDownloadItemWithCreateInfo(std::move(info)); |
| 224 } | 250 } |
| 225 | 251 |
| 226 DownloadItemImpl* CreateDownloadItemWithCreateInfo( | |
| 227 scoped_ptr<DownloadCreateInfo> info) { | |
| 228 DownloadItemImpl* download = new DownloadItemImpl( | |
| 229 &delegate_, next_download_id_++, *(info.get()), net::BoundNetLog()); | |
| 230 allocated_downloads_.insert(download); | |
| 231 return download; | |
| 232 } | |
| 233 | |
| 234 // Add DownloadFile to DownloadItem | 252 // Add DownloadFile to DownloadItem |
| 235 MockDownloadFile* AddDownloadFileToDownloadItem( | 253 MockDownloadFile* CallDownloadItemStart( |
| 236 DownloadItemImpl* item, | 254 DownloadItemImpl* item, |
| 237 DownloadItemImplDelegate::DownloadTargetCallback *callback) { | 255 DownloadItemImplDelegate::DownloadTargetCallback* callback) { |
| 238 MockDownloadFile* mock_download_file(new StrictMock<MockDownloadFile>); | 256 MockDownloadFile* mock_download_file(new StrictMock<MockDownloadFile>); |
| 239 scoped_ptr<DownloadFile> download_file(mock_download_file); | 257 scoped_ptr<DownloadFile> download_file(mock_download_file); |
| 240 EXPECT_CALL(*mock_download_file, Initialize(_)); | 258 EXPECT_CALL(*mock_download_file, Initialize(_)); |
| 241 if (callback) { | 259 if (callback) { |
| 242 // Save the callback. | 260 // Save the callback. |
| 243 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) | 261 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) |
| 244 .WillOnce(SaveArg<1>(callback)); | 262 .WillOnce(SaveArg<1>(callback)); |
| 245 } else { | 263 } else { |
| 246 // Drop it on the floor. | 264 // Drop it on the floor. |
| 247 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); | 265 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); |
| 248 } | 266 } |
| 249 | 267 |
| 250 scoped_ptr<DownloadRequestHandleInterface> request_handle( | 268 scoped_ptr<DownloadRequestHandleInterface> request_handle( |
| 251 new NiceMock<MockRequestHandle>); | 269 new NiceMock<MockRequestHandle>); |
| 252 item->Start(std::move(download_file), std::move(request_handle)); | 270 item->Start(std::move(download_file), std::move(request_handle)); |
| 253 loop_.RunUntilIdle(); | 271 RunAllPendingInMessageLoops(); |
| 254 | 272 |
| 255 // So that we don't have a function writing to a stack variable | 273 // So that we don't have a function writing to a stack variable |
| 256 // lying around if the above failed. | 274 // lying around if the above failed. |
| 257 mock_delegate()->VerifyAndClearExpectations(); | 275 mock_delegate()->VerifyAndClearExpectations(); |
| 258 EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_)) | 276 EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_)) |
| 259 .WillRepeatedly(Return()); | 277 .WillRepeatedly(Return()); |
| 260 EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_)) | 278 EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_)) |
| 261 .WillRepeatedly(Return(false)); | 279 .WillRepeatedly(Return(false)); |
| 262 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _)) | 280 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _)) |
| 263 .WillRepeatedly(Return(true)); | 281 .WillRepeatedly(Return(true)); |
| 264 | 282 |
| 265 return mock_download_file; | 283 return mock_download_file; |
| 266 } | 284 } |
| 267 | 285 |
| 268 // Perform the intermediate rename for |item|. The target path for the | 286 // Perform the intermediate rename for |item|. The target path for the |
| 269 // download will be set to kDummyPath. Returns the MockDownloadFile* that was | 287 // download will be set to kDummyTargetPath. Returns the MockDownloadFile* |
| 270 // added to the DownloadItem. | 288 // that was added to the DownloadItem. |
| 271 MockDownloadFile* DoIntermediateRename(DownloadItemImpl* item, | 289 MockDownloadFile* DoIntermediateRename(DownloadItemImpl* item, |
| 272 DownloadDangerType danger_type) { | 290 DownloadDangerType danger_type) { |
| 273 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 291 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 274 EXPECT_TRUE(item->GetTargetFilePath().empty()); | 292 EXPECT_TRUE(item->GetTargetFilePath().empty()); |
| 275 DownloadItemImplDelegate::DownloadTargetCallback callback; | 293 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 276 MockDownloadFile* download_file = | 294 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
| 277 AddDownloadFileToDownloadItem(item, &callback); | 295 base::FilePath target_path(kDummyTargetPath); |
| 278 base::FilePath target_path(kDummyPath); | 296 base::FilePath intermediate_path(kDummyIntermediatePath); |
| 279 base::FilePath intermediate_path( | |
| 280 target_path.InsertBeforeExtensionASCII("x")); | |
| 281 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) | 297 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) |
| 282 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 298 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 283 intermediate_path)); | 299 intermediate_path)); |
| 284 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 300 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 285 danger_type, intermediate_path); | 301 danger_type, intermediate_path); |
| 286 RunAllPendingInMessageLoops(); | 302 RunAllPendingInMessageLoops(); |
| 287 return download_file; | 303 return download_file; |
| 288 } | 304 } |
| 289 | 305 |
| 306 void DoDestinationComplete(DownloadItemImpl* item, |
| 307 MockDownloadFile* download_file) { |
| 308 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _)) |
| 309 .WillOnce(Return(true)); |
| 310 base::FilePath final_path(kDummyTargetPath); |
| 311 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) |
| 312 .WillOnce( |
| 313 ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, final_path)); |
| 314 EXPECT_CALL(*download_file, FullPath()) |
| 315 .WillRepeatedly(Return(base::FilePath(kDummyTargetPath))); |
| 316 EXPECT_CALL(*download_file, Detach()); |
| 317 |
| 318 item->DestinationObserverAsWeakPtr()->DestinationCompleted(""); |
| 319 RunAllPendingInMessageLoops(); |
| 320 } |
| 321 |
| 290 // Cleanup a download item (specifically get rid of the DownloadFile on it). | 322 // Cleanup a download item (specifically get rid of the DownloadFile on it). |
| 291 // The item must be in the expected state. | 323 // The item must be in the expected state. |
| 292 void CleanupItem(DownloadItemImpl* item, | 324 void CleanupItem(DownloadItemImpl* item, |
| 293 MockDownloadFile* download_file, | 325 MockDownloadFile* download_file, |
| 294 DownloadItem::DownloadState expected_state) { | 326 DownloadItem::DownloadState expected_state) { |
| 295 EXPECT_EQ(expected_state, item->GetState()); | 327 EXPECT_EQ(expected_state, item->GetState()); |
| 296 | 328 |
| 297 if (expected_state == DownloadItem::IN_PROGRESS) { | 329 if (expected_state == DownloadItem::IN_PROGRESS) { |
| 298 if (download_file) | 330 if (download_file) |
| 299 EXPECT_CALL(*download_file, Cancel()); | 331 EXPECT_CALL(*download_file, Cancel()); |
| 300 item->Cancel(true); | 332 item->Cancel(true); |
| 301 loop_.RunUntilIdle(); | 333 RunAllPendingInMessageLoops(); |
| 302 } | 334 } |
| 303 } | 335 } |
| 304 | 336 |
| 305 // Destroy a previously created download item. | 337 // Destroy a previously created download item. |
| 306 void DestroyDownloadItem(DownloadItem* item) { | 338 void DestroyDownloadItem(DownloadItem* item) { |
| 307 allocated_downloads_.erase(item); | 339 allocated_downloads_.erase(item); |
| 308 delete item; | 340 delete item; |
| 309 } | 341 } |
| 310 | 342 |
| 311 void RunAllPendingInMessageLoops() { | 343 void RunAllPendingInMessageLoops() { base::RunLoop().RunUntilIdle(); } |
| 312 loop_.RunUntilIdle(); | |
| 313 } | |
| 314 | 344 |
| 315 MockDelegate* mock_delegate() { | 345 MockDelegate* mock_delegate() { |
| 316 return &delegate_; | 346 return &delegate_; |
| 317 } | 347 } |
| 318 | 348 |
| 319 void OnDownloadFileAcquired(base::FilePath* return_path, | 349 void OnDownloadFileAcquired(base::FilePath* return_path, |
| 320 const base::FilePath& path) { | 350 const base::FilePath& path) { |
| 321 *return_path = path; | 351 *return_path = path; |
| 322 } | 352 } |
| 323 | 353 |
| 324 private: | 354 private: |
| 325 int next_download_id_ = DownloadItem::kInvalidId + 1; | 355 int next_download_id_ = DownloadItem::kInvalidId + 1; |
| 326 base::MessageLoopForUI loop_; | |
| 327 TestBrowserThread ui_thread_; // UI thread | |
| 328 TestBrowserThread file_thread_; // FILE thread | |
| 329 StrictMock<MockDelegate> delegate_; | 356 StrictMock<MockDelegate> delegate_; |
| 330 std::set<DownloadItem*> allocated_downloads_; | 357 std::set<DownloadItem*> allocated_downloads_; |
| 358 TestBrowserThreadBundle thread_bundle_; |
| 331 }; | 359 }; |
| 332 | 360 |
| 333 // Tests to ensure calls that change a DownloadItem generate an update to | 361 // Tests to ensure calls that change a DownloadItem generate an update to |
| 334 // observers. | 362 // observers. |
| 335 // State changing functions not tested: | 363 // State changing functions not tested: |
| 336 // void OpenDownload(); | 364 // void OpenDownload(); |
| 337 // void ShowDownloadInShell(); | 365 // void ShowDownloadInShell(); |
| 338 // void CompleteDelayedDownload(); | 366 // void CompleteDelayedDownload(); |
| 339 // set_* mutators | 367 // set_* mutators |
| 340 | 368 |
| 341 TEST_F(DownloadItemTest, NotificationAfterUpdate) { | 369 TEST_F(DownloadItemTest, NotificationAfterUpdate) { |
| 342 DownloadItemImpl* item = CreateDownloadItem(); | 370 DownloadItemImpl* item = CreateDownloadItem(); |
| 371 MockDownloadFile* file = |
| 372 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 373 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 343 TestDownloadItemObserver observer(item); | 374 TestDownloadItemObserver observer(item); |
| 344 | 375 |
| 345 item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string()); | 376 item->DestinationUpdate(kDownloadChunkSize, kDownloadSpeed, std::string()); |
| 346 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 377 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 347 EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed()); | 378 EXPECT_EQ(kDownloadSpeed, item->CurrentSpeed()); |
| 379 CleanupItem(item, file, DownloadItem::IN_PROGRESS); |
| 348 } | 380 } |
| 349 | 381 |
| 350 TEST_F(DownloadItemTest, NotificationAfterCancel) { | 382 TEST_F(DownloadItemTest, NotificationAfterCancel) { |
| 351 DownloadItemImpl* user_cancel = CreateDownloadItem(); | 383 DownloadItemImpl* user_cancel = CreateDownloadItem(); |
| 352 MockDownloadFile* download_file = | 384 MockDownloadFile* download_file = CallDownloadItemStart(user_cancel, nullptr); |
| 353 AddDownloadFileToDownloadItem(user_cancel, NULL); | |
| 354 EXPECT_CALL(*download_file, Cancel()); | 385 EXPECT_CALL(*download_file, Cancel()); |
| 355 TestDownloadItemObserver observer1(user_cancel); | 386 TestDownloadItemObserver observer1(user_cancel); |
| 356 | 387 |
| 357 user_cancel->Cancel(true); | 388 user_cancel->Cancel(true); |
| 358 ASSERT_TRUE(observer1.CheckAndResetDownloadUpdated()); | 389 ASSERT_TRUE(observer1.CheckAndResetDownloadUpdated()); |
| 359 | 390 |
| 360 DownloadItemImpl* system_cancel = CreateDownloadItem(); | 391 DownloadItemImpl* system_cancel = CreateDownloadItem(); |
| 361 download_file = AddDownloadFileToDownloadItem(system_cancel, NULL); | 392 download_file = CallDownloadItemStart(system_cancel, nullptr); |
| 362 EXPECT_CALL(*download_file, Cancel()); | 393 EXPECT_CALL(*download_file, Cancel()); |
| 363 TestDownloadItemObserver observer2(system_cancel); | 394 TestDownloadItemObserver observer2(system_cancel); |
| 364 | 395 |
| 365 system_cancel->Cancel(false); | 396 system_cancel->Cancel(false); |
| 366 ASSERT_TRUE(observer2.CheckAndResetDownloadUpdated()); | 397 ASSERT_TRUE(observer2.CheckAndResetDownloadUpdated()); |
| 367 } | 398 } |
| 368 | 399 |
| 369 TEST_F(DownloadItemTest, NotificationAfterComplete) { | 400 TEST_F(DownloadItemTest, NotificationAfterComplete) { |
| 370 DownloadItemImpl* item = CreateDownloadItem(); | 401 DownloadItemImpl* item = CreateDownloadItem(); |
| 371 TestDownloadItemObserver observer(item); | 402 TestDownloadItemObserver observer(item); |
| 372 | 403 MockDownloadFile* download_file = |
| 373 item->OnAllDataSaved(DownloadItem::kEmptyFileHash); | 404 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 374 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 405 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 375 | 406 DoDestinationComplete(item, download_file); |
| 376 item->MarkAsComplete(); | |
| 377 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 407 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 378 } | 408 } |
| 379 | 409 |
| 380 TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) { | 410 TEST_F(DownloadItemTest, NotificationAfterDownloadedFileRemoved) { |
| 381 DownloadItemImpl* item = CreateDownloadItem(); | 411 DownloadItemImpl* item = CreateDownloadItem(); |
| 382 TestDownloadItemObserver observer(item); | 412 TestDownloadItemObserver observer(item); |
| 383 | 413 |
| 384 item->OnDownloadedFileRemoved(); | 414 item->OnDownloadedFileRemoved(); |
| 385 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 415 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 386 } | 416 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 // Check we do correct cleanup for RESUME_MODE_INVALID interrupts. | 494 // Check we do correct cleanup for RESUME_MODE_INVALID interrupts. |
| 465 TEST_F(DownloadItemTest, UnresumableInterrupt) { | 495 TEST_F(DownloadItemTest, UnresumableInterrupt) { |
| 466 DownloadItemImpl* item = CreateDownloadItem(); | 496 DownloadItemImpl* item = CreateDownloadItem(); |
| 467 TestDownloadItemObserver observer(item); | 497 TestDownloadItemObserver observer(item); |
| 468 MockDownloadFile* download_file = | 498 MockDownloadFile* download_file = |
| 469 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 499 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 470 | 500 |
| 471 // Fail final rename with unresumable reason. | 501 // Fail final rename with unresumable reason. |
| 472 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) | 502 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 473 .WillOnce(Return(true)); | 503 .WillOnce(Return(true)); |
| 474 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) | 504 EXPECT_CALL(*download_file, |
| 505 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _)) |
| 475 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, | 506 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, |
| 476 base::FilePath(kDummyPath))); | 507 base::FilePath())); |
| 477 EXPECT_CALL(*download_file, Cancel()); | 508 EXPECT_CALL(*download_file, Cancel()); |
| 478 | 509 |
| 479 // Complete download to trigger final rename. | 510 // Complete download to trigger final rename. |
| 480 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); | 511 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); |
| 481 RunAllPendingInMessageLoops(); | 512 RunAllPendingInMessageLoops(); |
| 482 | 513 |
| 483 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 514 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 484 // Should not try to auto-resume. | 515 // Should not try to auto-resume. |
| 485 ASSERT_EQ(1, observer.interrupt_count()); | 516 ASSERT_EQ(1, observer.interrupt_count()); |
| 486 ASSERT_EQ(0, observer.resume_count()); | 517 ASSERT_EQ(0, observer.resume_count()); |
| 487 | 518 |
| 488 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); | 519 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); |
| 489 } | 520 } |
| 490 | 521 |
| 491 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) { | 522 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) { |
| 492 TestBrowserContext test_browser_context; | 523 TestBrowserContext test_browser_context; |
| 493 DownloadItemImpl* item = CreateDownloadItem(); | 524 DownloadItemImpl* item = CreateDownloadItem(); |
| 494 base::WeakPtr<DownloadDestinationObserver> as_observer( | 525 base::WeakPtr<DownloadDestinationObserver> as_observer( |
| 495 item->DestinationObserverAsWeakPtr()); | 526 item->DestinationObserverAsWeakPtr()); |
| 496 TestDownloadItemObserver observer(item); | 527 TestDownloadItemObserver observer(item); |
| 497 MockDownloadFile* mock_download_file(NULL); | 528 MockDownloadFile* mock_download_file(nullptr); |
| 498 scoped_ptr<DownloadFile> download_file; | 529 scoped_ptr<DownloadFile> download_file; |
| 499 MockRequestHandle* mock_request_handle(NULL); | 530 MockRequestHandle* mock_request_handle(nullptr); |
| 500 scoped_ptr<DownloadRequestHandleInterface> request_handle; | 531 scoped_ptr<DownloadRequestHandleInterface> request_handle; |
| 501 DownloadItemImplDelegate::DownloadTargetCallback callback; | 532 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 502 | 533 |
| 503 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) | 534 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) |
| 504 .WillRepeatedly(SaveArg<1>(&callback)); | 535 .WillRepeatedly(SaveArg<1>(&callback)); |
| 505 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | 536 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
| 506 .WillRepeatedly(Return(&test_browser_context)); | 537 .WillRepeatedly(Return(&test_browser_context)); |
| 507 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)) | 538 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)) |
| 508 .Times(DownloadItemImpl::kMaxAutoResumeAttempts); | 539 .Times(DownloadItemImpl::kMaxAutoResumeAttempts); |
| 509 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { | 540 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { |
| 510 DVLOG(20) << "Loop iteration " << i; | 541 DVLOG(20) << "Loop iteration " << i; |
| 511 | 542 |
| 512 mock_download_file = new NiceMock<MockDownloadFile>; | 543 mock_download_file = new NiceMock<MockDownloadFile>; |
| 513 download_file.reset(mock_download_file); | 544 download_file.reset(mock_download_file); |
| 514 mock_request_handle = new NiceMock<MockRequestHandle>; | 545 mock_request_handle = new NiceMock<MockRequestHandle>; |
| 515 request_handle.reset(mock_request_handle); | 546 request_handle.reset(mock_request_handle); |
| 516 | 547 |
| 517 ON_CALL(*mock_download_file, FullPath()) | 548 ON_CALL(*mock_download_file, FullPath()) |
| 518 .WillByDefault(Return(base::FilePath())); | 549 .WillByDefault(Return(base::FilePath())); |
| 519 | 550 |
| 520 // Copied key parts of DoIntermediateRename & AddDownloadFileToDownloadItem | 551 // Copied key parts of DoIntermediateRename & CallDownloadItemStart |
| 521 // to allow for holding onto the request handle. | 552 // to allow for holding onto the request handle. |
| 522 item->Start(std::move(download_file), std::move(request_handle)); | 553 item->Start(std::move(download_file), std::move(request_handle)); |
| 523 RunAllPendingInMessageLoops(); | 554 RunAllPendingInMessageLoops(); |
| 555 |
| 556 base::FilePath target_path(kDummyTargetPath); |
| 557 base::FilePath intermediate_path(kDummyIntermediatePath); |
| 524 if (i == 0) { | 558 if (i == 0) { |
| 525 // Target determination is only done the first time through. | 559 // RenameAndUniquify is only called the first time. In all the subsequent |
| 526 base::FilePath target_path(kDummyPath); | 560 // iterations, the intermediate file already has the correct name, hence |
| 527 base::FilePath intermediate_path( | 561 // no rename is necessary. |
| 528 target_path.InsertBeforeExtensionASCII("x")); | |
| 529 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) | 562 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) |
| 530 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 563 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 531 intermediate_path)); | 564 intermediate_path)); |
| 532 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 533 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); | |
| 534 RunAllPendingInMessageLoops(); | |
| 535 } | 565 } |
| 566 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 567 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); |
| 568 RunAllPendingInMessageLoops(); |
| 536 | 569 |
| 537 // Use a continuable interrupt. | 570 // Use a continuable interrupt. |
| 538 item->DestinationObserverAsWeakPtr()->DestinationError( | 571 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 539 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 572 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
| 540 | 573 |
| 541 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); | 574 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); |
| 542 } | 575 } |
| 543 | 576 |
| 577 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 544 EXPECT_EQ(1, observer.interrupt_count()); | 578 EXPECT_EQ(1, observer.interrupt_count()); |
| 545 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); | 579 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); |
| 546 } | 580 } |
| 547 | 581 |
| 548 // Test that resumption uses the final URL in a URL chain when resuming. | 582 // Test that resumption uses the final URL in a URL chain when resuming. |
| 549 TEST_F(DownloadItemTest, ResumeUsingFinalURL) { | 583 TEST_F(DownloadItemTest, ResumeUsingFinalURL) { |
| 550 TestBrowserContext test_browser_context; | 584 TestBrowserContext test_browser_context; |
| 551 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo); | 585 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo); |
| 552 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); | 586 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); |
| 553 create_info->save_info->prompt_for_save_location = false; | 587 create_info->save_info->prompt_for_save_location = false; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 581 // ResumeInterruptedDownload() being called is sufficient for verifying that | 615 // ResumeInterruptedDownload() being called is sufficient for verifying that |
| 582 // the resumption was triggered. | 616 // the resumption was triggered. |
| 583 RunAllPendingInMessageLoops(); | 617 RunAllPendingInMessageLoops(); |
| 584 | 618 |
| 585 // The download is currently in RESUMING_INTERNAL, which maps to IN_PROGRESS. | 619 // The download is currently in RESUMING_INTERNAL, which maps to IN_PROGRESS. |
| 586 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); | 620 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); |
| 587 } | 621 } |
| 588 | 622 |
| 589 TEST_F(DownloadItemTest, NotificationAfterRemove) { | 623 TEST_F(DownloadItemTest, NotificationAfterRemove) { |
| 590 DownloadItemImpl* item = CreateDownloadItem(); | 624 DownloadItemImpl* item = CreateDownloadItem(); |
| 591 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL); | 625 MockDownloadFile* download_file = CallDownloadItemStart(item, nullptr); |
| 592 EXPECT_CALL(*download_file, Cancel()); | 626 EXPECT_CALL(*download_file, Cancel()); |
| 593 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); | 627 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); |
| 594 TestDownloadItemObserver observer(item); | 628 TestDownloadItemObserver observer(item); |
| 595 | 629 |
| 596 item->Remove(); | 630 item->Remove(); |
| 597 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 631 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 598 ASSERT_TRUE(observer.download_removed()); | 632 ASSERT_TRUE(observer.download_removed()); |
| 599 } | 633 } |
| 600 | 634 |
| 601 TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) { | 635 TEST_F(DownloadItemTest, NotificationAfterOnContentCheckCompleted) { |
| 602 // Setting to NOT_DANGEROUS does not trigger a notification. | 636 // Setting to NOT_DANGEROUS does not trigger a notification. |
| 603 DownloadItemImpl* safe_item = CreateDownloadItem(); | 637 DownloadItemImpl* safe_item = CreateDownloadItem(); |
| 638 MockDownloadFile* download_file = |
| 639 DoIntermediateRename(safe_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 604 TestDownloadItemObserver safe_observer(safe_item); | 640 TestDownloadItemObserver safe_observer(safe_item); |
| 605 | 641 |
| 606 safe_item->OnAllDataSaved(std::string()); | 642 safe_item->OnAllDataSaved(std::string()); |
| 607 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); | 643 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); |
| 608 safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 644 safe_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 609 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); | 645 EXPECT_TRUE(safe_observer.CheckAndResetDownloadUpdated()); |
| 646 CleanupItem(safe_item, download_file, DownloadItem::IN_PROGRESS); |
| 610 | 647 |
| 611 // Setting to unsafe url or unsafe file should trigger a notification. | 648 // Setting to unsafe url or unsafe file should trigger a notification. |
| 612 DownloadItemImpl* unsafeurl_item = | 649 DownloadItemImpl* unsafeurl_item = |
| 613 CreateDownloadItem(); | 650 CreateDownloadItem(); |
| 651 download_file = |
| 652 DoIntermediateRename(unsafeurl_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 614 TestDownloadItemObserver unsafeurl_observer(unsafeurl_item); | 653 TestDownloadItemObserver unsafeurl_observer(unsafeurl_item); |
| 615 | 654 |
| 616 unsafeurl_item->OnAllDataSaved(std::string()); | 655 unsafeurl_item->OnAllDataSaved(std::string()); |
| 617 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); | 656 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); |
| 618 unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL); | 657 unsafeurl_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_URL); |
| 619 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); | 658 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); |
| 620 | 659 |
| 660 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _)) |
| 661 .WillOnce(Return(true)); |
| 662 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)); |
| 621 unsafeurl_item->ValidateDangerousDownload(); | 663 unsafeurl_item->ValidateDangerousDownload(); |
| 622 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); | 664 EXPECT_TRUE(unsafeurl_observer.CheckAndResetDownloadUpdated()); |
| 665 CleanupItem(unsafeurl_item, download_file, DownloadItem::IN_PROGRESS); |
| 623 | 666 |
| 624 DownloadItemImpl* unsafefile_item = | 667 DownloadItemImpl* unsafefile_item = |
| 625 CreateDownloadItem(); | 668 CreateDownloadItem(); |
| 669 download_file = |
| 670 DoIntermediateRename(unsafefile_item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 626 TestDownloadItemObserver unsafefile_observer(unsafefile_item); | 671 TestDownloadItemObserver unsafefile_observer(unsafefile_item); |
| 627 | 672 |
| 628 unsafefile_item->OnAllDataSaved(std::string()); | 673 unsafefile_item->OnAllDataSaved(std::string()); |
| 629 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); | 674 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); |
| 630 unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | 675 unsafefile_item->OnContentCheckCompleted(DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); |
| 631 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); | 676 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); |
| 632 | 677 |
| 678 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _)) |
| 679 .WillOnce(Return(true)); |
| 680 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)); |
| 633 unsafefile_item->ValidateDangerousDownload(); | 681 unsafefile_item->ValidateDangerousDownload(); |
| 634 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); | 682 EXPECT_TRUE(unsafefile_observer.CheckAndResetDownloadUpdated()); |
| 683 CleanupItem(unsafefile_item, download_file, DownloadItem::IN_PROGRESS); |
| 635 } | 684 } |
| 636 | 685 |
| 637 // DownloadItemImpl::OnDownloadTargetDetermined will schedule a task to run | 686 // DownloadItemImpl::OnDownloadTargetDetermined will schedule a task to run |
| 638 // DownloadFile::Rename(). Once the rename | 687 // DownloadFile::Rename(). Once the rename |
| 639 // completes, DownloadItemImpl receives a notification with the new file | 688 // completes, DownloadItemImpl receives a notification with the new file |
| 640 // name. Check that observers are updated when the new filename is available and | 689 // name. Check that observers are updated when the new filename is available and |
| 641 // not before. | 690 // not before. |
| 642 TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) { | 691 TEST_F(DownloadItemTest, NotificationAfterOnDownloadTargetDetermined) { |
| 643 DownloadItemImpl* item = CreateDownloadItem(); | 692 DownloadItemImpl* item = CreateDownloadItem(); |
| 644 DownloadItemImplDelegate::DownloadTargetCallback callback; | 693 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 645 MockDownloadFile* download_file = | 694 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
| 646 AddDownloadFileToDownloadItem(item, &callback); | |
| 647 TestDownloadItemObserver observer(item); | 695 TestDownloadItemObserver observer(item); |
| 648 base::FilePath target_path(kDummyPath); | 696 base::FilePath target_path(kDummyTargetPath); |
| 649 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x")); | 697 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x")); |
| 650 base::FilePath new_intermediate_path( | 698 base::FilePath new_intermediate_path( |
| 651 target_path.InsertBeforeExtensionASCII("y")); | 699 target_path.InsertBeforeExtensionASCII("y")); |
| 652 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) | 700 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) |
| 653 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 701 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 654 new_intermediate_path)); | 702 new_intermediate_path)); |
| 655 | 703 |
| 656 // Currently, a notification would be generated if the danger type is anything | 704 // Currently, a notification would be generated if the danger type is anything |
| 657 // other than NOT_DANGEROUS. | 705 // other than NOT_DANGEROUS. |
| 658 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 706 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 686 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 734 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 687 | 735 |
| 688 RunAllPendingInMessageLoops(); | 736 RunAllPendingInMessageLoops(); |
| 689 | 737 |
| 690 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); | 738 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); |
| 691 } | 739 } |
| 692 | 740 |
| 693 TEST_F(DownloadItemTest, DisplayName) { | 741 TEST_F(DownloadItemTest, DisplayName) { |
| 694 DownloadItemImpl* item = CreateDownloadItem(); | 742 DownloadItemImpl* item = CreateDownloadItem(); |
| 695 DownloadItemImplDelegate::DownloadTargetCallback callback; | 743 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 696 MockDownloadFile* download_file = | 744 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
| 697 AddDownloadFileToDownloadItem(item, &callback); | 745 base::FilePath target_path( |
| 698 base::FilePath target_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); | 746 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); |
| 699 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x")); | 747 base::FilePath intermediate_path(target_path.InsertBeforeExtensionASCII("x")); |
| 700 EXPECT_EQ(FILE_PATH_LITERAL(""), | 748 EXPECT_EQ(FILE_PATH_LITERAL(""), |
| 701 item->GetFileNameToReportUser().value()); | 749 item->GetFileNameToReportUser().value()); |
| 702 EXPECT_CALL(*download_file, RenameAndUniquify(_, _)) | 750 EXPECT_CALL(*download_file, RenameAndUniquify(_, _)) |
| 703 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 751 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 704 intermediate_path)); | 752 intermediate_path)); |
| 705 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 753 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 706 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); | 754 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); |
| 707 RunAllPendingInMessageLoops(); | 755 RunAllPendingInMessageLoops(); |
| 708 EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"), | 756 EXPECT_EQ(FILE_PATH_LITERAL("foo.bar"), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 721 EXPECT_CALL(*mock_download_file, Initialize(_)); | 769 EXPECT_CALL(*mock_download_file, Initialize(_)); |
| 722 scoped_ptr<DownloadRequestHandleInterface> request_handle( | 770 scoped_ptr<DownloadRequestHandleInterface> request_handle( |
| 723 new NiceMock<MockRequestHandle>); | 771 new NiceMock<MockRequestHandle>); |
| 724 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); | 772 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); |
| 725 item->Start(std::move(download_file), std::move(request_handle)); | 773 item->Start(std::move(download_file), std::move(request_handle)); |
| 726 RunAllPendingInMessageLoops(); | 774 RunAllPendingInMessageLoops(); |
| 727 | 775 |
| 728 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); | 776 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); |
| 729 } | 777 } |
| 730 | 778 |
| 779 // Download file and the request should be cancelled as a result of download |
| 780 // file initialization failing. |
| 781 TEST_F(DownloadItemTest, InitDownloadFileFails) { |
| 782 scoped_ptr<MockDownloadFile> file(new MockDownloadFile()); |
| 783 scoped_ptr<MockRequestHandle> request_handle(new MockRequestHandle()); |
| 784 EXPECT_CALL(*file, Cancel()); |
| 785 EXPECT_CALL(*request_handle, CancelRequest()); |
| 786 EXPECT_CALL(*file, Initialize(_)) |
| 787 .WillOnce(ScheduleCallbackWithParam( |
| 788 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED)); |
| 789 |
| 790 DownloadItemImpl* item = CreateDownloadItem(); |
| 791 item->Start(std::move(file), std::move(request_handle)); |
| 792 RunAllPendingInMessageLoops(); |
| 793 |
| 794 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 795 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, |
| 796 item->GetLastReason()); |
| 797 } |
| 798 |
| 731 // Test that the delegate is invoked after the download file is renamed. | 799 // Test that the delegate is invoked after the download file is renamed. |
| 732 TEST_F(DownloadItemTest, CallbackAfterRename) { | 800 TEST_F(DownloadItemTest, CallbackAfterRename) { |
| 733 DownloadItemImpl* item = CreateDownloadItem(); | 801 DownloadItemImpl* item = CreateDownloadItem(); |
| 734 DownloadItemImplDelegate::DownloadTargetCallback callback; | 802 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 735 MockDownloadFile* download_file = | 803 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
| 736 AddDownloadFileToDownloadItem(item, &callback); | 804 base::FilePath final_path( |
| 737 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); | 805 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); |
| 738 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 806 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
| 739 base::FilePath new_intermediate_path( | 807 base::FilePath new_intermediate_path( |
| 740 final_path.InsertBeforeExtensionASCII("y")); | 808 final_path.InsertBeforeExtensionASCII("y")); |
| 741 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) | 809 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) |
| 742 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 810 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 743 new_intermediate_path)); | 811 new_intermediate_path)); |
| 744 | 812 |
| 745 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 813 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 746 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); | 814 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); |
| 747 RunAllPendingInMessageLoops(); | 815 RunAllPendingInMessageLoops(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 761 RunAllPendingInMessageLoops(); | 829 RunAllPendingInMessageLoops(); |
| 762 ::testing::Mock::VerifyAndClearExpectations(download_file); | 830 ::testing::Mock::VerifyAndClearExpectations(download_file); |
| 763 mock_delegate()->VerifyAndClearExpectations(); | 831 mock_delegate()->VerifyAndClearExpectations(); |
| 764 } | 832 } |
| 765 | 833 |
| 766 // Test that the delegate is invoked after the download file is renamed and the | 834 // Test that the delegate is invoked after the download file is renamed and the |
| 767 // download item is in an interrupted state. | 835 // download item is in an interrupted state. |
| 768 TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) { | 836 TEST_F(DownloadItemTest, CallbackAfterInterruptedRename) { |
| 769 DownloadItemImpl* item = CreateDownloadItem(); | 837 DownloadItemImpl* item = CreateDownloadItem(); |
| 770 DownloadItemImplDelegate::DownloadTargetCallback callback; | 838 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 771 MockDownloadFile* download_file = | 839 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
| 772 AddDownloadFileToDownloadItem(item, &callback); | 840 base::FilePath final_path( |
| 773 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); | 841 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); |
| 774 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 842 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
| 775 base::FilePath new_intermediate_path( | 843 base::FilePath new_intermediate_path( |
| 776 final_path.InsertBeforeExtensionASCII("y")); | 844 final_path.InsertBeforeExtensionASCII("y")); |
| 777 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) | 845 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) |
| 778 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, | 846 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, |
| 779 new_intermediate_path)); | 847 new_intermediate_path)); |
| 780 EXPECT_CALL(*download_file, Cancel()) | 848 EXPECT_CALL(*download_file, Cancel()) |
| 781 .Times(1); | 849 .Times(1); |
| 782 | 850 |
| 783 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 851 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 807 item->Cancel(true); | 875 item->Cancel(true); |
| 808 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); | 876 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); |
| 809 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, item->GetLastReason()); | 877 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, item->GetLastReason()); |
| 810 } | 878 } |
| 811 | 879 |
| 812 // Destination errors that occur before the intermediate rename shouldn't cause | 880 // Destination errors that occur before the intermediate rename shouldn't cause |
| 813 // the download to be marked as interrupted until after the intermediate rename. | 881 // the download to be marked as interrupted until after the intermediate rename. |
| 814 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) { | 882 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Restart) { |
| 815 DownloadItemImpl* item = CreateDownloadItem(); | 883 DownloadItemImpl* item = CreateDownloadItem(); |
| 816 DownloadItemImplDelegate::DownloadTargetCallback callback; | 884 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 817 MockDownloadFile* download_file = | 885 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
| 818 AddDownloadFileToDownloadItem(item, &callback); | |
| 819 item->DestinationObserverAsWeakPtr()->DestinationError( | 886 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 820 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 887 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
| 821 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 888 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 822 | 889 |
| 823 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); | 890 base::FilePath final_path( |
| 891 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); |
| 824 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 892 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
| 825 base::FilePath new_intermediate_path( | 893 base::FilePath new_intermediate_path( |
| 826 final_path.InsertBeforeExtensionASCII("y")); | 894 final_path.InsertBeforeExtensionASCII("y")); |
| 827 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) | 895 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) |
| 828 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 896 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 829 new_intermediate_path)); | 897 new_intermediate_path)); |
| 830 EXPECT_CALL(*download_file, Cancel()) | 898 EXPECT_CALL(*download_file, Cancel()) |
| 831 .Times(1); | 899 .Times(1); |
| 832 | 900 |
| 833 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 901 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 834 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); | 902 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); |
| 835 RunAllPendingInMessageLoops(); | 903 RunAllPendingInMessageLoops(); |
| 836 // All the callbacks should have happened by now. | 904 // All the callbacks should have happened by now. |
| 837 ::testing::Mock::VerifyAndClearExpectations(download_file); | 905 ::testing::Mock::VerifyAndClearExpectations(download_file); |
| 838 mock_delegate()->VerifyAndClearExpectations(); | 906 mock_delegate()->VerifyAndClearExpectations(); |
| 839 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 907 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 840 EXPECT_TRUE(item->GetFullPath().empty()); | 908 EXPECT_TRUE(item->GetFullPath().empty()); |
| 841 EXPECT_EQ(final_path, item->GetTargetFilePath()); | 909 EXPECT_EQ(final_path, item->GetTargetFilePath()); |
| 842 } | 910 } |
| 843 | 911 |
| 844 // As above. But if the download can be resumed by continuing, then the | 912 // As above. But if the download can be resumed by continuing, then the |
| 845 // intermediate path should be retained when the download is interrupted after | 913 // intermediate path should be retained when the download is interrupted after |
| 846 // the intermediate rename succeeds. | 914 // the intermediate rename succeeds. |
| 847 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) { | 915 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) { |
| 848 DownloadItemImpl* item = CreateDownloadItem(); | 916 DownloadItemImpl* item = CreateDownloadItem(); |
| 849 DownloadItemImplDelegate::DownloadTargetCallback callback; | 917 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 850 MockDownloadFile* download_file = | 918 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
| 851 AddDownloadFileToDownloadItem(item, &callback); | |
| 852 item->DestinationObserverAsWeakPtr()->DestinationError( | 919 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 853 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); | 920 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); |
| 854 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 921 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 855 | 922 |
| 856 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); | 923 base::FilePath final_path( |
| 924 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); |
| 857 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 925 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
| 858 base::FilePath new_intermediate_path( | 926 base::FilePath new_intermediate_path( |
| 859 final_path.InsertBeforeExtensionASCII("y")); | 927 final_path.InsertBeforeExtensionASCII("y")); |
| 860 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) | 928 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) |
| 861 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 929 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 862 new_intermediate_path)); | 930 new_intermediate_path)); |
| 863 EXPECT_CALL(*download_file, FullPath()) | 931 EXPECT_CALL(*download_file, FullPath()) |
| 864 .WillOnce(Return(base::FilePath(new_intermediate_path))); | 932 .WillOnce(Return(base::FilePath(new_intermediate_path))); |
| 865 EXPECT_CALL(*download_file, Detach()); | 933 EXPECT_CALL(*download_file, Detach()); |
| 866 | 934 |
| 867 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 935 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 868 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); | 936 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); |
| 869 RunAllPendingInMessageLoops(); | 937 RunAllPendingInMessageLoops(); |
| 870 // All the callbacks should have happened by now. | 938 // All the callbacks should have happened by now. |
| 871 ::testing::Mock::VerifyAndClearExpectations(download_file); | 939 ::testing::Mock::VerifyAndClearExpectations(download_file); |
| 872 mock_delegate()->VerifyAndClearExpectations(); | 940 mock_delegate()->VerifyAndClearExpectations(); |
| 873 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 941 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 874 EXPECT_EQ(new_intermediate_path, item->GetFullPath()); | 942 EXPECT_EQ(new_intermediate_path, item->GetFullPath()); |
| 875 EXPECT_EQ(final_path, item->GetTargetFilePath()); | 943 EXPECT_EQ(final_path, item->GetTargetFilePath()); |
| 876 } | 944 } |
| 877 | 945 |
| 878 // As above. If the intermediate rename fails, then the interrupt reason should | 946 // As above. If the intermediate rename fails, then the interrupt reason should |
| 879 // be set to the destination error and the intermediate path should be empty. | 947 // be set to the destination error and the intermediate path should be empty. |
| 880 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) { | 948 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) { |
| 881 DownloadItemImpl* item = CreateDownloadItem(); | 949 DownloadItemImpl* item = CreateDownloadItem(); |
| 882 DownloadItemImplDelegate::DownloadTargetCallback callback; | 950 DownloadItemImplDelegate::DownloadTargetCallback callback; |
| 883 MockDownloadFile* download_file = | 951 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
| 884 AddDownloadFileToDownloadItem(item, &callback); | |
| 885 item->DestinationObserverAsWeakPtr()->DestinationError( | 952 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 886 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); | 953 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); |
| 887 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 954 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 888 | 955 |
| 889 base::FilePath final_path(base::FilePath(kDummyPath).AppendASCII("foo.bar")); | 956 base::FilePath final_path( |
| 957 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); |
| 890 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 958 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
| 891 base::FilePath new_intermediate_path( | 959 base::FilePath new_intermediate_path( |
| 892 final_path.InsertBeforeExtensionASCII("y")); | 960 final_path.InsertBeforeExtensionASCII("y")); |
| 893 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) | 961 EXPECT_CALL(*download_file, RenameAndUniquify(intermediate_path, _)) |
| 894 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, | 962 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, |
| 895 new_intermediate_path)); | 963 new_intermediate_path)); |
| 896 EXPECT_CALL(*download_file, Cancel()) | 964 EXPECT_CALL(*download_file, Cancel()) |
| 897 .Times(1); | 965 .Times(1); |
| 898 | 966 |
| 899 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 967 callback.Run(final_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 900 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); | 968 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); |
| 901 RunAllPendingInMessageLoops(); | 969 RunAllPendingInMessageLoops(); |
| 902 // All the callbacks should have happened by now. | 970 // All the callbacks should have happened by now. |
| 903 ::testing::Mock::VerifyAndClearExpectations(download_file); | 971 ::testing::Mock::VerifyAndClearExpectations(download_file); |
| 904 mock_delegate()->VerifyAndClearExpectations(); | 972 mock_delegate()->VerifyAndClearExpectations(); |
| 905 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 973 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 906 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason()); | 974 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason()); |
| 907 EXPECT_TRUE(item->GetFullPath().empty()); | 975 EXPECT_TRUE(item->GetFullPath().empty()); |
| 908 EXPECT_EQ(final_path, item->GetTargetFilePath()); | 976 EXPECT_EQ(final_path, item->GetTargetFilePath()); |
| 909 } | 977 } |
| 910 | 978 |
| 911 TEST_F(DownloadItemTest, Canceled) { | 979 TEST_F(DownloadItemTest, Canceled) { |
| 912 DownloadItemImpl* item = CreateDownloadItem(); | 980 DownloadItemImpl* item = CreateDownloadItem(); |
| 913 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL); | 981 MockDownloadFile* download_file = CallDownloadItemStart(item, nullptr); |
| 914 | 982 |
| 915 // Confirm cancel sets state properly. | 983 // Confirm cancel sets state properly. |
| 916 EXPECT_CALL(*download_file, Cancel()); | 984 EXPECT_CALL(*download_file, Cancel()); |
| 917 item->Cancel(true); | 985 item->Cancel(true); |
| 918 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); | 986 EXPECT_EQ(DownloadItem::CANCELLED, item->GetState()); |
| 919 } | 987 } |
| 920 | 988 |
| 921 TEST_F(DownloadItemTest, FileRemoved) { | 989 TEST_F(DownloadItemTest, FileRemoved) { |
| 922 DownloadItemImpl* item = CreateDownloadItem(); | 990 DownloadItemImpl* item = CreateDownloadItem(); |
| 923 | 991 |
| 924 EXPECT_FALSE(item->GetFileExternallyRemoved()); | 992 EXPECT_FALSE(item->GetFileExternallyRemoved()); |
| 925 item->OnDownloadedFileRemoved(); | 993 item->OnDownloadedFileRemoved(); |
| 926 EXPECT_TRUE(item->GetFileExternallyRemoved()); | 994 EXPECT_TRUE(item->GetFileExternallyRemoved()); |
| 927 } | 995 } |
| 928 | 996 |
| 929 TEST_F(DownloadItemTest, DestinationUpdate) { | 997 TEST_F(DownloadItemTest, DestinationUpdate) { |
| 930 DownloadItemImpl* item = CreateDownloadItem(); | 998 DownloadItemImpl* item = CreateDownloadItem(); |
| 999 MockDownloadFile* file = |
| 1000 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 931 base::WeakPtr<DownloadDestinationObserver> as_observer( | 1001 base::WeakPtr<DownloadDestinationObserver> as_observer( |
| 932 item->DestinationObserverAsWeakPtr()); | 1002 item->DestinationObserverAsWeakPtr()); |
| 933 TestDownloadItemObserver observer(item); | 1003 TestDownloadItemObserver observer(item); |
| 934 | 1004 |
| 935 EXPECT_EQ(0l, item->CurrentSpeed()); | 1005 EXPECT_EQ(0l, item->CurrentSpeed()); |
| 936 EXPECT_EQ("", item->GetHashState()); | 1006 EXPECT_EQ("", item->GetHashState()); |
| 937 EXPECT_EQ(0l, item->GetReceivedBytes()); | 1007 EXPECT_EQ(0l, item->GetReceivedBytes()); |
| 938 EXPECT_EQ(0l, item->GetTotalBytes()); | 1008 EXPECT_EQ(0l, item->GetTotalBytes()); |
| 939 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); | 1009 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); |
| 940 item->SetTotalBytes(100l); | 1010 item->SetTotalBytes(100l); |
| 941 EXPECT_EQ(100l, item->GetTotalBytes()); | 1011 EXPECT_EQ(100l, item->GetTotalBytes()); |
| 942 | 1012 |
| 943 as_observer->DestinationUpdate(10, 20, "deadbeef"); | 1013 as_observer->DestinationUpdate(10, 20, "deadbeef"); |
| 944 EXPECT_EQ(20l, item->CurrentSpeed()); | 1014 EXPECT_EQ(20l, item->CurrentSpeed()); |
| 945 EXPECT_EQ("deadbeef", item->GetHashState()); | 1015 EXPECT_EQ("deadbeef", item->GetHashState()); |
| 946 EXPECT_EQ(10l, item->GetReceivedBytes()); | 1016 EXPECT_EQ(10l, item->GetReceivedBytes()); |
| 947 EXPECT_EQ(100l, item->GetTotalBytes()); | 1017 EXPECT_EQ(100l, item->GetTotalBytes()); |
| 948 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); | 1018 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 949 | 1019 |
| 950 as_observer->DestinationUpdate(200, 20, "livebeef"); | 1020 as_observer->DestinationUpdate(200, 20, "livebeef"); |
| 951 EXPECT_EQ(20l, item->CurrentSpeed()); | 1021 EXPECT_EQ(20l, item->CurrentSpeed()); |
| 952 EXPECT_EQ("livebeef", item->GetHashState()); | 1022 EXPECT_EQ("livebeef", item->GetHashState()); |
| 953 EXPECT_EQ(200l, item->GetReceivedBytes()); | 1023 EXPECT_EQ(200l, item->GetReceivedBytes()); |
| 954 EXPECT_EQ(0l, item->GetTotalBytes()); | 1024 EXPECT_EQ(0l, item->GetTotalBytes()); |
| 955 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); | 1025 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 1026 |
| 1027 CleanupItem(item, file, DownloadItem::IN_PROGRESS); |
| 956 } | 1028 } |
| 957 | 1029 |
| 958 TEST_F(DownloadItemTest, DestinationError) { | 1030 TEST_F(DownloadItemTest, DestinationError) { |
| 959 DownloadItemImpl* item = CreateDownloadItem(); | 1031 DownloadItemImpl* item = CreateDownloadItem(); |
| 960 MockDownloadFile* download_file = | 1032 MockDownloadFile* download_file = |
| 961 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 1033 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 962 base::WeakPtr<DownloadDestinationObserver> as_observer( | 1034 base::WeakPtr<DownloadDestinationObserver> as_observer( |
| 963 item->DestinationObserverAsWeakPtr()); | 1035 item->DestinationObserverAsWeakPtr()); |
| 964 TestDownloadItemObserver observer(item); | 1036 TestDownloadItemObserver observer(item); |
| 965 | 1037 |
| 966 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1038 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 967 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason()); | 1039 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, item->GetLastReason()); |
| 968 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); | 1040 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); |
| 969 | 1041 |
| 970 EXPECT_CALL(*download_file, Cancel()); | 1042 EXPECT_CALL(*download_file, Cancel()); |
| 971 as_observer->DestinationError( | 1043 as_observer->DestinationError( |
| 972 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); | 1044 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); |
| 973 mock_delegate()->VerifyAndClearExpectations(); | 1045 mock_delegate()->VerifyAndClearExpectations(); |
| 974 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); | 1046 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 975 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 1047 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 976 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, | 1048 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, |
| 977 item->GetLastReason()); | 1049 item->GetLastReason()); |
| 978 } | 1050 } |
| 979 | 1051 |
| 980 TEST_F(DownloadItemTest, DestinationCompleted) { | 1052 TEST_F(DownloadItemTest, DestinationCompleted) { |
| 981 DownloadItemImpl* item = CreateDownloadItem(); | 1053 DownloadItemImpl* item = CreateDownloadItem(); |
| 1054 MockDownloadFile* download_file = CallDownloadItemStart(item, nullptr); |
| 982 base::WeakPtr<DownloadDestinationObserver> as_observer( | 1055 base::WeakPtr<DownloadDestinationObserver> as_observer( |
| 983 item->DestinationObserverAsWeakPtr()); | 1056 item->DestinationObserverAsWeakPtr()); |
| 984 TestDownloadItemObserver observer(item); | 1057 TestDownloadItemObserver observer(item); |
| 985 | 1058 |
| 986 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1059 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 987 EXPECT_EQ("", item->GetHash()); | 1060 EXPECT_EQ("", item->GetHash()); |
| 988 EXPECT_EQ("", item->GetHashState()); | 1061 EXPECT_EQ("", item->GetHashState()); |
| 989 EXPECT_FALSE(item->AllDataSaved()); | 1062 EXPECT_FALSE(item->AllDataSaved()); |
| 990 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); | 1063 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); |
| 991 | 1064 |
| 992 as_observer->DestinationUpdate(10, 20, "deadbeef"); | 1065 as_observer->DestinationUpdate(10, 20, "deadbeef"); |
| 993 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); | 1066 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 994 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); // Confirm reset. | 1067 EXPECT_FALSE(observer.CheckAndResetDownloadUpdated()); // Confirm reset. |
| 995 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1068 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 996 EXPECT_EQ("", item->GetHash()); | 1069 EXPECT_EQ("", item->GetHash()); |
| 997 EXPECT_EQ("deadbeef", item->GetHashState()); | 1070 EXPECT_EQ("deadbeef", item->GetHashState()); |
| 998 EXPECT_FALSE(item->AllDataSaved()); | 1071 EXPECT_FALSE(item->AllDataSaved()); |
| 999 | 1072 |
| 1000 as_observer->DestinationCompleted("livebeef"); | 1073 as_observer->DestinationCompleted("livebeef"); |
| 1001 mock_delegate()->VerifyAndClearExpectations(); | 1074 mock_delegate()->VerifyAndClearExpectations(); |
| 1002 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1075 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 1003 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); | 1076 EXPECT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 1004 EXPECT_EQ("livebeef", item->GetHash()); | 1077 EXPECT_EQ("livebeef", item->GetHash()); |
| 1005 EXPECT_EQ("", item->GetHashState()); | 1078 EXPECT_EQ("", item->GetHashState()); |
| 1006 EXPECT_TRUE(item->AllDataSaved()); | 1079 EXPECT_TRUE(item->AllDataSaved()); |
| 1080 |
| 1081 // Even though the DownloadItem receives a DestinationCompleted() event, |
| 1082 // target determination hasn't completed, hence the download item is stuck in |
| 1083 // TARGET_PENDING. |
| 1084 CleanupItem(item, download_file, DownloadItem::IN_PROGRESS); |
| 1007 } | 1085 } |
| 1008 | 1086 |
| 1009 TEST_F(DownloadItemTest, EnabledActionsForNormalDownload) { | 1087 TEST_F(DownloadItemTest, EnabledActionsForNormalDownload) { |
| 1010 DownloadItemImpl* item = CreateDownloadItem(); | 1088 DownloadItemImpl* item = CreateDownloadItem(); |
| 1011 MockDownloadFile* download_file = | 1089 MockDownloadFile* download_file = |
| 1012 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 1090 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 1013 | 1091 |
| 1014 // InProgress | 1092 // InProgress |
| 1015 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1093 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 1016 ASSERT_FALSE(item->GetTargetFilePath().empty()); | 1094 ASSERT_FALSE(item->GetTargetFilePath().empty()); |
| 1017 EXPECT_TRUE(item->CanShowInFolder()); | 1095 EXPECT_TRUE(item->CanShowInFolder()); |
| 1018 EXPECT_TRUE(item->CanOpenDownload()); | 1096 EXPECT_TRUE(item->CanOpenDownload()); |
| 1019 | 1097 |
| 1020 // Complete | 1098 // Complete |
| 1021 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) | 1099 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) |
| 1022 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 1100 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 1023 base::FilePath(kDummyPath))); | 1101 base::FilePath(kDummyTargetPath))); |
| 1024 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) | 1102 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 1025 .WillOnce(Return(true)); | 1103 .WillOnce(Return(true)); |
| 1026 EXPECT_CALL(*download_file, FullPath()) | 1104 EXPECT_CALL(*download_file, FullPath()) |
| 1027 .WillOnce(Return(base::FilePath())); | 1105 .WillOnce(Return(base::FilePath())); |
| 1028 EXPECT_CALL(*download_file, Detach()); | 1106 EXPECT_CALL(*download_file, Detach()); |
| 1029 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); | 1107 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); |
| 1030 RunAllPendingInMessageLoops(); | 1108 RunAllPendingInMessageLoops(); |
| 1031 | 1109 |
| 1032 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState()); | 1110 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState()); |
| 1033 EXPECT_TRUE(item->CanShowInFolder()); | 1111 EXPECT_TRUE(item->CanShowInFolder()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1045 ASSERT_FALSE(item->GetTargetFilePath().empty()); | 1123 ASSERT_FALSE(item->GetTargetFilePath().empty()); |
| 1046 ASSERT_TRUE(item->IsTemporary()); | 1124 ASSERT_TRUE(item->IsTemporary()); |
| 1047 EXPECT_FALSE(item->CanShowInFolder()); | 1125 EXPECT_FALSE(item->CanShowInFolder()); |
| 1048 EXPECT_FALSE(item->CanOpenDownload()); | 1126 EXPECT_FALSE(item->CanOpenDownload()); |
| 1049 | 1127 |
| 1050 // Complete Temporary | 1128 // Complete Temporary |
| 1051 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) | 1129 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 1052 .WillOnce(Return(true)); | 1130 .WillOnce(Return(true)); |
| 1053 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) | 1131 EXPECT_CALL(*download_file, RenameAndAnnotate(_, _)) |
| 1054 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 1132 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 1055 base::FilePath(kDummyPath))); | 1133 base::FilePath(kDummyTargetPath))); |
| 1056 EXPECT_CALL(*download_file, FullPath()) | 1134 EXPECT_CALL(*download_file, FullPath()) |
| 1057 .WillOnce(Return(base::FilePath())); | 1135 .WillOnce(Return(base::FilePath())); |
| 1058 EXPECT_CALL(*download_file, Detach()); | 1136 EXPECT_CALL(*download_file, Detach()); |
| 1059 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); | 1137 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); |
| 1060 RunAllPendingInMessageLoops(); | 1138 RunAllPendingInMessageLoops(); |
| 1061 | 1139 |
| 1062 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState()); | 1140 ASSERT_EQ(DownloadItem::COMPLETE, item->GetState()); |
| 1063 EXPECT_FALSE(item->CanShowInFolder()); | 1141 EXPECT_FALSE(item->CanShowInFolder()); |
| 1064 EXPECT_FALSE(item->CanOpenDownload()); | 1142 EXPECT_FALSE(item->CanOpenDownload()); |
| 1065 } | 1143 } |
| 1066 | 1144 |
| 1067 TEST_F(DownloadItemTest, EnabledActionsForInterruptedDownload) { | 1145 TEST_F(DownloadItemTest, EnabledActionsForInterruptedDownload) { |
| 1068 DownloadItemImpl* item = CreateDownloadItem(); | 1146 DownloadItemImpl* item = CreateDownloadItem(); |
| 1069 MockDownloadFile* download_file = | 1147 MockDownloadFile* download_file = |
| 1070 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 1148 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 1071 | 1149 |
| 1072 EXPECT_CALL(*download_file, Cancel()); | 1150 EXPECT_CALL(*download_file, Cancel()); |
| 1073 item->DestinationObserverAsWeakPtr()->DestinationError( | 1151 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 1074 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 1152 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
| 1075 RunAllPendingInMessageLoops(); | 1153 RunAllPendingInMessageLoops(); |
| 1076 | 1154 |
| 1077 ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 1155 ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
| 1078 ASSERT_FALSE(item->GetTargetFilePath().empty()); | 1156 ASSERT_FALSE(item->GetTargetFilePath().empty()); |
| 1079 EXPECT_FALSE(item->CanShowInFolder()); | 1157 EXPECT_FALSE(item->CanShowInFolder()); |
| 1080 EXPECT_FALSE(item->CanOpenDownload()); | 1158 EXPECT_TRUE(item->CanOpenDownload()); |
| 1081 } | 1159 } |
| 1082 | 1160 |
| 1083 TEST_F(DownloadItemTest, EnabledActionsForCancelledDownload) { | 1161 TEST_F(DownloadItemTest, EnabledActionsForCancelledDownload) { |
| 1084 DownloadItemImpl* item = CreateDownloadItem(); | 1162 DownloadItemImpl* item = CreateDownloadItem(); |
| 1085 MockDownloadFile* download_file = | 1163 MockDownloadFile* download_file = |
| 1086 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 1164 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 1087 | 1165 |
| 1088 EXPECT_CALL(*download_file, Cancel()); | 1166 EXPECT_CALL(*download_file, Cancel()); |
| 1089 item->Cancel(true); | 1167 item->Cancel(true); |
| 1090 RunAllPendingInMessageLoops(); | 1168 RunAllPendingInMessageLoops(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1105 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 1183 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 1106 | 1184 |
| 1107 // Drive the delegate interaction. | 1185 // Drive the delegate interaction. |
| 1108 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) | 1186 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 1109 .WillOnce(Return(true)); | 1187 .WillOnce(Return(true)); |
| 1110 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); | 1188 item->DestinationObserverAsWeakPtr()->DestinationCompleted(std::string()); |
| 1111 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1189 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 1112 EXPECT_FALSE(item->IsDangerous()); | 1190 EXPECT_FALSE(item->IsDangerous()); |
| 1113 | 1191 |
| 1114 // Make sure the download can complete. | 1192 // Make sure the download can complete. |
| 1115 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) | 1193 EXPECT_CALL(*download_file, |
| 1194 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _)) |
| 1116 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 1195 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 1117 base::FilePath(kDummyPath))); | 1196 base::FilePath(kDummyTargetPath))); |
| 1118 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) | 1197 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 1119 .WillOnce(Return(true)); | 1198 .WillOnce(Return(true)); |
| 1120 EXPECT_CALL(*download_file, FullPath()) | 1199 EXPECT_CALL(*download_file, FullPath()) |
| 1121 .WillOnce(Return(base::FilePath())); | 1200 .WillOnce(Return(base::FilePath())); |
| 1122 EXPECT_CALL(*download_file, Detach()); | 1201 EXPECT_CALL(*download_file, Detach()); |
| 1123 RunAllPendingInMessageLoops(); | 1202 RunAllPendingInMessageLoops(); |
| 1124 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); | 1203 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); |
| 1125 } | 1204 } |
| 1126 | 1205 |
| 1127 // Just delaying completion. | 1206 // Just delaying completion. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1143 ASSERT_FALSE(delegate_callback.is_null()); | 1222 ASSERT_FALSE(delegate_callback.is_null()); |
| 1144 copy_delegate_callback = delegate_callback; | 1223 copy_delegate_callback = delegate_callback; |
| 1145 delegate_callback.Reset(); | 1224 delegate_callback.Reset(); |
| 1146 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1225 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 1147 copy_delegate_callback.Run(); | 1226 copy_delegate_callback.Run(); |
| 1148 ASSERT_TRUE(delegate_callback.is_null()); | 1227 ASSERT_TRUE(delegate_callback.is_null()); |
| 1149 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1228 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 1150 EXPECT_FALSE(item->IsDangerous()); | 1229 EXPECT_FALSE(item->IsDangerous()); |
| 1151 | 1230 |
| 1152 // Make sure the download can complete. | 1231 // Make sure the download can complete. |
| 1153 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) | 1232 EXPECT_CALL(*download_file, |
| 1233 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _)) |
| 1154 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 1234 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 1155 base::FilePath(kDummyPath))); | 1235 base::FilePath(kDummyTargetPath))); |
| 1156 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) | 1236 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 1157 .WillOnce(Return(true)); | 1237 .WillOnce(Return(true)); |
| 1158 EXPECT_CALL(*download_file, FullPath()) | 1238 EXPECT_CALL(*download_file, FullPath()) |
| 1159 .WillOnce(Return(base::FilePath())); | 1239 .WillOnce(Return(base::FilePath())); |
| 1160 EXPECT_CALL(*download_file, Detach()); | 1240 EXPECT_CALL(*download_file, Detach()); |
| 1161 RunAllPendingInMessageLoops(); | 1241 RunAllPendingInMessageLoops(); |
| 1162 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); | 1242 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); |
| 1163 } | 1243 } |
| 1164 | 1244 |
| 1165 // Delay and set danger. | 1245 // Delay and set danger. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1184 EXPECT_FALSE(item->IsDangerous()); | 1264 EXPECT_FALSE(item->IsDangerous()); |
| 1185 item->OnContentCheckCompleted( | 1265 item->OnContentCheckCompleted( |
| 1186 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | 1266 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); |
| 1187 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1267 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 1188 copy_delegate_callback.Run(); | 1268 copy_delegate_callback.Run(); |
| 1189 ASSERT_TRUE(delegate_callback.is_null()); | 1269 ASSERT_TRUE(delegate_callback.is_null()); |
| 1190 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1270 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 1191 EXPECT_TRUE(item->IsDangerous()); | 1271 EXPECT_TRUE(item->IsDangerous()); |
| 1192 | 1272 |
| 1193 // Make sure the download doesn't complete until we've validated it. | 1273 // Make sure the download doesn't complete until we've validated it. |
| 1194 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) | 1274 EXPECT_CALL(*download_file, |
| 1275 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _)) |
| 1195 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 1276 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 1196 base::FilePath(kDummyPath))); | 1277 base::FilePath(kDummyTargetPath))); |
| 1197 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) | 1278 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 1198 .WillOnce(Return(true)); | 1279 .WillOnce(Return(true)); |
| 1199 EXPECT_CALL(*download_file, FullPath()) | 1280 EXPECT_CALL(*download_file, FullPath()) |
| 1200 .WillOnce(Return(base::FilePath())); | 1281 .WillOnce(Return(base::FilePath())); |
| 1201 EXPECT_CALL(*download_file, Detach()); | 1282 EXPECT_CALL(*download_file, Detach()); |
| 1202 RunAllPendingInMessageLoops(); | 1283 RunAllPendingInMessageLoops(); |
| 1203 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1284 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 1204 EXPECT_TRUE(item->IsDangerous()); | 1285 EXPECT_TRUE(item->IsDangerous()); |
| 1205 | 1286 |
| 1206 item->ValidateDangerousDownload(); | 1287 item->ValidateDangerousDownload(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1235 ASSERT_FALSE(delegate_callback.is_null()); | 1316 ASSERT_FALSE(delegate_callback.is_null()); |
| 1236 copy_delegate_callback = delegate_callback; | 1317 copy_delegate_callback = delegate_callback; |
| 1237 delegate_callback.Reset(); | 1318 delegate_callback.Reset(); |
| 1238 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1319 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 1239 copy_delegate_callback.Run(); | 1320 copy_delegate_callback.Run(); |
| 1240 ASSERT_TRUE(delegate_callback.is_null()); | 1321 ASSERT_TRUE(delegate_callback.is_null()); |
| 1241 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1322 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
| 1242 EXPECT_FALSE(item->IsDangerous()); | 1323 EXPECT_FALSE(item->IsDangerous()); |
| 1243 | 1324 |
| 1244 // Make sure the download can complete. | 1325 // Make sure the download can complete. |
| 1245 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) | 1326 EXPECT_CALL(*download_file, |
| 1327 RenameAndAnnotate(base::FilePath(kDummyTargetPath), _)) |
| 1246 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 1328 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 1247 base::FilePath(kDummyPath))); | 1329 base::FilePath(kDummyTargetPath))); |
| 1248 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) | 1330 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(item, _)) |
| 1249 .WillOnce(Return(true)); | 1331 .WillOnce(Return(true)); |
| 1250 EXPECT_CALL(*download_file, FullPath()) | 1332 EXPECT_CALL(*download_file, FullPath()) |
| 1251 .WillOnce(Return(base::FilePath())); | 1333 .WillOnce(Return(base::FilePath())); |
| 1252 EXPECT_CALL(*download_file, Detach()); | 1334 EXPECT_CALL(*download_file, Detach()); |
| 1253 RunAllPendingInMessageLoops(); | 1335 RunAllPendingInMessageLoops(); |
| 1254 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); | 1336 EXPECT_EQ(DownloadItem::COMPLETE, item->GetState()); |
| 1255 } | 1337 } |
| 1256 | 1338 |
| 1257 TEST_F(DownloadItemTest, StealDangerousDownload) { | 1339 TEST_F(DownloadItemTest, StealDangerousDownload) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); | 1394 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); |
| 1313 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); | 1395 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); |
| 1314 item->StealDangerousDownload( | 1396 item->StealDangerousDownload( |
| 1315 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, | 1397 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, |
| 1316 weak_ptr_factory.GetWeakPtr(), | 1398 weak_ptr_factory.GetWeakPtr(), |
| 1317 base::Unretained(&returned_path))); | 1399 base::Unretained(&returned_path))); |
| 1318 RunAllPendingInMessageLoops(); | 1400 RunAllPendingInMessageLoops(); |
| 1319 EXPECT_TRUE(returned_path.empty()); | 1401 EXPECT_TRUE(returned_path.empty()); |
| 1320 } | 1402 } |
| 1321 | 1403 |
| 1404 namespace { |
| 1405 |
| 1406 // The DownloadItemDestinationUpdateRaceTest fixture (defined below) is used to |
| 1407 // test for race conditions between download destination events received via the |
| 1408 // DownloadDestinationObserver interface, and the target determination logic. |
| 1409 // |
| 1410 // The general control flow for DownloadItemImpl looks like this: |
| 1411 // |
| 1412 // * Start() called, which in turn calls DownloadFile::Initialize(). |
| 1413 // |
| 1414 // Even though OnDownloadFileInitialized hasn't been called, there could now |
| 1415 // be destination observer calls queued prior to the task that calls |
| 1416 // OnDownloadFileInitialized. Let's call this point in the workflow "A". |
| 1417 // |
| 1418 // * DownloadItemImpl::OnDownloadFileInitialized() called. |
| 1419 // |
| 1420 // * Assuming the result is successful, DII now invokes the delegate's |
| 1421 // DetermineDownloadTarget method. |
| 1422 // |
| 1423 // At this point DonwnloadFile acts as the source of |
| 1424 // DownloadDestinationObserver events, and may invoke callbacks. Let's call |
| 1425 // this point in the workflow "B". |
| 1426 // |
| 1427 // * DII::OnDownloadTargetDetermined() invoked after delegate is done with |
| 1428 // target determination. |
| 1429 // |
| 1430 // * DII attempts to rename the DownloadFile to its intermediate name. |
| 1431 // |
| 1432 // More DownloadDestinationObserver events can happen here. Let's call this |
| 1433 // point in the workflow "C". |
| 1434 // |
| 1435 // * DII::OnDownloadRenamedToIntermediateName() invoked. Assuming all went well, |
| 1436 // DII is now in IN_PROGRESS state. |
| 1437 // |
| 1438 // More DownloadDestinationObserver events can happen here. Let's call this |
| 1439 // point in the workflow "D". |
| 1440 // |
| 1441 // The DownloadItemDestinationUpdateRaceTest works by generating various |
| 1442 // combinations of DownloadDestinationObserver events that might occur at the |
| 1443 // points "A", "B", "C", and "D" above. Each test in this suite cranks a |
| 1444 // DownloadItemImpl through the states listed above and invokes the events |
| 1445 // assigned to each position. |
| 1446 |
| 1447 // This type of callback represents a call to a DownloadDestinationObserver |
| 1448 // method that's missing the DownloadDestinationObserver object. Currying this |
| 1449 // way allows us to bind a call prior to constructing the object on which the |
| 1450 // method would be invoked. This is necessary since we are going to construct |
| 1451 // various permutations of observer calls that will then be applied to a |
| 1452 // DownloadItem in a state as yet undetermined. |
| 1453 using CurriedObservation = |
| 1454 base::Callback<void(base::WeakPtr<DownloadDestinationObserver>)>; |
| 1455 |
| 1456 // A list of observations that are to be made during some event in the |
| 1457 // DownloadItemImpl control flow. Ordering of the observations is significant. |
| 1458 using ObservationList = std::deque<CurriedObservation>; |
| 1459 |
| 1460 // An ordered list of events. |
| 1461 // |
| 1462 // An "event" in this context refers to some stage in the DownloadItemImpl's |
| 1463 // workflow described as "A", "B", "C", or "D" above. An EventList is expected |
| 1464 // to always contains kEventCount events. |
| 1465 using EventList = std::deque<ObservationList>; |
| 1466 |
| 1467 // Number of events in an EventList. This is always 4 for now as described |
| 1468 // above. |
| 1469 const int kEventCount = 4; |
| 1470 |
| 1471 // The following functions help us with currying the calls to |
| 1472 // DownloadDestinationObserver. If std::bind was allowed along with |
| 1473 // std::placeholders, it is possible to avoid these functions, but currently |
| 1474 // Chromium doesn't allow using std::bind for good reasons. |
| 1475 void DestinationUpdateInvoker( |
| 1476 int64_t bytes_so_far, |
| 1477 int64_t bytes_per_sec, |
| 1478 const std::string& hash_state, |
| 1479 base::WeakPtr<DownloadDestinationObserver> observer) { |
| 1480 DVLOG(20) << "DestinationUpdate(bytes_so_far:" << bytes_so_far |
| 1481 << ", bytes_per_sec:" << bytes_per_sec |
| 1482 << ", hash_state:" << hash_state << ") observer:" << !!observer; |
| 1483 if (observer) |
| 1484 observer->DestinationUpdate(bytes_so_far, bytes_per_sec, hash_state); |
| 1485 } |
| 1486 |
| 1487 void DestinationErrorInvoker( |
| 1488 DownloadInterruptReason reason, |
| 1489 base::WeakPtr<DownloadDestinationObserver> observer) { |
| 1490 DVLOG(20) << "DestinationError(reason:" |
| 1491 << DownloadInterruptReasonToString(reason) |
| 1492 << ") observer:" << !!observer; |
| 1493 if (observer) |
| 1494 observer->DestinationError(reason); |
| 1495 } |
| 1496 |
| 1497 void DestinationCompletedInvoker( |
| 1498 const std::string& final_hash, |
| 1499 base::WeakPtr<DownloadDestinationObserver> observer) { |
| 1500 DVLOG(20) << "DestinationComplete(final_hash:" << final_hash |
| 1501 << ") observer:" << !!observer; |
| 1502 if (observer) |
| 1503 observer->DestinationCompleted(final_hash); |
| 1504 } |
| 1505 |
| 1506 // Given a set of observations (via the range |begin|..|end|), constructs a list |
| 1507 // of EventLists such that: |
| 1508 // |
| 1509 // * There are exactly |event_count| ObservationSets in each EventList. |
| 1510 // |
| 1511 // * Each ObservationList in each EventList contains a subrange (possibly empty) |
| 1512 // of observations from the input range, in the same order as the input range. |
| 1513 // |
| 1514 // * The ordering of the ObservationList in each EventList is such that all |
| 1515 // observations in one ObservationList occur earlier than all observations in |
| 1516 // an ObservationList that follows it. |
| 1517 // |
| 1518 // * The list of EventLists together describe all the possible ways in which the |
| 1519 // list of observations can be distributed into |event_count| events. |
| 1520 std::vector<EventList> DistributeObservationsIntoEvents( |
| 1521 const std::vector<CurriedObservation>::iterator begin, |
| 1522 const std::vector<CurriedObservation>::iterator end, |
| 1523 int event_count) { |
| 1524 std::vector<EventList> all_event_lists; |
| 1525 for (auto partition = begin;; ++partition) { |
| 1526 ObservationList first_group_of_observations(begin, partition); |
| 1527 if (event_count > 1) { |
| 1528 std::vector<EventList> list_of_subsequent_events = |
| 1529 DistributeObservationsIntoEvents(partition, end, event_count - 1); |
| 1530 for (const auto& subsequent_events : list_of_subsequent_events) { |
| 1531 EventList event_list; |
| 1532 event_list = subsequent_events; |
| 1533 event_list.push_front(first_group_of_observations); |
| 1534 all_event_lists.push_back(event_list); |
| 1535 } |
| 1536 } else { |
| 1537 EventList event_list; |
| 1538 event_list.push_front(first_group_of_observations); |
| 1539 all_event_lists.push_back(event_list); |
| 1540 } |
| 1541 if (partition == end) |
| 1542 break; |
| 1543 } |
| 1544 return all_event_lists; |
| 1545 } |
| 1546 |
| 1547 // For the purpose of this tests, we are only concerned with 3 events: |
| 1548 // |
| 1549 // 1. Immediately after the DownloadFile is initialized. |
| 1550 // 2. Immediately after the DownloadTargetCallback is invoked. |
| 1551 // 3. Immediately after the intermediate file is renamed. |
| 1552 // |
| 1553 // We are going to take a couple of sets of DownloadDestinationObserver events |
| 1554 // and distribute them into the three events described above. And then we are |
| 1555 // going to invoke the observations while a DownloadItemImpl is carefully |
| 1556 // stepped through its stages. |
| 1557 |
| 1558 std::vector<EventList> GenerateSuccessfulEventLists() { |
| 1559 std::vector<CurriedObservation> all_observations; |
| 1560 all_observations.push_back( |
| 1561 base::Bind(&DestinationUpdateInvoker, 100, 100, "abc")); |
| 1562 all_observations.push_back( |
| 1563 base::Bind(&DestinationUpdateInvoker, 200, 100, "def")); |
| 1564 all_observations.push_back( |
| 1565 base::Bind(&DestinationCompletedInvoker, "final-hash-1")); |
| 1566 return DistributeObservationsIntoEvents(all_observations.begin(), |
| 1567 all_observations.end(), kEventCount); |
| 1568 } |
| 1569 |
| 1570 std::vector<EventList> GenerateFailingEventLists() { |
| 1571 std::vector<CurriedObservation> all_observations; |
| 1572 all_observations.push_back( |
| 1573 base::Bind(&DestinationUpdateInvoker, 100, 100, "abc")); |
| 1574 all_observations.push_back(base::Bind( |
| 1575 &DestinationErrorInvoker, DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); |
| 1576 return DistributeObservationsIntoEvents(all_observations.begin(), |
| 1577 all_observations.end(), kEventCount); |
| 1578 } |
| 1579 |
| 1580 class DownloadItemDestinationUpdateRaceTest |
| 1581 : public DownloadItemTest, |
| 1582 public ::testing::WithParamInterface<EventList> { |
| 1583 public: |
| 1584 DownloadItemDestinationUpdateRaceTest() |
| 1585 : DownloadItemTest(), |
| 1586 item_(CreateDownloadItem()), |
| 1587 file_(new ::testing::StrictMock<MockDownloadFile>()), |
| 1588 request_handle_(new ::testing::StrictMock<MockRequestHandle>()) { |
| 1589 DCHECK_EQ(GetParam().size(), static_cast<unsigned>(kEventCount)); |
| 1590 EXPECT_CALL(*request_handle_, GetWebContents()) |
| 1591 .WillRepeatedly(Return(nullptr)); |
| 1592 } |
| 1593 |
| 1594 protected: |
| 1595 const ObservationList& PreInitializeFileObservations() { |
| 1596 return GetParam().front(); |
| 1597 } |
| 1598 const ObservationList& PostInitializeFileObservations() { |
| 1599 return *(GetParam().begin() + 1); |
| 1600 } |
| 1601 const ObservationList& PostTargetDeterminationObservations() { |
| 1602 return *(GetParam().begin() + 2); |
| 1603 } |
| 1604 const ObservationList& PostIntermediateRenameObservations() { |
| 1605 return *(GetParam().begin() + 3); |
| 1606 } |
| 1607 |
| 1608 // Apply all the observations in |observations| to |observer|, but do so |
| 1609 // asynchronously so that the events are applied in order behind any tasks |
| 1610 // that are already scheduled. |
| 1611 void ScheduleObservations( |
| 1612 const ObservationList& observations, |
| 1613 base::WeakPtr<DownloadDestinationObserver> observer) { |
| 1614 for (const auto action : observations) |
| 1615 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 1616 base::Bind(action, observer)); |
| 1617 } |
| 1618 |
| 1619 DownloadItemImpl* item_; |
| 1620 scoped_ptr<MockDownloadFile> file_; |
| 1621 scoped_ptr<MockRequestHandle> request_handle_; |
| 1622 |
| 1623 std::queue<base::Closure> successful_update_events_; |
| 1624 std::queue<base::Closure> failing_update_events_; |
| 1625 }; |
| 1626 |
| 1627 INSTANTIATE_TEST_CASE_P(Success, |
| 1628 DownloadItemDestinationUpdateRaceTest, |
| 1629 ::testing::ValuesIn(GenerateSuccessfulEventLists())); |
| 1630 |
| 1631 INSTANTIATE_TEST_CASE_P(Failure, |
| 1632 DownloadItemDestinationUpdateRaceTest, |
| 1633 ::testing::ValuesIn(GenerateFailingEventLists())); |
| 1634 |
| 1635 } // namespace |
| 1636 |
| 1637 // Run through the DII workflow but the embedder cancels the download at target |
| 1638 // determination. |
| 1639 TEST_P(DownloadItemDestinationUpdateRaceTest, DownloadCancelledByUser) { |
| 1640 // Expect that the download file and the request will be cancelled as a |
| 1641 // result. |
| 1642 EXPECT_CALL(*file_, Cancel()); |
| 1643 EXPECT_CALL(*request_handle_, CancelRequest()); |
| 1644 |
| 1645 base::RunLoop download_start_loop; |
| 1646 DownloadFile::InitializeCallback initialize_callback; |
| 1647 EXPECT_CALL(*file_, Initialize(_)) |
| 1648 .WillOnce(DoAll(SaveArg<0>(&initialize_callback), |
| 1649 ScheduleClosure(download_start_loop.QuitClosure()))); |
| 1650 item_->Start(std::move(file_), std::move(request_handle_)); |
| 1651 download_start_loop.Run(); |
| 1652 |
| 1653 base::WeakPtr<DownloadDestinationObserver> destination_observer = |
| 1654 item_->DestinationObserverAsWeakPtr(); |
| 1655 |
| 1656 ScheduleObservations(PreInitializeFileObservations(), destination_observer); |
| 1657 RunAllPendingInMessageLoops(); |
| 1658 |
| 1659 base::RunLoop initialize_completion_loop; |
| 1660 DownloadItemImplDelegate::DownloadTargetCallback target_callback; |
| 1661 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) |
| 1662 .WillOnce( |
| 1663 DoAll(SaveArg<1>(&target_callback), |
| 1664 ScheduleClosure(initialize_completion_loop.QuitClosure()))); |
| 1665 ScheduleObservations(PostInitializeFileObservations(), destination_observer); |
| 1666 initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE); |
| 1667 initialize_completion_loop.Run(); |
| 1668 |
| 1669 RunAllPendingInMessageLoops(); |
| 1670 |
| 1671 ASSERT_FALSE(target_callback.is_null()); |
| 1672 ScheduleObservations(PostTargetDeterminationObservations(), |
| 1673 destination_observer); |
| 1674 target_callback.Run(base::FilePath(), |
| 1675 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1676 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, base::FilePath()); |
| 1677 EXPECT_EQ(DownloadItem::CANCELLED, item_->GetState()); |
| 1678 RunAllPendingInMessageLoops(); |
| 1679 } |
| 1680 |
| 1681 // Run through the DII workflow, but the intermediate rename fails. |
| 1682 TEST_P(DownloadItemDestinationUpdateRaceTest, IntermediateRenameFails) { |
| 1683 // Expect that the download file and the request will be cancelled as a |
| 1684 // result. |
| 1685 EXPECT_CALL(*file_, Cancel()); |
| 1686 EXPECT_CALL(*request_handle_, CancelRequest()); |
| 1687 |
| 1688 // Intermediate rename loop is not used immediately, but let's set up the |
| 1689 // DownloadFile expectations since we are about to transfer its ownership to |
| 1690 // the DownloadItem. |
| 1691 base::RunLoop intermediate_rename_loop; |
| 1692 DownloadFile::RenameCompletionCallback intermediate_rename_callback; |
| 1693 EXPECT_CALL(*file_, RenameAndUniquify(_, _)) |
| 1694 .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback), |
| 1695 ScheduleClosure(intermediate_rename_loop.QuitClosure()))); |
| 1696 |
| 1697 base::RunLoop download_start_loop; |
| 1698 DownloadFile::InitializeCallback initialize_callback; |
| 1699 EXPECT_CALL(*file_, Initialize(_)) |
| 1700 .WillOnce(DoAll(SaveArg<0>(&initialize_callback), |
| 1701 ScheduleClosure(download_start_loop.QuitClosure()))); |
| 1702 |
| 1703 item_->Start(std::move(file_), std::move(request_handle_)); |
| 1704 download_start_loop.Run(); |
| 1705 base::WeakPtr<DownloadDestinationObserver> destination_observer = |
| 1706 item_->DestinationObserverAsWeakPtr(); |
| 1707 |
| 1708 ScheduleObservations(PreInitializeFileObservations(), destination_observer); |
| 1709 RunAllPendingInMessageLoops(); |
| 1710 |
| 1711 base::RunLoop initialize_completion_loop; |
| 1712 DownloadItemImplDelegate::DownloadTargetCallback target_callback; |
| 1713 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) |
| 1714 .WillOnce( |
| 1715 DoAll(SaveArg<1>(&target_callback), |
| 1716 ScheduleClosure(initialize_completion_loop.QuitClosure()))); |
| 1717 ScheduleObservations(PostInitializeFileObservations(), destination_observer); |
| 1718 initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE); |
| 1719 initialize_completion_loop.Run(); |
| 1720 |
| 1721 RunAllPendingInMessageLoops(); |
| 1722 ASSERT_FALSE(target_callback.is_null()); |
| 1723 |
| 1724 ScheduleObservations(PostTargetDeterminationObservations(), |
| 1725 destination_observer); |
| 1726 target_callback.Run(base::FilePath(kDummyTargetPath), |
| 1727 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1728 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1729 base::FilePath(kDummyIntermediatePath)); |
| 1730 |
| 1731 intermediate_rename_loop.Run(); |
| 1732 ASSERT_FALSE(intermediate_rename_callback.is_null()); |
| 1733 |
| 1734 ScheduleObservations(PostIntermediateRenameObservations(), |
| 1735 destination_observer); |
| 1736 intermediate_rename_callback.Run(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, |
| 1737 base::FilePath()); |
| 1738 RunAllPendingInMessageLoops(); |
| 1739 |
| 1740 EXPECT_EQ(DownloadItem::INTERRUPTED, item_->GetState()); |
| 1741 } |
| 1742 |
| 1743 // Run through the DII workflow. Download file initialization, target |
| 1744 // determination and intermediate rename all succeed. |
| 1745 TEST_P(DownloadItemDestinationUpdateRaceTest, IntermediateRenameSucceeds) { |
| 1746 // We expect either that the download will fail (in which case the request and |
| 1747 // the download file will be cancelled), or it will succeed (in which case the |
| 1748 // DownloadFile will Detach()). It depends on the list of observations that |
| 1749 // are given to us. |
| 1750 EXPECT_CALL(*file_, Cancel()).Times(::testing::AnyNumber()); |
| 1751 EXPECT_CALL(*request_handle_, CancelRequest()).Times(::testing::AnyNumber()); |
| 1752 EXPECT_CALL(*file_, Detach()).Times(::testing::AnyNumber()); |
| 1753 |
| 1754 EXPECT_CALL(*file_, FullPath()) |
| 1755 .WillRepeatedly(Return(base::FilePath(kDummyIntermediatePath))); |
| 1756 |
| 1757 // Intermediate rename loop is not used immediately, but let's set up the |
| 1758 // DownloadFile expectations since we are about to transfer its ownership to |
| 1759 // the DownloadItem. |
| 1760 base::RunLoop intermediate_rename_loop; |
| 1761 DownloadFile::RenameCompletionCallback intermediate_rename_callback; |
| 1762 EXPECT_CALL(*file_, RenameAndUniquify(_, _)) |
| 1763 .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback), |
| 1764 ScheduleClosure(intermediate_rename_loop.QuitClosure()))); |
| 1765 |
| 1766 base::RunLoop download_start_loop; |
| 1767 DownloadFile::InitializeCallback initialize_callback; |
| 1768 EXPECT_CALL(*file_, Initialize(_)) |
| 1769 .WillOnce(DoAll(SaveArg<0>(&initialize_callback), |
| 1770 ScheduleClosure(download_start_loop.QuitClosure()))); |
| 1771 |
| 1772 item_->Start(std::move(file_), std::move(request_handle_)); |
| 1773 download_start_loop.Run(); |
| 1774 base::WeakPtr<DownloadDestinationObserver> destination_observer = |
| 1775 item_->DestinationObserverAsWeakPtr(); |
| 1776 |
| 1777 ScheduleObservations(PreInitializeFileObservations(), destination_observer); |
| 1778 RunAllPendingInMessageLoops(); |
| 1779 |
| 1780 base::RunLoop initialize_completion_loop; |
| 1781 DownloadItemImplDelegate::DownloadTargetCallback target_callback; |
| 1782 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) |
| 1783 .WillOnce( |
| 1784 DoAll(SaveArg<1>(&target_callback), |
| 1785 ScheduleClosure(initialize_completion_loop.QuitClosure()))); |
| 1786 ScheduleObservations(PostInitializeFileObservations(), destination_observer); |
| 1787 initialize_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE); |
| 1788 initialize_completion_loop.Run(); |
| 1789 |
| 1790 RunAllPendingInMessageLoops(); |
| 1791 ASSERT_FALSE(target_callback.is_null()); |
| 1792 |
| 1793 ScheduleObservations(PostTargetDeterminationObservations(), |
| 1794 destination_observer); |
| 1795 target_callback.Run(base::FilePath(kDummyTargetPath), |
| 1796 DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
| 1797 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, |
| 1798 base::FilePath(kDummyIntermediatePath)); |
| 1799 |
| 1800 intermediate_rename_loop.Run(); |
| 1801 ASSERT_FALSE(intermediate_rename_callback.is_null()); |
| 1802 |
| 1803 // This may or may not be called, depending on whether there are any errors in |
| 1804 // our action list. |
| 1805 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(_, _)) |
| 1806 .Times(::testing::AnyNumber()); |
| 1807 |
| 1808 ScheduleObservations(PostIntermediateRenameObservations(), |
| 1809 destination_observer); |
| 1810 intermediate_rename_callback.Run(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 1811 base::FilePath(kDummyIntermediatePath)); |
| 1812 RunAllPendingInMessageLoops(); |
| 1813 |
| 1814 // The state of the download depends on the observer events that were played |
| 1815 // back to the DownloadItemImpl. Hence we can't establish a single expectation |
| 1816 // here. On Debug builds, the DCHECKs will verify that the state transitions |
| 1817 // were correct. On Release builds, tests are expected to run to completion |
| 1818 // without crashing on success. |
| 1819 EXPECT_TRUE(item_->GetState() == DownloadItem::IN_PROGRESS || |
| 1820 item_->GetState() == DownloadItem::INTERRUPTED); |
| 1821 if (item_->GetState() == DownloadItem::INTERRUPTED) |
| 1822 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item_->GetLastReason()); |
| 1823 |
| 1824 item_->Cancel(true); |
| 1825 RunAllPendingInMessageLoops(); |
| 1826 } |
| 1827 |
| 1322 TEST(MockDownloadItem, Compiles) { | 1828 TEST(MockDownloadItem, Compiles) { |
| 1323 MockDownloadItem mock_item; | 1829 MockDownloadItem mock_item; |
| 1324 } | 1830 } |
| 1325 | 1831 |
| 1326 } // namespace content | 1832 } // namespace content |
| OLD | NEW |