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 |