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