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