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 | 8 |
9 #include <iterator> | 9 #include <iterator> |
10 #include <queue> | 10 #include <queue> |
11 #include <utility> | 11 #include <utility> |
12 | 12 |
13 #include "base/callback.h" | 13 #include "base/callback.h" |
14 #include "base/feature_list.h" | 14 #include "base/feature_list.h" |
15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
16 #include "base/run_loop.h" | 16 #include "base/run_loop.h" |
17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
18 #include "base/threading/thread.h" | 18 #include "base/threading/thread.h" |
19 #include "content/browser/byte_stream.h" | 19 #include "content/browser/byte_stream.h" |
20 #include "content/browser/download/download_create_info.h" | 20 #include "content/browser/download/download_create_info.h" |
21 #include "content/browser/download/download_file_factory.h" | 21 #include "content/browser/download/download_file_factory.h" |
22 #include "content/browser/download/download_item_impl_delegate.h" | 22 #include "content/browser/download/download_item_impl_delegate.h" |
23 #include "content/browser/download/download_request_handle.h" | 23 #include "content/browser/download/download_request_handle.h" |
24 #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" | 25 #include "content/public/browser/browser_thread.h" |
26 #include "content/public/browser/download_destination_observer.h" | 26 #include "content/public/browser/download_destination_observer.h" |
27 #include "content/public/browser/download_interrupt_reasons.h" | 27 #include "content/public/browser/download_interrupt_reasons.h" |
28 #include "content/public/browser/download_url_parameters.h" | 28 #include "content/public/browser/download_url_parameters.h" |
29 #include "content/public/browser/site_instance.h" | |
30 #include "content/public/browser/web_contents.h" | |
29 #include "content/public/common/content_features.h" | 31 #include "content/public/common/content_features.h" |
30 #include "content/public/test/mock_download_item.h" | 32 #include "content/public/test/mock_download_item.h" |
33 #include "content/public/test/mock_download_item.h" | |
34 #include "content/public/test/test_browser_context.h" | |
31 #include "content/public/test/test_browser_context.h" | 35 #include "content/public/test/test_browser_context.h" |
32 #include "content/public/test/test_browser_thread_bundle.h" | 36 #include "content/public/test/test_browser_thread_bundle.h" |
37 #include "content/public/test/web_contents_tester.h" | |
33 #include "testing/gmock/include/gmock/gmock.h" | 38 #include "testing/gmock/include/gmock/gmock.h" |
34 #include "testing/gtest/include/gtest/gtest.h" | 39 #include "testing/gtest/include/gtest/gtest.h" |
35 | 40 |
36 using ::testing::DoAll; | 41 using ::testing::DoAll; |
37 using ::testing::NiceMock; | 42 using ::testing::NiceMock; |
38 using ::testing::Property; | 43 using ::testing::Property; |
39 using ::testing::Return; | 44 using ::testing::Return; |
40 using ::testing::SaveArg; | 45 using ::testing::SaveArg; |
41 using ::testing::StrictMock; | 46 using ::testing::StrictMock; |
42 using ::testing::WithArg; | 47 using ::testing::WithArg; |
(...skipping 26 matching lines...) Expand all Loading... | |
69 MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*)); | 74 MOCK_METHOD1(CheckForFileRemoval, void(DownloadItemImpl*)); |
70 | 75 |
71 void ResumeInterruptedDownload(scoped_ptr<DownloadUrlParameters> params, | 76 void ResumeInterruptedDownload(scoped_ptr<DownloadUrlParameters> params, |
72 uint32_t id) override { | 77 uint32_t id) override { |
73 MockResumeInterruptedDownload(params.get(), id); | 78 MockResumeInterruptedDownload(params.get(), id); |
74 } | 79 } |
75 MOCK_METHOD2(MockResumeInterruptedDownload, | 80 MOCK_METHOD2(MockResumeInterruptedDownload, |
76 void(DownloadUrlParameters* params, uint32_t id)); | 81 void(DownloadUrlParameters* params, uint32_t id)); |
77 | 82 |
78 MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*()); | 83 MOCK_CONST_METHOD0(GetBrowserContext, BrowserContext*()); |
79 MOCK_METHOD1(UpdatePersistence, void(DownloadItemImpl*)); | |
80 MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*)); | 84 MOCK_METHOD1(DownloadOpened, void(DownloadItemImpl*)); |
81 MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*)); | 85 MOCK_METHOD1(DownloadRemoved, void(DownloadItemImpl*)); |
82 MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*)); | 86 MOCK_CONST_METHOD1(AssertStateConsistent, void(DownloadItemImpl*)); |
83 | 87 |
84 void VerifyAndClearExpectations() { | 88 void VerifyAndClearExpectations() { |
85 ::testing::Mock::VerifyAndClearExpectations(this); | 89 ::testing::Mock::VerifyAndClearExpectations(this); |
86 SetDefaultExpectations(); | 90 SetDefaultExpectations(); |
87 } | 91 } |
88 | 92 |
89 private: | 93 private: |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 int resume_count() const { return resume_count_; } | 135 int resume_count() const { return resume_count_; } |
132 | 136 |
133 bool CheckAndResetDownloadUpdated() { | 137 bool CheckAndResetDownloadUpdated() { |
134 bool was_updated = updated_; | 138 bool was_updated = updated_; |
135 updated_ = false; | 139 updated_ = false; |
136 return was_updated; | 140 return was_updated; |
137 } | 141 } |
138 | 142 |
139 private: | 143 private: |
140 void OnDownloadRemoved(DownloadItem* download) override { | 144 void OnDownloadRemoved(DownloadItem* download) override { |
141 DVLOG(20) << " " << __FUNCTION__ | 145 SCOPED_TRACE(::testing::Message() << " " << __FUNCTION__ << " download = " |
142 << " download = " << download->DebugString(false); | 146 << download->DebugString(false)); |
143 removed_ = true; | 147 removed_ = true; |
144 } | 148 } |
145 | 149 |
146 void OnDownloadUpdated(DownloadItem* download) override { | 150 void OnDownloadUpdated(DownloadItem* download) override { |
147 DVLOG(20) << " " << __FUNCTION__ | 151 DVLOG(20) << " " << __FUNCTION__ |
148 << " download = " << download->DebugString(false); | 152 << " download = " << download->DebugString(false); |
149 updated_ = true; | 153 updated_ = true; |
150 DownloadItem::DownloadState new_state = download->GetState(); | 154 DownloadItem::DownloadState new_state = download->GetState(); |
151 if (last_state_ == DownloadItem::IN_PROGRESS && | 155 if (last_state_ == DownloadItem::IN_PROGRESS && |
152 new_state == DownloadItem::INTERRUPTED) { | 156 new_state == DownloadItem::INTERRUPTED) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 } | 210 } |
207 | 211 |
208 ACTION_P(InvokeClosure, closure) { | 212 ACTION_P(InvokeClosure, closure) { |
209 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closure); | 213 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, closure); |
210 } | 214 } |
211 | 215 |
212 } // namespace | 216 } // namespace |
213 | 217 |
214 class DownloadItemTest : public testing::Test { | 218 class DownloadItemTest : public testing::Test { |
215 public: | 219 public: |
216 DownloadItemTest() { | 220 DownloadItemTest() |
221 : delegate_(), next_download_id_(DownloadItem::kInvalidId + 1) { | |
217 base::FeatureList::ClearInstanceForTesting(); | 222 base::FeatureList::ClearInstanceForTesting(); |
218 scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); | 223 scoped_ptr<base::FeatureList> feature_list(new base::FeatureList); |
219 feature_list->InitializeFromCommandLine(features::kDownloadResumption.name, | 224 feature_list->InitializeFromCommandLine(features::kDownloadResumption.name, |
220 std::string()); | 225 std::string()); |
221 base::FeatureList::SetInstance(std::move(feature_list)); | 226 base::FeatureList::SetInstance(std::move(feature_list)); |
227 | |
228 create_info_.reset(new DownloadCreateInfo()); | |
229 create_info_->save_info = | |
230 scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); | |
231 create_info_->save_info->prompt_for_save_location = false; | |
232 create_info_->url_chain.push_back(GURL("http://example.com/download")); | |
233 create_info_->etag = "SomethingToSatisfyResumption"; | |
222 } | 234 } |
223 | 235 |
224 ~DownloadItemTest() { | 236 ~DownloadItemTest() { |
225 RunAllPendingInMessageLoops(); | 237 RunAllPendingInMessageLoops(); |
226 STLDeleteElements(&allocated_downloads_); | 238 STLDeleteElements(&allocated_downloads_); |
227 } | 239 } |
228 | 240 |
229 DownloadItemImpl* CreateDownloadItemWithCreateInfo( | 241 DownloadItemImpl* CreateDownloadItemWithCreateInfo( |
230 scoped_ptr<DownloadCreateInfo> info) { | 242 scoped_ptr<DownloadCreateInfo> info) { |
231 DownloadItemImpl* download = new DownloadItemImpl( | 243 DownloadItemImpl* download = new DownloadItemImpl( |
232 &delegate_, next_download_id_++, *(info.get()), net::BoundNetLog()); | 244 &delegate_, next_download_id_++, *(info.get()), net::BoundNetLog()); |
233 allocated_downloads_.insert(download); | 245 allocated_downloads_.insert(download); |
234 return download; | 246 return download; |
235 } | 247 } |
236 | 248 |
237 // This class keeps ownership of the created download item; it will | 249 // This class keeps ownership of the created download item; it will |
238 // be torn down at the end of the test unless DestroyDownloadItem is | 250 // be torn down at the end of the test unless DestroyDownloadItem is |
239 // called. | 251 // called. |
240 DownloadItemImpl* CreateDownloadItem() { | 252 DownloadItemImpl* CreateDownloadItem() { |
241 scoped_ptr<DownloadCreateInfo> info; | 253 create_info_->download_id = ++next_download_id_; |
242 | 254 DownloadItemImpl* download = |
243 info.reset(new DownloadCreateInfo()); | 255 new DownloadItemImpl(&delegate_, create_info_->download_id, |
244 info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); | 256 *create_info_, net::BoundNetLog()); |
245 info->save_info->prompt_for_save_location = false; | 257 allocated_downloads_.insert(download); |
246 info->url_chain.push_back(GURL("http://example.com/download")); | 258 return download; |
247 info->etag = "SomethingToSatisfyResumption"; | |
248 | |
249 return CreateDownloadItemWithCreateInfo(std::move(info)); | |
250 } | 259 } |
251 | 260 |
252 // Add DownloadFile to DownloadItem | 261 // Add DownloadFile to DownloadItem |
253 MockDownloadFile* CallDownloadItemStart( | 262 MockDownloadFile* CallDownloadItemStart( |
254 DownloadItemImpl* item, | 263 DownloadItemImpl* item, |
255 DownloadItemImplDelegate::DownloadTargetCallback* callback) { | 264 DownloadItemImplDelegate::DownloadTargetCallback* callback) { |
256 MockDownloadFile* mock_download_file(new StrictMock<MockDownloadFile>); | 265 MockDownloadFile* mock_download_file = nullptr; |
257 scoped_ptr<DownloadFile> download_file(mock_download_file); | 266 scoped_ptr<DownloadFile> download_file; |
258 EXPECT_CALL(*mock_download_file, Initialize(_)); | |
259 if (callback) { | 267 if (callback) { |
260 // Save the callback. | 268 // Save the callback. |
261 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) | 269 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) |
262 .WillOnce(SaveArg<1>(callback)); | 270 .WillOnce(SaveArg<1>(callback)); |
263 } else { | 271 } else { |
264 // Drop it on the floor. | 272 // Drop it on the floor. |
265 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); | 273 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); |
266 } | 274 } |
267 | 275 |
268 scoped_ptr<DownloadRequestHandleInterface> request_handle( | 276 // Only create a DownloadFile if the request was successful. |
277 if (create_info_->result == DOWNLOAD_INTERRUPT_REASON_NONE) { | |
278 mock_download_file = new StrictMock<MockDownloadFile>; | |
279 download_file.reset(mock_download_file); | |
280 EXPECT_CALL(*mock_download_file, Initialize(_)) | |
281 .WillOnce(InvokeCallbackWithParam(DOWNLOAD_INTERRUPT_REASON_NONE)); | |
282 EXPECT_CALL(*mock_download_file, FullPath()) | |
283 .WillRepeatedly(Return(base::FilePath())); | |
284 } | |
285 | |
286 scoped_ptr<MockRequestHandle> request_handle( | |
269 new NiceMock<MockRequestHandle>); | 287 new NiceMock<MockRequestHandle>); |
270 item->Start(std::move(download_file), std::move(request_handle)); | 288 EXPECT_CALL(*request_handle, GetWebContents()) |
289 .WillRepeatedly(Return(GetWebContents())); | |
290 item->Start(std::move(download_file), std::move(request_handle), | |
291 *create_info_); | |
271 RunAllPendingInMessageLoops(); | 292 RunAllPendingInMessageLoops(); |
272 | 293 |
273 // So that we don't have a function writing to a stack variable | 294 // So that we don't have a function writing to a stack variable |
274 // lying around if the above failed. | 295 // lying around if the above failed. |
275 mock_delegate()->VerifyAndClearExpectations(); | 296 mock_delegate()->VerifyAndClearExpectations(); |
276 EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_)) | 297 EXPECT_CALL(*mock_delegate(), AssertStateConsistent(_)) |
277 .WillRepeatedly(Return()); | 298 .WillRepeatedly(Return()); |
278 EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_)) | 299 EXPECT_CALL(*mock_delegate(), ShouldOpenFileBasedOnExtension(_)) |
279 .WillRepeatedly(Return(false)); | 300 .WillRepeatedly(Return(false)); |
280 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _)) | 301 EXPECT_CALL(*mock_delegate(), ShouldOpenDownload(_, _)) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
345 | 366 |
346 MockDelegate* mock_delegate() { | 367 MockDelegate* mock_delegate() { |
347 return &delegate_; | 368 return &delegate_; |
348 } | 369 } |
349 | 370 |
350 void OnDownloadFileAcquired(base::FilePath* return_path, | 371 void OnDownloadFileAcquired(base::FilePath* return_path, |
351 const base::FilePath& path) { | 372 const base::FilePath& path) { |
352 *return_path = path; | 373 *return_path = path; |
353 } | 374 } |
354 | 375 |
376 DownloadCreateInfo* create_info() { return create_info_.get(); } | |
377 | |
378 virtual WebContents* GetWebContents() { return nullptr; } | |
379 | |
355 private: | 380 private: |
356 int next_download_id_ = DownloadItem::kInvalidId + 1; | |
357 StrictMock<MockDelegate> delegate_; | 381 StrictMock<MockDelegate> delegate_; |
358 std::set<DownloadItem*> allocated_downloads_; | 382 std::set<DownloadItem*> allocated_downloads_; |
383 scoped_ptr<DownloadCreateInfo> create_info_; | |
384 uint32_t next_download_id_ = DownloadItem::kInvalidId + 1; | |
359 TestBrowserThreadBundle thread_bundle_; | 385 TestBrowserThreadBundle thread_bundle_; |
360 }; | 386 }; |
361 | 387 |
388 // Test fixture for resumption tests. The fixture takes a GTest parameter of | |
389 // type 'bool'. If the parameter is true, then the DownloadItem has a valid | |
390 // WebContents. It would have a null WebContents otherwise. Whether or not a | |
391 // WebContents exists has a bearing on the code path used for resumption. Hence | |
392 // it's important to exercise both possibilities for these tests. | |
393 class DownloadItemTestWithResumption | |
asanka
2016/02/12 16:06:49
No longer need two sets of tests since there's onl
Randy Smith (Not in Mondays)
2016/02/12 19:10:28
Acknowledged.
| |
394 : public DownloadItemTest, | |
395 public ::testing::WithParamInterface<bool> { | |
396 public: | |
397 void SetUp() override { | |
398 browser_context_.reset(new TestBrowserContext); | |
399 if (GetParam()) { | |
400 scoped_refptr<SiteInstance> site_instance( | |
401 SiteInstance::Create(browser_context_.get())); | |
402 web_contents_.reset(WebContentsTester::CreateTestWebContents( | |
403 browser_context_.get(), site_instance.get())); | |
404 } | |
405 DownloadItemTest::SetUp(); | |
406 } | |
407 | |
408 void TearDown() override { | |
409 DownloadItemTest::TearDown(); | |
410 web_contents_.reset(); | |
411 browser_context_.reset(); | |
412 } | |
413 | |
414 WebContents* GetWebContents() override { return web_contents_.get(); } | |
415 | |
416 BrowserContext* GetBrowserContext() { return browser_context_.get(); } | |
417 | |
418 private: | |
419 scoped_ptr<TestBrowserContext> browser_context_; | |
420 scoped_ptr<WebContents> web_contents_; | |
421 }; | |
422 | |
423 INSTANTIATE_TEST_CASE_P(WithAndWithoutWebContents, | |
424 DownloadItemTestWithResumption, | |
425 ::testing::Bool()); | |
426 | |
362 // Tests to ensure calls that change a DownloadItem generate an update to | 427 // Tests to ensure calls that change a DownloadItem generate an update to |
363 // observers. | 428 // observers. |
364 // State changing functions not tested: | 429 // State changing functions not tested: |
365 // void OpenDownload(); | 430 // void OpenDownload(); |
366 // void ShowDownloadInShell(); | 431 // void ShowDownloadInShell(); |
367 // void CompleteDelayedDownload(); | 432 // void CompleteDelayedDownload(); |
368 // set_* mutators | 433 // set_* mutators |
369 | 434 |
370 TEST_F(DownloadItemTest, NotificationAfterUpdate) { | 435 TEST_F(DownloadItemTest, NotificationAfterUpdate) { |
371 DownloadItemImpl* item = CreateDownloadItem(); | 436 DownloadItemImpl* item = CreateDownloadItem(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
428 } | 493 } |
429 | 494 |
430 TEST_F(DownloadItemTest, NotificationAfterDestroyed) { | 495 TEST_F(DownloadItemTest, NotificationAfterDestroyed) { |
431 DownloadItemImpl* item = CreateDownloadItem(); | 496 DownloadItemImpl* item = CreateDownloadItem(); |
432 TestDownloadItemObserver observer(item); | 497 TestDownloadItemObserver observer(item); |
433 | 498 |
434 DestroyDownloadItem(item); | 499 DestroyDownloadItem(item); |
435 ASSERT_TRUE(observer.download_destroyed()); | 500 ASSERT_TRUE(observer.download_destroyed()); |
436 } | 501 } |
437 | 502 |
438 TEST_F(DownloadItemTest, ContinueAfterInterrupted) { | 503 // Test that a download is resumed automatcially after a continuable interrupt. |
439 TestBrowserContext test_browser_context; | 504 TEST_P(DownloadItemTestWithResumption, ContinueAfterInterrupted) { |
440 DownloadItemImpl* item = CreateDownloadItem(); | 505 DownloadItemImpl* item = CreateDownloadItem(); |
441 TestDownloadItemObserver observer(item); | 506 TestDownloadItemObserver observer(item); |
442 MockDownloadFile* download_file = | 507 MockDownloadFile* download_file = |
443 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 508 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
444 | 509 |
445 // Interrupt the download, using a continuable interrupt. | 510 // Interrupt the download, using a continuable interrupt. |
446 EXPECT_CALL(*download_file, FullPath()) | 511 EXPECT_CALL(*download_file, FullPath()) |
447 .WillOnce(Return(base::FilePath())); | 512 .WillOnce(Return(base::FilePath())); |
448 EXPECT_CALL(*download_file, Detach()); | 513 EXPECT_CALL(*download_file, Detach()); |
449 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | 514 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
450 .WillRepeatedly(Return(&test_browser_context)); | 515 .WillRepeatedly(Return(GetBrowserContext())); |
451 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1); | 516 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)).Times(1); |
452 item->DestinationObserverAsWeakPtr()->DestinationError( | 517 item->DestinationObserverAsWeakPtr()->DestinationError( |
453 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 518 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
454 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 519 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
455 // Since the download is resumed automatically, the interrupt count doesn't | 520 // Since the download is resumed automatically, the interrupt count doesn't |
456 // increase. | 521 // increase. |
457 ASSERT_EQ(0, observer.interrupt_count()); | 522 ASSERT_EQ(0, observer.interrupt_count()); |
458 | 523 |
459 // Test expectations verify that ResumeInterruptedDownload() is called (by way | 524 // Test expectations verify that ResumeInterruptedDownload() is called (by way |
460 // of MockResumeInterruptedDownload) after the download is interrupted. But | 525 // of MockResumeInterruptedDownload) after the download is interrupted. But |
461 // the mock doesn't follow through with the resumption. | 526 // the mock doesn't follow through with the resumption. |
462 // ResumeInterruptedDownload() being called is sufficient for verifying that | 527 // ResumeInterruptedDownload() being called is sufficient for verifying that |
463 // the automatic resumption was triggered. | 528 // the automatic resumption was triggered. |
464 RunAllPendingInMessageLoops(); | 529 RunAllPendingInMessageLoops(); |
465 | 530 |
466 // The download item is currently in RESUMING_INTERNAL state, which maps to | 531 // The download item is currently in RESUMING_INTERNAL state, which maps to |
467 // IN_PROGRESS. | 532 // IN_PROGRESS. |
468 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); | 533 CleanupItem(item, nullptr, DownloadItem::IN_PROGRESS); |
469 } | 534 } |
470 | 535 |
471 // Same as above, but with a non-continuable interrupt. | 536 // Test that automatic resumption doesn't happen after a non-continuable |
472 TEST_F(DownloadItemTest, RestartAfterInterrupted) { | 537 // interrupt. |
538 TEST_P(DownloadItemTestWithResumption, RestartAfterInterrupted) { | |
473 DownloadItemImpl* item = CreateDownloadItem(); | 539 DownloadItemImpl* item = CreateDownloadItem(); |
474 TestDownloadItemObserver observer(item); | 540 TestDownloadItemObserver observer(item); |
475 MockDownloadFile* download_file = | 541 MockDownloadFile* download_file = |
476 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 542 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
477 | 543 |
478 // Interrupt the download, using a restartable interrupt. | 544 // Interrupt the download, using a restartable interrupt. |
479 EXPECT_CALL(*download_file, Cancel()); | 545 EXPECT_CALL(*download_file, Cancel()); |
480 item->DestinationObserverAsWeakPtr()->DestinationError( | 546 item->DestinationObserverAsWeakPtr()->DestinationError( |
481 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 547 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
482 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 548 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
(...skipping 26 matching lines...) Expand all Loading... | |
509 RunAllPendingInMessageLoops(); | 575 RunAllPendingInMessageLoops(); |
510 | 576 |
511 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 577 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
512 // Should not try to auto-resume. | 578 // Should not try to auto-resume. |
513 ASSERT_EQ(1, observer.interrupt_count()); | 579 ASSERT_EQ(1, observer.interrupt_count()); |
514 ASSERT_EQ(0, observer.resume_count()); | 580 ASSERT_EQ(0, observer.resume_count()); |
515 | 581 |
516 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); | 582 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); |
517 } | 583 } |
518 | 584 |
519 TEST_F(DownloadItemTest, LimitRestartsAfterInterrupted) { | 585 TEST_P(DownloadItemTestWithResumption, LimitRestartsAfterInterrupted) { |
520 TestBrowserContext test_browser_context; | |
521 DownloadItemImpl* item = CreateDownloadItem(); | 586 DownloadItemImpl* item = CreateDownloadItem(); |
522 base::WeakPtr<DownloadDestinationObserver> as_observer( | 587 base::WeakPtr<DownloadDestinationObserver> as_observer( |
523 item->DestinationObserverAsWeakPtr()); | 588 item->DestinationObserverAsWeakPtr()); |
524 TestDownloadItemObserver observer(item); | 589 TestDownloadItemObserver observer(item); |
525 MockDownloadFile* mock_download_file(nullptr); | 590 MockDownloadFile* mock_download_file(nullptr); |
526 scoped_ptr<DownloadFile> download_file; | 591 scoped_ptr<DownloadFile> download_file; |
527 MockRequestHandle* mock_request_handle(nullptr); | 592 MockRequestHandle* mock_request_handle(nullptr); |
528 scoped_ptr<DownloadRequestHandleInterface> request_handle; | 593 scoped_ptr<DownloadRequestHandleInterface> request_handle; |
529 DownloadItemImplDelegate::DownloadTargetCallback callback; | 594 DownloadItemImplDelegate::DownloadTargetCallback callback; |
530 | 595 |
531 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) | 596 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) |
532 .WillRepeatedly(SaveArg<1>(&callback)); | 597 .WillRepeatedly(SaveArg<1>(&callback)); |
533 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | 598 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
534 .WillRepeatedly(Return(&test_browser_context)); | 599 .WillRepeatedly(Return(GetBrowserContext())); |
535 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)) | 600 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)) |
536 .Times(DownloadItemImpl::kMaxAutoResumeAttempts); | 601 .Times(DownloadItemImpl::kMaxAutoResumeAttempts); |
537 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { | 602 for (int i = 0; i < (DownloadItemImpl::kMaxAutoResumeAttempts + 1); ++i) { |
538 DVLOG(20) << "Loop iteration " << i; | 603 SCOPED_TRACE(::testing::Message() << "Iteration " << i); |
539 | 604 |
540 mock_download_file = new NiceMock<MockDownloadFile>; | 605 mock_download_file = new NiceMock<MockDownloadFile>; |
541 download_file.reset(mock_download_file); | 606 download_file.reset(mock_download_file); |
542 mock_request_handle = new NiceMock<MockRequestHandle>; | 607 mock_request_handle = new NiceMock<MockRequestHandle>; |
543 request_handle.reset(mock_request_handle); | 608 request_handle.reset(mock_request_handle); |
544 | 609 |
545 ON_CALL(*mock_download_file, FullPath()) | 610 ON_CALL(*mock_download_file, FullPath()) |
546 .WillByDefault(Return(base::FilePath())); | 611 .WillByDefault(Return(base::FilePath())); |
547 | 612 |
548 // Copied key parts of DoIntermediateRename & CallDownloadItemStart | 613 // Copied key parts of DoIntermediateRename & CallDownloadItemStart |
549 // to allow for holding onto the request handle. | 614 // to allow for holding onto the request handle. |
550 item->Start(std::move(download_file), std::move(request_handle)); | 615 item->Start(std::move(download_file), std::move(request_handle), |
616 *create_info()); | |
551 RunAllPendingInMessageLoops(); | 617 RunAllPendingInMessageLoops(); |
552 | 618 |
553 base::FilePath target_path(kDummyTargetPath); | 619 base::FilePath target_path(kDummyTargetPath); |
554 base::FilePath intermediate_path(kDummyIntermediatePath); | 620 base::FilePath intermediate_path(kDummyIntermediatePath); |
555 if (i == 0) { | 621 if (i == 0) { |
556 // RenameAndUniquify is only called the first time. In all the subsequent | 622 // RenameAndUniquify is only called the first time. In all the subsequent |
557 // iterations, the intermediate file already has the correct name, hence | 623 // iterations, the intermediate file already has the correct name, hence |
558 // no rename is necessary. | 624 // no rename is necessary. |
559 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) | 625 EXPECT_CALL(*mock_download_file, RenameAndUniquify(intermediate_path, _)) |
560 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, | 626 .WillOnce(ScheduleRenameCallback(DOWNLOAD_INTERRUPT_REASON_NONE, |
561 intermediate_path)); | 627 intermediate_path)); |
562 } | 628 } |
563 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, | 629 callback.Run(target_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE, |
564 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); | 630 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, intermediate_path); |
565 RunAllPendingInMessageLoops(); | 631 RunAllPendingInMessageLoops(); |
566 | 632 |
567 // Use a continuable interrupt. | 633 // Use a continuable interrupt. |
568 item->DestinationObserverAsWeakPtr()->DestinationError( | 634 item->DestinationObserverAsWeakPtr()->DestinationError( |
569 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 635 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
570 | 636 |
637 RunAllPendingInMessageLoops(); | |
571 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); | 638 ::testing::Mock::VerifyAndClearExpectations(mock_download_file); |
572 } | 639 } |
573 | 640 |
574 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 641 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
575 EXPECT_EQ(1, observer.interrupt_count()); | 642 EXPECT_EQ(1, observer.interrupt_count()); |
576 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); | 643 CleanupItem(item, nullptr, DownloadItem::INTERRUPTED); |
577 } | 644 } |
578 | 645 |
646 // If the download attempts to resume and the resumption request fails, the | |
647 // subsequent Start() call shouldn't update the origin state (URL redirect | |
648 // chains, Content-Disposition, download URL, etc..) | |
649 TEST_P(DownloadItemTestWithResumption, | |
650 FailedResumptionDoesntUpdateOriginState) { | |
651 const char kContentDisposition[] = "attachment; filename=foo"; | |
652 const char kFirstETag[] = "ABC"; | |
653 const char kFirstLastModified[] = "Yesterday"; | |
654 const char kFirstURL[] = "http://www.example.com/download"; | |
655 create_info()->content_disposition = kContentDisposition; | |
656 create_info()->etag = kFirstETag; | |
657 create_info()->last_modified = kFirstLastModified; | |
658 create_info()->url_chain.push_back(GURL(kFirstURL)); | |
659 | |
660 DownloadItemImpl* item = CreateDownloadItem(); | |
661 MockDownloadFile* download_file = | |
662 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | |
663 EXPECT_EQ(kContentDisposition, item->GetContentDisposition()); | |
664 EXPECT_EQ(kFirstETag, item->GetETag()); | |
665 EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime()); | |
666 EXPECT_EQ(kFirstURL, item->GetURL().spec()); | |
667 | |
668 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload(_, _)); | |
669 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | |
670 .WillRepeatedly(Return(GetBrowserContext())); | |
671 EXPECT_CALL(*download_file, Detach()); | |
672 item->DestinationObserverAsWeakPtr()->DestinationError( | |
673 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | |
674 RunAllPendingInMessageLoops(); | |
675 EXPECT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | |
676 | |
677 // Now change the create info. The changes should not cause the DownloadItem | |
678 // to be updated. | |
679 const char kSecondContentDisposition[] = "attachment; filename=bar"; | |
680 const char kSecondETag[] = "123"; | |
681 const char kSecondLastModified[] = "Today"; | |
682 const char kSecondURL[] = "http://example.com/another-download"; | |
683 create_info()->content_disposition = kSecondContentDisposition; | |
684 create_info()->etag = kSecondETag; | |
685 create_info()->last_modified = kSecondLastModified; | |
686 create_info()->url_chain.clear(); | |
687 create_info()->url_chain.push_back(GURL(kSecondURL)); | |
688 create_info()->result = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED; | |
689 | |
690 // The following ends up calling DownloadItem::Start(), but shouldn't result | |
691 // in an origin update. | |
692 DownloadItemImplDelegate::DownloadTargetCallback download_target_callback; | |
693 download_file = CallDownloadItemStart(item, &download_target_callback); | |
694 | |
695 EXPECT_EQ(kContentDisposition, item->GetContentDisposition()); | |
696 EXPECT_EQ(kFirstETag, item->GetETag()); | |
697 EXPECT_EQ(kFirstLastModified, item->GetLastModifiedTime()); | |
698 EXPECT_EQ(kFirstURL, item->GetURL().spec()); | |
699 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | |
700 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, item->GetLastReason()); | |
701 } | |
702 | |
579 // Test that resumption uses the final URL in a URL chain when resuming. | 703 // Test that resumption uses the final URL in a URL chain when resuming. |
580 TEST_F(DownloadItemTest, ResumeUsingFinalURL) { | 704 TEST_P(DownloadItemTestWithResumption, ResumeUsingFinalURL) { |
581 TestBrowserContext test_browser_context; | 705 create_info()->save_info->prompt_for_save_location = false; |
582 scoped_ptr<DownloadCreateInfo> create_info(new DownloadCreateInfo); | 706 create_info()->url_chain.clear(); |
583 create_info->save_info = scoped_ptr<DownloadSaveInfo>(new DownloadSaveInfo()); | 707 create_info()->url_chain.push_back(GURL("http://example.com/a")); |
584 create_info->save_info->prompt_for_save_location = false; | 708 create_info()->url_chain.push_back(GURL("http://example.com/b")); |
585 create_info->etag = "SomethingToSatisfyResumption"; | 709 create_info()->url_chain.push_back(GURL("http://example.com/c")); |
586 create_info->url_chain.push_back(GURL("http://example.com/a")); | |
587 create_info->url_chain.push_back(GURL("http://example.com/b")); | |
588 create_info->url_chain.push_back(GURL("http://example.com/c")); | |
589 | 710 |
590 DownloadItemImpl* item = | 711 DownloadItemImpl* item = CreateDownloadItem(); |
591 CreateDownloadItemWithCreateInfo(std::move(create_info)); | |
592 TestDownloadItemObserver observer(item); | 712 TestDownloadItemObserver observer(item); |
593 MockDownloadFile* download_file = | 713 MockDownloadFile* download_file = |
594 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | 714 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); |
595 | 715 |
596 // Interrupt the download, using a continuable interrupt. | 716 // Interrupt the download, using a continuable interrupt. |
597 EXPECT_CALL(*download_file, FullPath()).WillOnce(Return(base::FilePath())); | 717 EXPECT_CALL(*download_file, FullPath()).WillOnce(Return(base::FilePath())); |
598 EXPECT_CALL(*download_file, Detach()); | 718 EXPECT_CALL(*download_file, Detach()); |
599 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) | 719 EXPECT_CALL(*mock_delegate(), GetBrowserContext()) |
600 .WillRepeatedly(Return(&test_browser_context)); | 720 .WillRepeatedly(Return(GetBrowserContext())); |
601 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( | 721 EXPECT_CALL(*mock_delegate(), MockResumeInterruptedDownload( |
602 Property(&DownloadUrlParameters::url, | 722 Property(&DownloadUrlParameters::url, |
603 GURL("http://example.com/c")), | 723 GURL("http://example.com/c")), |
604 _)) | 724 _)) |
605 .Times(1); | 725 .Times(1); |
606 item->DestinationObserverAsWeakPtr()->DestinationError( | 726 item->DestinationObserverAsWeakPtr()->DestinationError( |
607 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); | 727 DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR); |
608 | 728 |
609 // Test expectations verify that ResumeInterruptedDownload() is called (by way | 729 // Test expectations verify that ResumeInterruptedDownload() is called (by way |
610 // of MockResumeInterruptedDownload) after the download is interrupted. But | 730 // of MockResumeInterruptedDownload) after the download is interrupted. But |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
713 TEST_F(DownloadItemTest, NotificationAfterTogglePause) { | 833 TEST_F(DownloadItemTest, NotificationAfterTogglePause) { |
714 DownloadItemImpl* item = CreateDownloadItem(); | 834 DownloadItemImpl* item = CreateDownloadItem(); |
715 TestDownloadItemObserver observer(item); | 835 TestDownloadItemObserver observer(item); |
716 MockDownloadFile* mock_download_file(new MockDownloadFile); | 836 MockDownloadFile* mock_download_file(new MockDownloadFile); |
717 scoped_ptr<DownloadFile> download_file(mock_download_file); | 837 scoped_ptr<DownloadFile> download_file(mock_download_file); |
718 scoped_ptr<DownloadRequestHandleInterface> request_handle( | 838 scoped_ptr<DownloadRequestHandleInterface> request_handle( |
719 new NiceMock<MockRequestHandle>); | 839 new NiceMock<MockRequestHandle>); |
720 | 840 |
721 EXPECT_CALL(*mock_download_file, Initialize(_)); | 841 EXPECT_CALL(*mock_download_file, Initialize(_)); |
722 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)); | 842 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)); |
723 item->Start(std::move(download_file), std::move(request_handle)); | 843 item->Start(std::move(download_file), std::move(request_handle), |
844 *create_info()); | |
724 | 845 |
725 item->Pause(); | 846 item->Pause(); |
726 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 847 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
727 | 848 |
728 ASSERT_TRUE(item->IsPaused()); | 849 ASSERT_TRUE(item->IsPaused()); |
729 | 850 |
730 item->Resume(); | 851 item->Resume(); |
731 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); | 852 ASSERT_TRUE(observer.CheckAndResetDownloadUpdated()); |
732 | 853 |
733 RunAllPendingInMessageLoops(); | 854 RunAllPendingInMessageLoops(); |
(...skipping 26 matching lines...) Expand all Loading... | |
760 | 881 |
761 // Test to make sure that Start method calls DF initialize properly. | 882 // Test to make sure that Start method calls DF initialize properly. |
762 TEST_F(DownloadItemTest, Start) { | 883 TEST_F(DownloadItemTest, Start) { |
763 MockDownloadFile* mock_download_file(new MockDownloadFile); | 884 MockDownloadFile* mock_download_file(new MockDownloadFile); |
764 scoped_ptr<DownloadFile> download_file(mock_download_file); | 885 scoped_ptr<DownloadFile> download_file(mock_download_file); |
765 DownloadItemImpl* item = CreateDownloadItem(); | 886 DownloadItemImpl* item = CreateDownloadItem(); |
766 EXPECT_CALL(*mock_download_file, Initialize(_)); | 887 EXPECT_CALL(*mock_download_file, Initialize(_)); |
767 scoped_ptr<DownloadRequestHandleInterface> request_handle( | 888 scoped_ptr<DownloadRequestHandleInterface> request_handle( |
768 new NiceMock<MockRequestHandle>); | 889 new NiceMock<MockRequestHandle>); |
769 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); | 890 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)); |
770 item->Start(std::move(download_file), std::move(request_handle)); | 891 item->Start(std::move(download_file), std::move(request_handle), |
892 *create_info()); | |
771 RunAllPendingInMessageLoops(); | 893 RunAllPendingInMessageLoops(); |
772 | 894 |
773 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); | 895 CleanupItem(item, mock_download_file, DownloadItem::IN_PROGRESS); |
774 } | 896 } |
775 | 897 |
898 // Handling of downloads initiated via a failed request. In this case, Start() | |
899 // will get called with a DownloadCreateInfo with a non-zero interrupt_reason. | |
900 TEST_F(DownloadItemTest, StartFailedDownload) { | |
901 create_info()->result = DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED; | |
902 DownloadItemImpl* item = CreateDownloadItem(); | |
903 | |
904 // DownloadFile and DownloadRequestHandleInterface objects aren't created for | |
905 // failed downloads. | |
906 scoped_ptr<DownloadFile> null_download_file; | |
907 scoped_ptr<DownloadRequestHandleInterface> null_request_handle; | |
908 DownloadItemImplDelegate::DownloadTargetCallback download_target_callback; | |
909 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(item, _)) | |
910 .WillOnce(SaveArg<1>(&download_target_callback)); | |
911 item->Start(std::move(null_download_file), std::move(null_request_handle), | |
912 *create_info()); | |
913 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | |
914 RunAllPendingInMessageLoops(); | |
915 | |
916 // The DownloadItemImpl should attempt to determine a target path even if the | |
917 // download was interrupted. | |
918 ASSERT_FALSE(download_target_callback.is_null()); | |
919 ASSERT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | |
920 base::FilePath target_path(FILE_PATH_LITERAL("foo")); | |
921 download_target_callback.Run(target_path, | |
922 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
923 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, target_path); | |
924 RunAllPendingInMessageLoops(); | |
925 | |
926 EXPECT_EQ(target_path, item->GetTargetFilePath()); | |
927 CleanupItem(item, NULL, DownloadItem::INTERRUPTED); | |
928 } | |
929 | |
776 // Test that the delegate is invoked after the download file is renamed. | 930 // Test that the delegate is invoked after the download file is renamed. |
777 TEST_F(DownloadItemTest, CallbackAfterRename) { | 931 TEST_F(DownloadItemTest, CallbackAfterRename) { |
778 DownloadItemImpl* item = CreateDownloadItem(); | 932 DownloadItemImpl* item = CreateDownloadItem(); |
779 DownloadItemImplDelegate::DownloadTargetCallback callback; | 933 DownloadItemImplDelegate::DownloadTargetCallback callback; |
780 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); | 934 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
781 base::FilePath final_path( | 935 base::FilePath final_path( |
782 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); | 936 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); |
783 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 937 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
784 base::FilePath new_intermediate_path( | 938 base::FilePath new_intermediate_path( |
785 final_path.InsertBeforeExtensionASCII("y")); | 939 final_path.InsertBeforeExtensionASCII("y")); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
882 ::testing::Mock::VerifyAndClearExpectations(download_file); | 1036 ::testing::Mock::VerifyAndClearExpectations(download_file); |
883 mock_delegate()->VerifyAndClearExpectations(); | 1037 mock_delegate()->VerifyAndClearExpectations(); |
884 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 1038 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
885 EXPECT_TRUE(item->GetFullPath().empty()); | 1039 EXPECT_TRUE(item->GetFullPath().empty()); |
886 EXPECT_EQ(final_path, item->GetTargetFilePath()); | 1040 EXPECT_EQ(final_path, item->GetTargetFilePath()); |
887 } | 1041 } |
888 | 1042 |
889 // As above. But if the download can be resumed by continuing, then the | 1043 // As above. But if the download can be resumed by continuing, then the |
890 // intermediate path should be retained when the download is interrupted after | 1044 // intermediate path should be retained when the download is interrupted after |
891 // the intermediate rename succeeds. | 1045 // the intermediate rename succeeds. |
892 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Continue) { | 1046 TEST_P(DownloadItemTestWithResumption, |
1047 InterruptedBeforeIntermediateRename_Continue) { | |
893 DownloadItemImpl* item = CreateDownloadItem(); | 1048 DownloadItemImpl* item = CreateDownloadItem(); |
894 DownloadItemImplDelegate::DownloadTargetCallback callback; | 1049 DownloadItemImplDelegate::DownloadTargetCallback callback; |
895 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); | 1050 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
896 item->DestinationObserverAsWeakPtr()->DestinationError( | 1051 item->DestinationObserverAsWeakPtr()->DestinationError( |
897 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); | 1052 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); |
898 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1053 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
899 | 1054 |
900 base::FilePath final_path( | 1055 base::FilePath final_path( |
901 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); | 1056 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); |
902 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 1057 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
(...skipping 12 matching lines...) Expand all Loading... | |
915 // All the callbacks should have happened by now. | 1070 // All the callbacks should have happened by now. |
916 ::testing::Mock::VerifyAndClearExpectations(download_file); | 1071 ::testing::Mock::VerifyAndClearExpectations(download_file); |
917 mock_delegate()->VerifyAndClearExpectations(); | 1072 mock_delegate()->VerifyAndClearExpectations(); |
918 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); | 1073 EXPECT_EQ(DownloadItem::INTERRUPTED, item->GetState()); |
919 EXPECT_EQ(new_intermediate_path, item->GetFullPath()); | 1074 EXPECT_EQ(new_intermediate_path, item->GetFullPath()); |
920 EXPECT_EQ(final_path, item->GetTargetFilePath()); | 1075 EXPECT_EQ(final_path, item->GetTargetFilePath()); |
921 } | 1076 } |
922 | 1077 |
923 // As above. If the intermediate rename fails, then the interrupt reason should | 1078 // As above. If the intermediate rename fails, then the interrupt reason should |
924 // be set to the destination error and the intermediate path should be empty. | 1079 // be set to the destination error and the intermediate path should be empty. |
925 TEST_F(DownloadItemTest, InterruptedBeforeIntermediateRename_Failed) { | 1080 TEST_P(DownloadItemTestWithResumption, |
1081 InterruptedBeforeIntermediateRename_Failed) { | |
926 DownloadItemImpl* item = CreateDownloadItem(); | 1082 DownloadItemImpl* item = CreateDownloadItem(); |
927 DownloadItemImplDelegate::DownloadTargetCallback callback; | 1083 DownloadItemImplDelegate::DownloadTargetCallback callback; |
928 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); | 1084 MockDownloadFile* download_file = CallDownloadItemStart(item, &callback); |
929 item->DestinationObserverAsWeakPtr()->DestinationError( | 1085 item->DestinationObserverAsWeakPtr()->DestinationError( |
930 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); | 1086 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); |
931 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); | 1087 ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState()); |
932 | 1088 |
933 base::FilePath final_path( | 1089 base::FilePath final_path( |
934 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); | 1090 base::FilePath(kDummyTargetPath).AppendASCII("foo.bar")); |
935 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); | 1091 base::FilePath intermediate_path(final_path.InsertBeforeExtensionASCII("x")); |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1323 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); | 1479 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); |
1324 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); | 1480 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); |
1325 item->StealDangerousDownload( | 1481 item->StealDangerousDownload( |
1326 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, | 1482 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, |
1327 weak_ptr_factory.GetWeakPtr(), | 1483 weak_ptr_factory.GetWeakPtr(), |
1328 base::Unretained(&returned_path))); | 1484 base::Unretained(&returned_path))); |
1329 RunAllPendingInMessageLoops(); | 1485 RunAllPendingInMessageLoops(); |
1330 EXPECT_EQ(full_path, returned_path); | 1486 EXPECT_EQ(full_path, returned_path); |
1331 } | 1487 } |
1332 | 1488 |
1333 TEST_F(DownloadItemTest, StealInterruptedDangerousDownload) { | 1489 TEST_P(DownloadItemTestWithResumption, StealInterruptedDangerousDownload) { |
1334 base::FilePath returned_path; | 1490 base::FilePath returned_path; |
1335 DownloadItemImpl* item = CreateDownloadItem(); | 1491 DownloadItemImpl* item = CreateDownloadItem(); |
1336 MockDownloadFile* download_file = | 1492 MockDownloadFile* download_file = |
1337 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | 1493 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); |
1338 base::FilePath full_path = item->GetFullPath(); | 1494 base::FilePath full_path = item->GetFullPath(); |
1339 EXPECT_FALSE(full_path.empty()); | 1495 EXPECT_FALSE(full_path.empty()); |
1340 EXPECT_CALL(*download_file, FullPath()) | 1496 EXPECT_CALL(*download_file, FullPath()) |
1341 .WillOnce(Return(full_path)); | 1497 .WillOnce(Return(full_path)); |
1342 EXPECT_CALL(*download_file, Detach()); | 1498 EXPECT_CALL(*download_file, Detach()); |
1343 item->DestinationObserverAsWeakPtr()->DestinationError( | 1499 item->DestinationObserverAsWeakPtr()->DestinationError( |
1344 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); | 1500 DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED); |
1345 ASSERT_TRUE(item->IsDangerous()); | 1501 ASSERT_TRUE(item->IsDangerous()); |
1346 | 1502 |
1347 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); | 1503 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); |
1348 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); | 1504 base::WeakPtrFactory<DownloadItemTest> weak_ptr_factory(this); |
1349 item->StealDangerousDownload( | 1505 item->StealDangerousDownload( |
1350 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, | 1506 base::Bind(&DownloadItemTest::OnDownloadFileAcquired, |
1351 weak_ptr_factory.GetWeakPtr(), | 1507 weak_ptr_factory.GetWeakPtr(), |
1352 base::Unretained(&returned_path))); | 1508 base::Unretained(&returned_path))); |
1353 RunAllPendingInMessageLoops(); | 1509 RunAllPendingInMessageLoops(); |
1354 EXPECT_EQ(full_path, returned_path); | 1510 EXPECT_EQ(full_path, returned_path); |
1355 } | 1511 } |
1356 | 1512 |
1357 TEST_F(DownloadItemTest, StealInterruptedNonResumableDangerousDownload) { | 1513 TEST_P(DownloadItemTestWithResumption, |
1514 StealInterruptedNonResumableDangerousDownload) { | |
1358 base::FilePath returned_path; | 1515 base::FilePath returned_path; |
1359 DownloadItemImpl* item = CreateDownloadItem(); | 1516 DownloadItemImpl* item = CreateDownloadItem(); |
1360 MockDownloadFile* download_file = | 1517 MockDownloadFile* download_file = |
1361 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); | 1518 DoIntermediateRename(item, DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE); |
1362 EXPECT_CALL(*download_file, Cancel()); | 1519 EXPECT_CALL(*download_file, Cancel()); |
1363 item->DestinationObserverAsWeakPtr()->DestinationError( | 1520 item->DestinationObserverAsWeakPtr()->DestinationError( |
1364 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 1521 DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
1365 ASSERT_TRUE(item->IsDangerous()); | 1522 ASSERT_TRUE(item->IsDangerous()); |
1366 | 1523 |
1367 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); | 1524 EXPECT_CALL(*mock_delegate(), DownloadRemoved(_)); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1544 INSTANTIATE_TEST_CASE_P(Success, | 1701 INSTANTIATE_TEST_CASE_P(Success, |
1545 DownloadItemDestinationUpdateRaceTest, | 1702 DownloadItemDestinationUpdateRaceTest, |
1546 ::testing::ValuesIn(GenerateSuccessfulEventLists())); | 1703 ::testing::ValuesIn(GenerateSuccessfulEventLists())); |
1547 | 1704 |
1548 INSTANTIATE_TEST_CASE_P(Failure, | 1705 INSTANTIATE_TEST_CASE_P(Failure, |
1549 DownloadItemDestinationUpdateRaceTest, | 1706 DownloadItemDestinationUpdateRaceTest, |
1550 ::testing::ValuesIn(GenerateFailingEventLists())); | 1707 ::testing::ValuesIn(GenerateFailingEventLists())); |
1551 | 1708 |
1552 } // namespace | 1709 } // namespace |
1553 | 1710 |
1554 TEST_P(DownloadItemDestinationUpdateRaceTest, DumpParameters) { | 1711 TEST_P(DownloadItemDestinationUpdateRaceTest, DumpParameters) { |
asanka
2016/02/12 16:06:49
This was only needed for visually verifying that w
Randy Smith (Not in Mondays)
2016/02/12 19:10:28
Acknowledged.
| |
1555 const auto parameter = GetParam(); | 1712 const auto parameter = GetParam(); |
1556 class Dump : public DownloadDestinationObserver { | 1713 class Dump : public DownloadDestinationObserver { |
1557 public: | 1714 public: |
1558 void DestinationUpdate(int64_t bytes_so_far, | 1715 void DestinationUpdate(int64_t bytes_so_far, |
1559 int64_t bytes_per_sec, | 1716 int64_t bytes_per_sec, |
1560 const std::string& hash_state) override { | 1717 const std::string& hash_state) override { |
1561 DVLOG(20) << " DestinationUpdate(bytes_so_far:" << bytes_so_far | 1718 DVLOG(20) << " DestinationUpdate(bytes_so_far:" << bytes_so_far |
1562 << " bytes_per_sec:" << bytes_per_sec | 1719 << " bytes_per_sec:" << bytes_per_sec |
1563 << " hash_state:" << hash_state << ")"; | 1720 << " hash_state:" << hash_state << ")"; |
1564 }; | 1721 }; |
(...skipping 15 matching lines...) Expand all Loading... | |
1580 for (const auto invoker : bin) | 1737 for (const auto invoker : bin) |
1581 invoker.Run(dumper_ptr); | 1738 invoker.Run(dumper_ptr); |
1582 } | 1739 } |
1583 } | 1740 } |
1584 | 1741 |
1585 TEST_P(DownloadItemDestinationUpdateRaceTest, InitDownloadFileFails) { | 1742 TEST_P(DownloadItemDestinationUpdateRaceTest, InitDownloadFileFails) { |
1586 // Expect that the download file and the request will be cancelled as a | 1743 // Expect that the download file and the request will be cancelled as a |
1587 // result. | 1744 // result. |
1588 EXPECT_CALL(*file_, Cancel()); | 1745 EXPECT_CALL(*file_, Cancel()); |
1589 EXPECT_CALL(*request_handle_, CancelRequest()); | 1746 EXPECT_CALL(*request_handle_, CancelRequest()); |
1747 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)); | |
1590 | 1748 |
1591 EXPECT_CALL(*file_, Initialize(_)) | 1749 EXPECT_CALL(*file_, Initialize(_)) |
1592 .WillOnce(InvokeCallbackWithParam( | 1750 .WillOnce(InvokeCallbackWithParam( |
1593 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED)); | 1751 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED)); |
1594 item_->Start(std::move(file_), std::move(request_handle_)); | 1752 item_->Start(std::move(file_), std::move(request_handle_), *create_info()); |
1595 | 1753 |
1596 RunAllPendingInMessageLoops(); | 1754 RunAllPendingInMessageLoops(); |
1597 | 1755 |
1598 // Since the download file initialization failed, no destination updates are | 1756 // Since the download file initialization failed, no destination updates are |
1599 // expected. No need to drain any action buckets. | 1757 // expected. No need to drain any action buckets. |
1600 EXPECT_EQ(DownloadItem::INTERRUPTED, item_->GetState()); | 1758 EXPECT_EQ(DownloadItem::INTERRUPTED, item_->GetState()); |
1601 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, | 1759 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, |
1602 item_->GetLastReason()); | 1760 item_->GetLastReason()); |
1603 } | 1761 } |
1604 | 1762 |
1605 TEST_P(DownloadItemDestinationUpdateRaceTest, DownloadCancelledByUser) { | 1763 TEST_P(DownloadItemDestinationUpdateRaceTest, DownloadCancelledByUser) { |
1606 // Expect that the download file and the request will be cancelled as a | 1764 // Expect that the download file and the request will be cancelled as a |
1607 // result. | 1765 // result. |
1608 EXPECT_CALL(*file_, Cancel()); | 1766 EXPECT_CALL(*file_, Cancel()); |
1609 EXPECT_CALL(*request_handle_, CancelRequest()); | 1767 EXPECT_CALL(*request_handle_, CancelRequest()); |
1610 | 1768 |
1611 base::RunLoop initialize_loop; | 1769 base::RunLoop initialize_loop; |
1612 DownloadFile::InitializeCallback initialize_callback; | 1770 DownloadFile::InitializeCallback initialize_callback; |
1613 EXPECT_CALL(*file_, Initialize(_)) | 1771 EXPECT_CALL(*file_, Initialize(_)) |
1614 .WillOnce(DoAll(SaveArg<0>(&initialize_callback), | 1772 .WillOnce(DoAll(SaveArg<0>(&initialize_callback), |
1615 InvokeClosure(initialize_loop.QuitClosure()))); | 1773 InvokeClosure(initialize_loop.QuitClosure()))); |
1616 | 1774 |
1617 item_->Start(std::move(file_), std::move(request_handle_)); | 1775 item_->Start(std::move(file_), std::move(request_handle_), *create_info()); |
1618 initialize_loop.Run(); | 1776 initialize_loop.Run(); |
1619 base::WeakPtr<DownloadDestinationObserver> destination_observer = | 1777 base::WeakPtr<DownloadDestinationObserver> destination_observer = |
1620 item_->DestinationObserverAsWeakPtr(); | 1778 item_->DestinationObserverAsWeakPtr(); |
1621 | 1779 |
1622 base::RunLoop target_determination_loop; | 1780 base::RunLoop target_determination_loop; |
1623 DownloadItemImplDelegate::DownloadTargetCallback target_callback; | 1781 DownloadItemImplDelegate::DownloadTargetCallback target_callback; |
1624 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) | 1782 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) |
1625 .WillOnce(DoAll(SaveArg<1>(&target_callback), | 1783 .WillOnce(DoAll(SaveArg<1>(&target_callback), |
1626 InvokeClosure(target_determination_loop.QuitClosure()))); | 1784 InvokeClosure(target_determination_loop.QuitClosure()))); |
1627 ScheduleObservations(PostInitializeFileObservations(), destination_observer); | 1785 ScheduleObservations(PostInitializeFileObservations(), destination_observer); |
(...skipping 27 matching lines...) Expand all Loading... | |
1655 EXPECT_CALL(*file_, RenameAndUniquify(_, _)) | 1813 EXPECT_CALL(*file_, RenameAndUniquify(_, _)) |
1656 .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback), | 1814 .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback), |
1657 InvokeClosure(intermediate_rename_loop.QuitClosure()))); | 1815 InvokeClosure(intermediate_rename_loop.QuitClosure()))); |
1658 | 1816 |
1659 base::RunLoop initialize_loop; | 1817 base::RunLoop initialize_loop; |
1660 DownloadFile::InitializeCallback initialize_callback; | 1818 DownloadFile::InitializeCallback initialize_callback; |
1661 EXPECT_CALL(*file_, Initialize(_)) | 1819 EXPECT_CALL(*file_, Initialize(_)) |
1662 .WillOnce(DoAll(SaveArg<0>(&initialize_callback), | 1820 .WillOnce(DoAll(SaveArg<0>(&initialize_callback), |
1663 InvokeClosure(initialize_loop.QuitClosure()))); | 1821 InvokeClosure(initialize_loop.QuitClosure()))); |
1664 | 1822 |
1665 item_->Start(std::move(file_), std::move(request_handle_)); | 1823 item_->Start(std::move(file_), std::move(request_handle_), *create_info()); |
1666 initialize_loop.Run(); | 1824 initialize_loop.Run(); |
1667 base::WeakPtr<DownloadDestinationObserver> destination_observer = | 1825 base::WeakPtr<DownloadDestinationObserver> destination_observer = |
1668 item_->DestinationObserverAsWeakPtr(); | 1826 item_->DestinationObserverAsWeakPtr(); |
1669 | 1827 |
1670 base::RunLoop target_determination_loop; | 1828 base::RunLoop target_determination_loop; |
1671 DownloadItemImplDelegate::DownloadTargetCallback target_callback; | 1829 DownloadItemImplDelegate::DownloadTargetCallback target_callback; |
1672 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) | 1830 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) |
1673 .WillOnce(DoAll(SaveArg<1>(&target_callback), | 1831 .WillOnce(DoAll(SaveArg<1>(&target_callback), |
1674 InvokeClosure(target_determination_loop.QuitClosure()))); | 1832 InvokeClosure(target_determination_loop.QuitClosure()))); |
1675 ScheduleObservations(PostInitializeFileObservations(), destination_observer); | 1833 ScheduleObservations(PostInitializeFileObservations(), destination_observer); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1718 EXPECT_CALL(*file_, RenameAndUniquify(_, _)) | 1876 EXPECT_CALL(*file_, RenameAndUniquify(_, _)) |
1719 .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback), | 1877 .WillOnce(DoAll(SaveArg<1>(&intermediate_rename_callback), |
1720 InvokeClosure(intermediate_rename_loop.QuitClosure()))); | 1878 InvokeClosure(intermediate_rename_loop.QuitClosure()))); |
1721 | 1879 |
1722 base::RunLoop initialize_loop; | 1880 base::RunLoop initialize_loop; |
1723 DownloadFile::InitializeCallback initialize_callback; | 1881 DownloadFile::InitializeCallback initialize_callback; |
1724 EXPECT_CALL(*file_, Initialize(_)) | 1882 EXPECT_CALL(*file_, Initialize(_)) |
1725 .WillOnce(DoAll(SaveArg<0>(&initialize_callback), | 1883 .WillOnce(DoAll(SaveArg<0>(&initialize_callback), |
1726 InvokeClosure(initialize_loop.QuitClosure()))); | 1884 InvokeClosure(initialize_loop.QuitClosure()))); |
1727 | 1885 |
1728 item_->Start(std::move(file_), std::move(request_handle_)); | 1886 item_->Start(std::move(file_), std::move(request_handle_), *create_info()); |
1729 initialize_loop.Run(); | 1887 initialize_loop.Run(); |
1730 base::WeakPtr<DownloadDestinationObserver> destination_observer = | 1888 base::WeakPtr<DownloadDestinationObserver> destination_observer = |
1731 item_->DestinationObserverAsWeakPtr(); | 1889 item_->DestinationObserverAsWeakPtr(); |
1732 | 1890 |
1733 base::RunLoop target_determination_loop; | 1891 base::RunLoop target_determination_loop; |
1734 DownloadItemImplDelegate::DownloadTargetCallback target_callback; | 1892 DownloadItemImplDelegate::DownloadTargetCallback target_callback; |
1735 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) | 1893 EXPECT_CALL(*mock_delegate(), DetermineDownloadTarget(_, _)) |
1736 .WillOnce(DoAll(SaveArg<1>(&target_callback), | 1894 .WillOnce(DoAll(SaveArg<1>(&target_callback), |
1737 InvokeClosure(target_determination_loop.QuitClosure()))); | 1895 InvokeClosure(target_determination_loop.QuitClosure()))); |
1738 ScheduleObservations(PostInitializeFileObservations(), destination_observer); | 1896 ScheduleObservations(PostInitializeFileObservations(), destination_observer); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1778 } | 1936 } |
1779 | 1937 |
1780 // TODO(asanka): Write tests for resuming and auto-resuming downloads which have | 1938 // TODO(asanka): Write tests for resuming and auto-resuming downloads which have |
1781 // their own brand of race conditions. | 1939 // their own brand of race conditions. |
1782 | 1940 |
1783 TEST(MockDownloadItem, Compiles) { | 1941 TEST(MockDownloadItem, Compiles) { |
1784 MockDownloadItem mock_item; | 1942 MockDownloadItem mock_item; |
1785 } | 1943 } |
1786 | 1944 |
1787 } // namespace content | 1945 } // namespace content |
OLD | NEW |