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_file_manager.h" | 5 #include "content/browser/download/download_file_manager.h" |
6 | 6 |
7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/scoped_temp_dir.h" | 10 #include "base/scoped_temp_dir.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
24 | 24 |
25 using content::BrowserThread; | 25 using content::BrowserThread; |
26 using content::BrowserThreadImpl; | 26 using content::BrowserThreadImpl; |
27 using content::DownloadId; | 27 using content::DownloadId; |
28 using content::MockDownloadManager; | 28 using content::MockDownloadManager; |
29 | 29 |
30 using ::testing::_; | 30 using ::testing::_; |
31 using ::testing::AtLeast; | 31 using ::testing::AtLeast; |
32 using ::testing::Mock; | 32 using ::testing::Mock; |
33 using ::testing::Return; | 33 using ::testing::Return; |
34 using ::testing::SaveArg; | |
34 using ::testing::StrictMock; | 35 using ::testing::StrictMock; |
35 using ::testing::StrEq; | 36 using ::testing::StrEq; |
36 | 37 |
37 namespace { | 38 namespace { |
38 | 39 |
39 // MockDownloadManager with the addition of a mock callback used for testing. | 40 // MockDownloadManager with the addition of a mock callback used for testing. |
40 class TestDownloadManager : public MockDownloadManager { | 41 class TestDownloadManager : public MockDownloadManager { |
41 public: | 42 public: |
42 MOCK_METHOD2(OnDownloadRenamed, | 43 MOCK_METHOD3(OnDownloadRenamed, |
43 void(int download_id, const FilePath& full_path)); | 44 void(int download_id, |
45 content::DownloadInterruptReason reason, | |
46 const FilePath& full_path)); | |
44 private: | 47 private: |
45 ~TestDownloadManager() {} | 48 ~TestDownloadManager() {} |
46 }; | 49 }; |
47 | 50 |
48 class MockDownloadFileFactory : | 51 class MockDownloadFileFactory : |
49 public DownloadFileManager::DownloadFileFactory { | 52 public DownloadFileManager::DownloadFileFactory { |
50 | 53 |
51 public: | 54 public: |
52 MockDownloadFileFactory() {} | 55 MockDownloadFileFactory() {} |
53 virtual ~MockDownloadFileFactory() {} | 56 virtual ~MockDownloadFileFactory() {} |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 return manager_; | 108 return manager_; |
106 } | 109 } |
107 | 110 |
108 void NullCallback() { } | 111 void NullCallback() { } |
109 | 112 |
110 } // namespace | 113 } // namespace |
111 | 114 |
112 class DownloadFileManagerTest : public testing::Test { | 115 class DownloadFileManagerTest : public testing::Test { |
113 public: | 116 public: |
114 // State of renamed file. Used with RenameFile(). | 117 // State of renamed file. Used with RenameFile(). |
115 enum RenameFileState { | 118 enum RenameFileState { |
asanka
2012/07/10 18:11:45
Remove.
| |
116 IN_PROGRESS, | 119 IN_PROGRESS, |
117 COMPLETE | 120 COMPLETE |
118 }; | 121 }; |
119 | 122 |
120 // Whether to overwrite the target filename in RenameFile(). | 123 // Whether to overwrite the target filename in RenameFile(). |
121 enum RenameFileOverwrite { | 124 enum RenameFileOverwrite { |
asanka
2012/07/10 18:11:45
Remove.
| |
122 OVERWRITE, | 125 OVERWRITE, |
123 DONT_OVERWRITE | 126 DONT_OVERWRITE |
124 }; | 127 }; |
125 | 128 |
126 static const char* kTestData1; | 129 static const char* kTestData1; |
127 static const char* kTestData2; | 130 static const char* kTestData2; |
128 static const char* kTestData3; | 131 static const char* kTestData3; |
129 static const char* kTestData4; | 132 static const char* kTestData4; |
130 static const char* kTestData5; | 133 static const char* kTestData5; |
131 static const char* kTestData6; | 134 static const char* kTestData6; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 // renamed to. If there is an existing file at | 208 // renamed to. If there is an existing file at |
206 // |new_path| and |replace| is false, then |new_path| | 209 // |new_path| and |replace| is false, then |new_path| |
207 // will be uniquified. | 210 // will be uniquified. |
208 // |rename_error| is the error to inject. For no error, | 211 // |rename_error| is the error to inject. For no error, |
209 // use content::DOWNLOAD_INTERRUPT_REASON_NONE. | 212 // use content::DOWNLOAD_INTERRUPT_REASON_NONE. |
210 // |state| whether we are renaming an in-progress download or a | 213 // |state| whether we are renaming an in-progress download or a |
211 // completed download. | 214 // completed download. |
212 // |should_overwrite| indicates whether to replace or uniquify the file. | 215 // |should_overwrite| indicates whether to replace or uniquify the file. |
213 void RenameFile(const DownloadId& id, | 216 void RenameFile(const DownloadId& id, |
214 const FilePath& new_path, | 217 const FilePath& new_path, |
215 const FilePath& unique_path, | 218 bool should_overwrite) { |
216 content::DownloadInterruptReason rename_error, | |
217 RenameFileState state, | |
218 RenameFileOverwrite should_overwrite) { | |
219 MockDownloadFile* file = download_file_factory_->GetExistingFile(id); | 219 MockDownloadFile* file = download_file_factory_->GetExistingFile(id); |
220 ASSERT_TRUE(file != NULL); | 220 ASSERT_TRUE(file != NULL); |
221 content::DownloadFile::RenameCompletionCallback rename_callback; | |
221 | 222 |
222 EXPECT_CALL(*file, Rename(unique_path)) | 223 EXPECT_CALL(*file, Rename(new_path, should_overwrite, _)) |
223 .Times(1) | 224 .WillOnce(SaveArg<2>(&rename_callback)); |
224 .WillOnce(Return(rename_error)); | |
225 | 225 |
226 if (rename_error != content::DOWNLOAD_INTERRUPT_REASON_NONE) { | 226 content::DownloadFile::RenameCompletionCallback passed_callback( |
227 EXPECT_CALL(*file, BytesSoFar()) | |
228 .Times(AtLeast(1)) | |
229 .WillRepeatedly(Return(byte_count_[id])); | |
230 EXPECT_CALL(*file, GetHashState()) | |
231 .Times(AtLeast(1)); | |
232 EXPECT_CALL(*file, GetDownloadManager()) | |
233 .Times(AtLeast(1)); | |
234 } | |
235 | |
236 download_file_manager_->RenameDownloadFile( | |
237 id, new_path, (should_overwrite == OVERWRITE), | |
238 base::Bind(&TestDownloadManager::OnDownloadRenamed, | 227 base::Bind(&TestDownloadManager::OnDownloadRenamed, |
239 download_manager_, id.local())); | 228 download_manager_, id.local())); |
240 | 229 |
241 if (rename_error != content::DOWNLOAD_INTERRUPT_REASON_NONE) { | 230 download_file_manager_->RenameDownloadFile( |
242 EXPECT_CALL(*download_manager_, | 231 id, new_path, should_overwrite, passed_callback); |
243 OnDownloadInterrupted( | 232 |
244 id.local(), | 233 EXPECT_TRUE(rename_callback.Equals(passed_callback)); |
245 byte_count_[id], | |
246 "", | |
247 rename_error)); | |
248 EXPECT_CALL(*download_manager_, | |
249 OnDownloadRenamed(id.local(), FilePath())); | |
250 ProcessAllPendingMessages(); | |
251 ++error_count_[id]; | |
252 } else { | |
253 EXPECT_CALL(*download_manager_, | |
254 OnDownloadRenamed(id.local(), unique_path)); | |
255 ProcessAllPendingMessages(); | |
256 } | |
257 } | 234 } |
258 | 235 |
259 void Complete(DownloadId id) { | 236 void Complete(DownloadId id) { |
260 MockDownloadFile* file = download_file_factory_->GetExistingFile(id); | 237 MockDownloadFile* file = download_file_factory_->GetExistingFile(id); |
261 ASSERT_TRUE(file != NULL); | 238 ASSERT_TRUE(file != NULL); |
262 | 239 |
263 EXPECT_CALL(*file, AnnotateWithSourceInformation()) | 240 EXPECT_CALL(*file, AnnotateWithSourceInformation()) |
264 .WillOnce(Return()); | 241 .WillOnce(Return()); |
265 EXPECT_CALL(*file, Detach()) | 242 EXPECT_CALL(*file, Detach()) |
266 .WillOnce(Return()); | 243 .WillOnce(Return()); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
338 TEST_F(DownloadFileManagerTest, Complete) { | 315 TEST_F(DownloadFileManagerTest, Complete) { |
339 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | 316 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); |
340 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); | 317 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); |
341 info->download_id = dummy_id; | 318 info->download_id = dummy_id; |
342 | 319 |
343 CreateDownloadFile(info.Pass()); | 320 CreateDownloadFile(info.Pass()); |
344 | 321 |
345 Complete(dummy_id); | 322 Complete(dummy_id); |
346 } | 323 } |
347 | 324 |
348 TEST_F(DownloadFileManagerTest, RenameInProgress) { | 325 TEST_F(DownloadFileManagerTest, Rename) { |
349 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | 326 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); |
350 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); | 327 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); |
351 info->download_id = dummy_id; | 328 info->download_id = dummy_id; |
352 ScopedTempDir download_dir; | |
353 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); | |
354 | |
355 CreateDownloadFile(info.Pass()); | |
356 | |
357 FilePath foo(download_dir.path().Append(FILE_PATH_LITERAL("foo.txt"))); | |
358 RenameFile(dummy_id, foo, foo, content::DOWNLOAD_INTERRUPT_REASON_NONE, | |
359 IN_PROGRESS, OVERWRITE); | |
360 | |
361 CleanUp(dummy_id); | |
362 } | |
363 | |
364 TEST_F(DownloadFileManagerTest, RenameInProgressWithUniquification) { | |
365 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | |
366 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); | |
367 info->download_id = dummy_id; | |
368 ScopedTempDir download_dir; | |
369 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); | |
370 | |
371 CreateDownloadFile(info.Pass()); | |
372 | |
373 FilePath foo(download_dir.path().Append(FILE_PATH_LITERAL("foo.txt"))); | |
374 FilePath unique_foo(foo.InsertBeforeExtension(FILE_PATH_LITERAL(" (1)"))); | |
375 ASSERT_EQ(0, file_util::WriteFile(foo, "", 0)); | |
376 RenameFile(dummy_id, foo, unique_foo, | |
377 content::DOWNLOAD_INTERRUPT_REASON_NONE, IN_PROGRESS, | |
378 DONT_OVERWRITE); | |
379 | |
380 CleanUp(dummy_id); | |
381 } | |
382 | |
383 TEST_F(DownloadFileManagerTest, RenameInProgressWithError) { | |
384 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | |
385 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); | |
386 info->download_id = dummy_id; | |
387 ScopedTempDir download_dir; | 329 ScopedTempDir download_dir; |
388 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); | 330 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); |
389 | 331 |
390 CreateDownloadFile(info.Pass()); | 332 CreateDownloadFile(info.Pass()); |
391 | 333 |
392 FilePath foo(download_dir.path().Append(FILE_PATH_LITERAL("foo.txt"))); | 334 FilePath foo(download_dir.path().Append(FILE_PATH_LITERAL("foo.txt"))); |
393 RenameFile(dummy_id, foo, foo, | 335 RenameFile(dummy_id, foo, true); |
394 content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG, | |
395 IN_PROGRESS, OVERWRITE); | |
396 | 336 |
397 CleanUp(dummy_id); | 337 CleanUp(dummy_id); |
398 } | 338 } |
399 | 339 |
400 TEST_F(DownloadFileManagerTest, RenameWithUniquification) { | 340 TEST_F(DownloadFileManagerTest, RenameNoOverwrite) { |
401 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | 341 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); |
402 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); | 342 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); |
403 info->download_id = dummy_id; | 343 info->download_id = dummy_id; |
404 ScopedTempDir download_dir; | 344 ScopedTempDir download_dir; |
405 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); | 345 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); |
406 | 346 |
407 CreateDownloadFile(info.Pass()); | 347 CreateDownloadFile(info.Pass()); |
408 | 348 |
409 FilePath foo(download_dir.path().Append(FILE_PATH_LITERAL("foo.txt"))); | 349 FilePath foo(download_dir.path().Append(FILE_PATH_LITERAL("foo.txt"))); |
410 FilePath unique_foo(foo.InsertBeforeExtension(FILE_PATH_LITERAL(" (1)"))); | 350 RenameFile(dummy_id, foo, false); |
411 // Create a file at |foo|. Since we are specifying DONT_OVERWRITE, | |
412 // RenameDownloadFile() should pick "foo (1).txt" instead of | |
413 // overwriting this file. | |
414 ASSERT_EQ(0, file_util::WriteFile(foo, "", 0)); | |
415 RenameFile(dummy_id, foo, unique_foo, | |
416 content::DOWNLOAD_INTERRUPT_REASON_NONE, COMPLETE, DONT_OVERWRITE); | |
417 | 351 |
418 CleanUp(dummy_id); | 352 CleanUp(dummy_id); |
419 } | 353 } |
420 | 354 |
421 TEST_F(DownloadFileManagerTest, RenameTwice) { | 355 TEST_F(DownloadFileManagerTest, RenameTwice) { |
422 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | 356 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); |
423 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); | 357 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); |
424 info->download_id = dummy_id; | 358 info->download_id = dummy_id; |
425 ScopedTempDir download_dir; | 359 ScopedTempDir download_dir; |
426 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); | 360 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); |
427 | 361 |
428 CreateDownloadFile(info.Pass()); | 362 CreateDownloadFile(info.Pass()); |
429 | 363 |
430 FilePath crfoo(download_dir.path().Append( | 364 FilePath crfoo(download_dir.path().Append( |
431 FILE_PATH_LITERAL("foo.txt.crdownload"))); | 365 FILE_PATH_LITERAL("foo.txt.crdownload"))); |
432 RenameFile(dummy_id, crfoo, crfoo, content::DOWNLOAD_INTERRUPT_REASON_NONE, | 366 RenameFile(dummy_id, crfoo, true); |
433 IN_PROGRESS, OVERWRITE); | |
434 | 367 |
435 FilePath foo(download_dir.path().Append(FILE_PATH_LITERAL("foo.txt"))); | 368 FilePath foo(download_dir.path().Append(FILE_PATH_LITERAL("foo.txt"))); |
436 RenameFile(dummy_id, foo, foo, content::DOWNLOAD_INTERRUPT_REASON_NONE, | 369 RenameFile(dummy_id, foo, true); |
437 COMPLETE, OVERWRITE); | |
438 | 370 |
439 CleanUp(dummy_id); | 371 CleanUp(dummy_id); |
440 } | 372 } |
441 | 373 |
442 TEST_F(DownloadFileManagerTest, TwoDownloads) { | 374 TEST_F(DownloadFileManagerTest, TwoDownloads) { |
443 // Same as StartDownload, at first. | 375 // Same as StartDownload, at first. |
444 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | 376 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); |
445 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); | 377 DownloadId dummy_id(download_manager_.get(), kDummyDownloadId); |
446 info->download_id = dummy_id; | 378 info->download_id = dummy_id; |
447 scoped_ptr<DownloadCreateInfo> info2(new DownloadCreateInfo); | 379 scoped_ptr<DownloadCreateInfo> info2(new DownloadCreateInfo); |
448 DownloadId dummy_id2(download_manager_.get(), kDummyDownloadId2); | 380 DownloadId dummy_id2(download_manager_.get(), kDummyDownloadId2); |
449 info2->download_id = dummy_id2; | 381 info2->download_id = dummy_id2; |
450 ScopedTempDir download_dir; | 382 ScopedTempDir download_dir; |
451 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); | 383 ASSERT_TRUE(download_dir.CreateUniqueTempDir()); |
452 | 384 |
453 CreateDownloadFile(info.Pass()); | 385 CreateDownloadFile(info.Pass()); |
454 CreateDownloadFile(info2.Pass()); | 386 CreateDownloadFile(info2.Pass()); |
455 | 387 |
456 FilePath crbar(download_dir.path().Append( | 388 FilePath crbar(download_dir.path().Append( |
457 FILE_PATH_LITERAL("bar.txt.crdownload"))); | 389 FILE_PATH_LITERAL("bar.txt.crdownload"))); |
458 RenameFile(dummy_id2, crbar, crbar, content::DOWNLOAD_INTERRUPT_REASON_NONE, | 390 RenameFile(dummy_id2, crbar, true); |
459 IN_PROGRESS, OVERWRITE); | |
460 | 391 |
461 FilePath crfoo(download_dir.path().Append( | 392 FilePath crfoo(download_dir.path().Append( |
462 FILE_PATH_LITERAL("foo.txt.crdownload"))); | 393 FILE_PATH_LITERAL("foo.txt.crdownload"))); |
463 RenameFile(dummy_id, crfoo, crfoo, content::DOWNLOAD_INTERRUPT_REASON_NONE, | 394 RenameFile(dummy_id, crfoo, true); |
464 IN_PROGRESS, OVERWRITE); | |
465 | 395 |
466 | 396 |
467 FilePath bar(download_dir.path().Append(FILE_PATH_LITERAL("bar.txt"))); | 397 FilePath bar(download_dir.path().Append(FILE_PATH_LITERAL("bar.txt"))); |
468 RenameFile(dummy_id2, bar, bar, content::DOWNLOAD_INTERRUPT_REASON_NONE, | 398 RenameFile(dummy_id2, bar, true); |
469 COMPLETE, OVERWRITE); | |
470 | 399 |
471 CleanUp(dummy_id2); | 400 CleanUp(dummy_id2); |
472 | 401 |
473 FilePath foo(download_dir.path().Append(FILE_PATH_LITERAL("foo.txt"))); | 402 FilePath foo(download_dir.path().Append(FILE_PATH_LITERAL("foo.txt"))); |
474 RenameFile(dummy_id, foo, foo, content::DOWNLOAD_INTERRUPT_REASON_NONE, | 403 RenameFile(dummy_id, foo, true); |
475 COMPLETE, OVERWRITE); | |
476 | 404 |
477 CleanUp(dummy_id); | 405 CleanUp(dummy_id); |
478 } | 406 } |
479 | 407 |
480 // TODO(ahendrickson) -- A test for download manager shutdown. | 408 // TODO(ahendrickson) -- A test for download manager shutdown. |
481 // Expected call sequence: | 409 // Expected call sequence: |
482 // OnDownloadManagerShutdown | 410 // OnDownloadManagerShutdown |
483 // DownloadFile::GetDownloadManager | 411 // DownloadFile::GetDownloadManager |
484 // DownloadFile::CancelDownloadRequest | 412 // DownloadFile::CancelDownloadRequest |
485 // DownloadFile::~DownloadFile | 413 // DownloadFile::~DownloadFile |
OLD | NEW |