| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/callback.h" | 5 #include "base/callback.h" |
| 6 #include "base/command_line.h" | 6 #include "base/command_line.h" |
| 7 #include "base/message_loop/message_loop.h" | 7 #include "base/message_loop/message_loop.h" |
| 8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
| 9 #include "base/threading/thread.h" | 9 #include "base/threading/thread.h" |
| 10 #include "content/browser/byte_stream.h" | 10 #include "content/browser/byte_stream.h" |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 | 196 |
| 197 virtual void TearDown() { | 197 virtual void TearDown() { |
| 198 ui_thread_.DeprecatedGetThreadObject()->message_loop()->RunUntilIdle(); | 198 ui_thread_.DeprecatedGetThreadObject()->message_loop()->RunUntilIdle(); |
| 199 STLDeleteElements(&allocated_downloads_); | 199 STLDeleteElements(&allocated_downloads_); |
| 200 } | 200 } |
| 201 | 201 |
| 202 // This class keeps ownership of the created download item; it will | 202 // This class keeps ownership of the created download item; it will |
| 203 // be torn down at the end of the test unless DestroyDownloadItem is | 203 // be torn down at the end of the test unless DestroyDownloadItem is |
| 204 // called. | 204 // called. |
| 205 DownloadItemImpl* CreateDownloadItem() { | 205 DownloadItemImpl* CreateDownloadItem() { |
| 206 // Normally, the download system takes ownership of info, and is | 206 scoped_ptr<DownloadCreateInfo> info; |
| 207 // responsible for deleting it. In these unit tests, however, we | |
| 208 // don't call the function that deletes it, so we do so ourselves. | |
| 209 scoped_ptr<DownloadCreateInfo> info_; | |
| 210 | 207 |
| 211 info_.reset(new DownloadCreateInfo()); | 208 info.reset(new DownloadCreateInfo()); |
| 212 static uint32 next_id = DownloadItem::kInvalidId + 1; | 209 info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); |
| 213 info_->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); | 210 info->save_info->prompt_for_save_location = false; |
| 214 info_->save_info->prompt_for_save_location = false; | 211 info->url_chain.push_back(GURL()); |
| 215 info_->url_chain.push_back(GURL()); | 212 info->etag = "SomethingToSatisfyResumption"; |
| 216 info_->etag = "SomethingToSatisfyResumption"; | |
| 217 | 213 |
| 218 DownloadItemImpl* download = | 214 return CreateDownloadItemWithCreateInfo(info.Pass()); |
| 219 new DownloadItemImpl( | 215 } |
| 220 &delegate_, next_id++, *(info_.get()), net::BoundNetLog()); | 216 |
| 217 DownloadItemImpl* CreateDownloadItemWithCreateInfo( |
| 218 scoped_ptr<DownloadCreateInfo> info) { |
| 219 DownloadItemImpl* download = new DownloadItemImpl( |
| 220 &delegate_, next_download_id_++, *(info.get()), net::BoundNetLog()); |
| 221 allocated_downloads_.insert(download); | 221 allocated_downloads_.insert(download); |
| 222 return download; | 222 return download; |
| 223 } | 223 } |
| 224 | 224 |
| 225 // Add DownloadFile to DownloadItem | 225 // Add DownloadFile to DownloadItem |
| 226 MockDownloadFile* AddDownloadFileToDownloadItem( | 226 MockDownloadFile* AddDownloadFileToDownloadItem( |
| 227 DownloadItemImpl* item, | 227 DownloadItemImpl* item, |
| 228 DownloadItemImplDelegate::DownloadTargetCallback *callback) { | 228 DownloadItemImplDelegate::DownloadTargetCallback *callback) { |
| 229 MockDownloadFile* mock_download_file(new StrictMock<MockDownloadFile>); | 229 MockDownloadFile* mock_download_file(new StrictMock<MockDownloadFile>); |
| 230 scoped_ptr<DownloadFile> download_file(mock_download_file); | 230 scoped_ptr<DownloadFile> download_file(mock_download_file); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 MockDelegate* mock_delegate() { | 305 MockDelegate* mock_delegate() { |
| 306 return &delegate_; | 306 return &delegate_; |
| 307 } | 307 } |
| 308 | 308 |
| 309 void OnDownloadFileAcquired(base::FilePath* return_path, | 309 void OnDownloadFileAcquired(base::FilePath* return_path, |
| 310 const base::FilePath& path) { | 310 const base::FilePath& path) { |
| 311 *return_path = path; | 311 *return_path = path; |
| 312 } | 312 } |
| 313 | 313 |
| 314 private: | 314 private: |
| 315 int next_download_id_ = DownloadItem::kInvalidId + 1; |
| 315 base::MessageLoopForUI loop_; | 316 base::MessageLoopForUI loop_; |
| 316 TestBrowserThread ui_thread_; // UI thread | 317 TestBrowserThread ui_thread_; // UI thread |
| 317 TestBrowserThread file_thread_; // FILE thread | 318 TestBrowserThread file_thread_; // FILE thread |
| 318 StrictMock<MockDelegate> delegate_; | 319 StrictMock<MockDelegate> delegate_; |
| 319 std::set<DownloadItem*> allocated_downloads_; | 320 std::set<DownloadItem*> allocated_downloads_; |
| 320 }; | 321 }; |
| 321 | 322 |
| 322 // Tests to ensure calls that change a DownloadItem generate an update to | 323 // Tests to ensure calls that change a DownloadItem generate an update to |
| 323 // observers. | 324 // observers. |
| 324 // State changing functions not tested: | 325 // State changing functions not tested: |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 ASSERT_TRUE(observer.download_destroyed()); | 398 ASSERT_TRUE(observer.download_destroyed()); |
| 398 } | 399 } |
| 399 | 400 |
| 400 TEST_F(DownloadItemTest, ContinueAfterInterrupted) { | 401 TEST_F(DownloadItemTest, ContinueAfterInterrupted) { |
| 401 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 402 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 402 switches::kEnableDownloadResumption); | 403 switches::kEnableDownloadResumption); |
| 403 | 404 |
| 404 TestBrowserContext test_browser_context; | 405 TestBrowserContext test_browser_context; |
| 405 DownloadItemImpl* item = CreateDownloadItem(); | 406 DownloadItemImpl* item = CreateDownloadItem(); |
| 406 TestDownloadItemObserver observer(item); | 407 TestDownloadItemObserver observer(item); |
| 407 DownloadItemImplDelegate::DownloadTargetCallback callback; | |
| 408 MockDownloadFile* download_file = | 408 MockDownloadFile* download_file = |
| 409 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 409 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 410 | 410 |
| 411 // Interrupt the download, using a continuable interrupt. | 411 // Interrupt the download, using a continuable interrupt. |
| 412 EXPECT_CALL(*download_file, FullPath()) | 412 EXPECT_CALL(*download_file, FullPath()) |
| 413 .WillOnce(Return(base::FilePath())); | 413 .WillOnce(Return(base::FilePath())); |
| 414 EXPECT_CALL(*download_file, Detach()); | 414 EXPECT_CALL(*download_file, Detach()); |
| 415 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | 415 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
| 416 .WillRepeatedly(Return(&test_browser_context)); | 416 .WillRepeatedly(Return(&test_browser_context)); |
| 417 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1); | 417 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 430 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); | 430 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); |
| 431 } | 431 } |
| 432 | 432 |
| 433 // Same as above, but with a non-continuable interrupt. | 433 // Same as above, but with a non-continuable interrupt. |
| 434 TEST_F(DownloadItemTest, RestartAfterInterrupted) { | 434 TEST_F(DownloadItemTest, RestartAfterInterrupted) { |
| 435 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 435 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 436 switches::kEnableDownloadResumption); | 436 switches::kEnableDownloadResumption); |
| 437 | 437 |
| 438 DownloadItemImpl* item = CreateDownloadItem(); | 438 DownloadItemImpl* item = CreateDownloadItem(); |
| 439 TestDownloadItemObserver observer(item); | 439 TestDownloadItemObserver observer(item); |
| 440 DownloadItemImplDelegate::DownloadTargetCallback callback; | |
| 441 MockDownloadFile* download_file = | 440 MockDownloadFile* download_file = |
| 442 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 441 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 443 | 442 |
| 444 // Interrupt the download, using a restartable interrupt. | 443 // Interrupt the download, using a restartable interrupt. |
| 445 EXPECT_CALL(*download_file, Cancel()); | 444 EXPECT_CALL(*download_file, Cancel()); |
| 446 item->DestinationObserverAsWeakPtr()->DestinationError( | 445 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 447 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 446 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
| 448 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 447 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 449 // Should not try to auto-resume. | 448 // Should not try to auto-resume. |
| 450 ASSERT_EQ(1, observer.interrupt_count()); | 449 ASSERT_EQ(1, observer.interrupt_count()); |
| 451 ASSERT_EQ(0, observer.resume_count()); | 450 ASSERT_EQ(0, observer.resume_count()); |
| 452 RunAllPendingInMessageLoops(); | 451 RunAllPendingInMessageLoops(); |
| 453 | 452 |
| 454 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); | 453 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); |
| 455 } | 454 } |
| 456 | 455 |
| 457 // Check we do correct cleanup for RESUME_MODE_INVALID interrupts. | 456 // Check we do correct cleanup for RESUME_MODE_INVALID interrupts. |
| 458 TEST_F(DownloadItemTest, UnresumableInterrupt) { | 457 TEST_F(DownloadItemTest, UnresumableInterrupt) { |
| 459 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 458 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 460 switches::kEnableDownloadResumption); | 459 switches::kEnableDownloadResumption); |
| 461 | 460 |
| 462 DownloadItemImpl* item = CreateDownloadItem(); | 461 DownloadItemImpl* item = CreateDownloadItem(); |
| 463 TestDownloadItemObserver observer(item); | 462 TestDownloadItemObserver observer(item); |
| 464 DownloadItemImplDelegate::DownloadTargetCallback callback; | |
| 465 MockDownloadFile* download_file = | 463 MockDownloadFile* download_file = |
| 466 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 464 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 467 | 465 |
| 468 // Fail final rename with unresumable reason. | 466 // Fail final rename with unresumable reason. |
| 469 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) | 467 EXPECT_CALL(*mock_delegate(), ShouldCompleteDownload(item, _)) |
| 470 .WillOnce(Return(true)); | 468 .WillOnce(Return(true)); |
| 471 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) | 469 EXPECT_CALL(*download_file, RenameAndAnnotate(base::FilePath(kDummyPath), _)) |
| 472 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, | 470 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, |
| 473 base::FilePath(kDummyPath))); | 471 base::FilePath(kDummyPath))); |
| 474 EXPECT_CALL(*download_file, Cancel()); | 472 EXPECT_CALL(*download_file, Cancel()); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 item->DestinationObserverAsWeakPtr()->DestinationError( | 537 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 540 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 538 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
| 541 | 539 |
| 542 ASSERT_EQ(i + 1, observer.interrupt_count()); | 540 ASSERT_EQ(i + 1, observer.interrupt_count()); |
| 543 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); | 541 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); |
| 544 } | 542 } |
| 545 | 543 |
| 546 CleanupItem(item, mock_download_file, DownloadItem::INTERRUPTED); | 544 CleanupItem(item, mock_download_file, DownloadItem::INTERRUPTED); |
| 547 } | 545 } |
| 548 | 546 |
| 547 // Test that resumption uses the final URL in a URL chain when resuming. |
| 548 TEST_F(DownloadItemTest, ResumeUsingFinalURL) { |
| 549 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 550 switches::kEnableDownloadResumption); |
| 551 |
| 552 TestBrowserContext test_browser_context; |
| 553 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo); |
| 554 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); |
| 555 create_info->save_info->prompt_for_save_location = false; |
| 556 create_info->etag = "SomethingToSatisfyResumption"; |
| 557 create_info->url_chain.push_back(GURL("http://example.com/a")); |
| 558 create_info->url_chain.push_back(GURL("http://example.com/b")); |
| 559 create_info->url_chain.push_back(GURL("http://example.com/c")); |
| 560 |
| 561 DownloadItemImpl* item = CreateDownloadItemWithCreateInfo(create_info.Pass()); |
| 562 TestDownloadItemObserver observer(item); |
| 563 MockDownloadFile* download_file = |
| 564 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
| 565 |
| 566 // Interrupt the download, using a continuable interrupt. |
| 567 EXPECT_CALL(*download_file, FullPath()).WillOnce(Return(base::FilePath())); |
| 568 EXPECT_CALL(*download_file, Detach()); |
| 569 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
| 570 .WillRepeatedly(Return(&test_browser_context)); |
| 571 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( |
| 572 Property(&DownloadUrlParameters::url, |
| 573 GURL("http://example.com/c")), |
| 574 _)) |
| 575 .Times(1); |
| 576 item->DestinationObserverAsWeakPtr()->DestinationError( |
| 577 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
| 578 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 579 ASSERT_EQ(1, observer.interrupt_count()); |
| 580 |
| 581 // Test expectations verify that ResumeInterruptedDownload() is called (by way |
| 582 // of MockResumeInterruptedDownload) after the download is interrupted. But |
| 583 // the mock doesn't follow through with the resumption. |
| 584 // ResumeInterruptedDownload() being called is sufficient for verifying that |
| 585 // the resumption was triggered. |
| 586 RunAllPendingInMessageLoops(); |
| 587 |
| 588 CleanupItem(item, download_file, DownloadItem::INTERRUPTED); |
| 589 } |
| 590 |
| 549 TEST_F(DownloadItemTest, NotificationAfterRemove) { | 591 TEST_F(DownloadItemTest, NotificationAfterRemove) { |
| 550 DownloadItemImpl* item = CreateDownloadItem(); | 592 DownloadItemImpl* item = CreateDownloadItem(); |
| 551 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL); | 593 MockDownloadFile* download_file = AddDownloadFileToDownloadItem(item, NULL); |
| 552 EXPECT_CALL(*download_file, Cancel()); | 594 EXPECT_CALL(*download_file, Cancel()); |
| 553 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); | 595 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); |
| 554 TestDownloadItemObserver observer(item); | 596 TestDownloadItemObserver observer(item); |
| 555 | 597 |
| 556 item->Remove(); | 598 item->Remove(); |
| 557 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 599 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
| 558 ASSERT_TRUE(observer.download_removed()); | 600 ASSERT_TRUE(observer.download_removed()); |
| (...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 base::Unretained(&returned_path))); | 1327 base::Unretained(&returned_path))); |
| 1286 RunAllPendingInMessageLoops(); | 1328 RunAllPendingInMessageLoops(); |
| 1287 EXPECT_TRUE(returned_path.empty()); | 1329 EXPECT_TRUE(returned_path.empty()); |
| 1288 } | 1330 } |
| 1289 | 1331 |
| 1290 TEST(MockDownloadItem, Compiles) { | 1332 TEST(MockDownloadItem, Compiles) { |
| 1291 MockDownloadItem mock_item; | 1333 MockDownloadItem mock_item; |
| 1292 } | 1334 } |
| 1293 | 1335 |
| 1294 } // namespace content | 1336 } // namespace content |
| OLD | NEW |