| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <set> | 5 #include <set> |
| 6 #include <string> | 6 #include <string> |
| 7 | 7 |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
| 10 #include "base/i18n/number_formatting.h" | 10 #include "base/i18n/number_formatting.h" |
| 11 #include "base/i18n/rtl.h" | 11 #include "base/i18n/rtl.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 14 #include "base/string16.h" | 14 #include "base/string16.h" |
| 15 #include "base/string_util.h" | 15 #include "base/string_util.h" |
| 16 #include "base/utf_string_conversions.h" | 16 #include "base/utf_string_conversions.h" |
| 17 #include "build/build_config.h" | 17 #include "build/build_config.h" |
| 18 #include "chrome/browser/download/chrome_download_manager_delegate.h" | 18 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
| 19 #include "chrome/browser/download/download_item_model.h" | 19 #include "chrome/browser/download/download_item_model.h" |
| 20 #include "chrome/browser/download/download_prefs.h" | 20 #include "chrome/browser/download/download_prefs.h" |
| 21 #include "chrome/browser/download/download_util.h" | 21 #include "chrome/browser/download/download_util.h" |
| 22 #include "chrome/browser/prefs/pref_service.h" | 22 #include "chrome/browser/prefs/pref_service.h" |
| 23 #include "chrome/common/pref_names.h" | 23 #include "chrome/common/pref_names.h" |
| 24 #include "chrome/test/base/testing_profile.h" | 24 #include "chrome/test/base/testing_profile.h" |
| 25 #include "content/browser/download/download_buffer.h" | 25 #include "content/browser/download/download_buffer.h" |
| 26 #include "content/browser/download/download_create_info.h" | 26 #include "content/browser/download/download_create_info.h" |
| 27 #include "content/browser/download/download_file.h" | 27 #include "content/browser/download/download_file_impl.h" |
| 28 #include "content/browser/download/download_file_manager.h" | 28 #include "content/browser/download/download_file_manager.h" |
| 29 #include "content/browser/download/download_id_factory.h" | 29 #include "content/browser/download/download_id_factory.h" |
| 30 #include "content/browser/download/download_item.h" | 30 #include "content/browser/download/download_item.h" |
| 31 #include "content/browser/download/download_manager.h" | 31 #include "content/browser/download/download_manager.h" |
| 32 #include "content/browser/download/download_request_handle.h" | 32 #include "content/browser/download/download_request_handle.h" |
| 33 #include "content/browser/download/download_status_updater.h" | 33 #include "content/browser/download/download_status_updater.h" |
| 34 #include "content/browser/download/interrupt_reasons.h" | 34 #include "content/browser/download/interrupt_reasons.h" |
| 35 #include "content/browser/download/mock_download_file.h" |
| 35 #include "content/browser/download/mock_download_manager.h" | 36 #include "content/browser/download/mock_download_manager.h" |
| 36 #include "content/test/test_browser_thread.h" | 37 #include "content/test/test_browser_thread.h" |
| 37 #include "grit/generated_resources.h" | 38 #include "grit/generated_resources.h" |
| 38 #include "net/base/io_buffer.h" | 39 #include "net/base/io_buffer.h" |
| 39 #include "net/base/mock_file_stream.h" | |
| 40 #include "testing/gmock/include/gmock/gmock.h" | 40 #include "testing/gmock/include/gmock/gmock.h" |
| 41 #include "testing/gmock_mutant.h" | 41 #include "testing/gmock_mutant.h" |
| 42 #include "testing/gtest/include/gtest/gtest.h" | 42 #include "testing/gtest/include/gtest/gtest.h" |
| 43 #include "ui/base/l10n/l10n_util.h" | 43 #include "ui/base/l10n/l10n_util.h" |
| 44 #include "ui/base/text/bytes_formatting.h" | 44 #include "ui/base/text/bytes_formatting.h" |
| 45 | 45 |
| 46 using content::BrowserThread; | 46 using content::BrowserThread; |
| 47 | 47 |
| 48 DownloadId::Domain kValidIdDomain = "valid DownloadId::Domain"; | 48 DownloadId::Domain kValidIdDomain = "valid DownloadId::Domain"; |
| 49 | 49 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 safety_state != DownloadItem::SAFE : safety_state == DownloadItem::SAFE; | 156 safety_state != DownloadItem::SAFE : safety_state == DownloadItem::SAFE; |
| 157 } | 157 } |
| 158 | 158 |
| 159 DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest); | 159 DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest); |
| 160 }; | 160 }; |
| 161 | 161 |
| 162 const char* DownloadManagerTest::kTestData = "a;sdlfalsdfjalsdkfjad"; | 162 const char* DownloadManagerTest::kTestData = "a;sdlfalsdfjalsdkfjad"; |
| 163 const size_t DownloadManagerTest::kTestDataLen = | 163 const size_t DownloadManagerTest::kTestDataLen = |
| 164 strlen(DownloadManagerTest::kTestData); | 164 strlen(DownloadManagerTest::kTestData); |
| 165 | 165 |
| 166 // A DownloadFile that we can inject errors into. Uses MockFileStream. | 166 // A DownloadFile that we can inject errors into. |
| 167 // Note: This can't be in an anonymous namespace because it must be declared | 167 class DownloadFileWithErrors : public DownloadFileImpl { |
| 168 // as a friend of |DownloadFile| in order to access its private members. | |
| 169 class DownloadFileWithMockStream : public DownloadFile { | |
| 170 public: | 168 public: |
| 171 DownloadFileWithMockStream(DownloadCreateInfo* info, | 169 DownloadFileWithErrors(DownloadCreateInfo* info, DownloadManager* manager); |
| 172 DownloadManager* manager, | 170 virtual ~DownloadFileWithErrors() {} |
| 173 net::testing::MockFileStream* stream); | |
| 174 | 171 |
| 175 virtual ~DownloadFileWithMockStream() {} | 172 // BaseFile delegated functions. |
| 173 virtual net::Error Initialize(bool calculate_hash); |
| 174 virtual net::Error AppendDataToFile(const char* data, size_t data_len); |
| 175 virtual net::Error Rename(const FilePath& full_path); |
| 176 | 176 |
| 177 void SetForcedError(int error); | 177 void set_forced_error(net::Error error) { forced_error_ = error; } |
| 178 void clear_forced_error() { forced_error_ = net::OK; } |
| 179 net::Error forced_error() const { return forced_error_; } |
| 178 | 180 |
| 179 protected: | 181 private: |
| 180 // This version creates a |MockFileStream| instead of a |FileStream|. | 182 net::Error ReturnError(net::Error function_error) { |
| 181 virtual void CreateFileStream() OVERRIDE; | 183 if (forced_error_ != net::OK) { |
| 184 net::Error ret = forced_error_; |
| 185 clear_forced_error(); |
| 186 return ret; |
| 187 } |
| 188 |
| 189 return function_error; |
| 190 } |
| 191 |
| 192 net::Error forced_error_; |
| 182 }; | 193 }; |
| 183 | 194 |
| 184 DownloadFileWithMockStream::DownloadFileWithMockStream( | 195 DownloadFileWithErrors::DownloadFileWithErrors(DownloadCreateInfo* info, |
| 185 DownloadCreateInfo* info, | 196 DownloadManager* manager) |
| 186 DownloadManager* manager, | 197 : DownloadFileImpl(info, new DownloadRequestHandle(), manager), |
| 187 net::testing::MockFileStream* stream) | 198 forced_error_(net::OK) { |
| 188 : DownloadFile(info, new DownloadRequestHandle(), manager) { | |
| 189 DCHECK(file_stream_ == NULL); | |
| 190 file_stream_.reset(stream); | |
| 191 } | 199 } |
| 192 | 200 |
| 193 void DownloadFileWithMockStream::SetForcedError(int error) | 201 net::Error DownloadFileWithErrors::Initialize(bool calculate_hash) { |
| 194 { | 202 return ReturnError(DownloadFileImpl::Initialize(calculate_hash)); |
| 195 // |file_stream_| can only be set in the constructor and in | |
| 196 // CreateFileStream(), both of which insure that it is a |MockFileStream|. | |
| 197 net::testing::MockFileStream* mock_stream = | |
| 198 static_cast<net::testing::MockFileStream *>(file_stream_.get()); | |
| 199 mock_stream->set_forced_error(error); | |
| 200 } | 203 } |
| 201 void DownloadFileWithMockStream::CreateFileStream() { | 204 |
| 202 file_stream_.reset(new net::testing::MockFileStream); | 205 net::Error DownloadFileWithErrors::AppendDataToFile(const char* data, |
| 206 size_t data_len) { |
| 207 return ReturnError(DownloadFileImpl::AppendDataToFile(data, data_len)); |
| 208 } |
| 209 |
| 210 net::Error DownloadFileWithErrors::Rename(const FilePath& full_path) { |
| 211 return ReturnError(DownloadFileImpl::Rename(full_path)); |
| 203 } | 212 } |
| 204 | 213 |
| 205 namespace { | 214 namespace { |
| 206 | 215 |
| 207 const struct { | 216 const struct { |
| 208 const char* url; | 217 const char* url; |
| 209 const char* mime_type; | 218 const char* mime_type; |
| 210 bool save_as; | 219 bool save_as; |
| 211 bool prompt_for_download; | 220 bool prompt_for_download; |
| 212 bool expected_save_as; | 221 bool expected_save_as; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 // Safe download, download finishes AFTER file name determined. | 282 // Safe download, download finishes AFTER file name determined. |
| 274 // Needs to be renamed twice. | 283 // Needs to be renamed twice. |
| 275 { FILE_PATH_LITERAL("foo.zip"), false, false, false, 2, }, | 284 { FILE_PATH_LITERAL("foo.zip"), false, false, false, 2, }, |
| 276 // Dangerous download, download finishes AFTER file name determined. | 285 // Dangerous download, download finishes AFTER file name determined. |
| 277 // Needs to be renamed only once. | 286 // Needs to be renamed only once. |
| 278 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), true, false, false, 1, }, | 287 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), true, false, false, 1, }, |
| 279 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), false, true, false, 1, }, | 288 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), false, true, false, 1, }, |
| 280 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), true, true, false, 1, }, | 289 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), true, true, false, 1, }, |
| 281 }; | 290 }; |
| 282 | 291 |
| 283 class MockDownloadFile : public DownloadFile { | |
| 284 public: | |
| 285 MockDownloadFile(DownloadCreateInfo* info, DownloadManager* manager) | |
| 286 : DownloadFile(info, new DownloadRequestHandle(), manager), | |
| 287 renamed_count_(0) { } | |
| 288 virtual ~MockDownloadFile() { Destructed(); } | |
| 289 MOCK_METHOD1(Rename, net::Error(const FilePath&)); | |
| 290 MOCK_METHOD0(Destructed, void()); | |
| 291 | |
| 292 net::Error TestMultipleRename( | |
| 293 int expected_count, const FilePath& expected, | |
| 294 const FilePath& path) { | |
| 295 ++renamed_count_; | |
| 296 EXPECT_EQ(expected_count, renamed_count_); | |
| 297 EXPECT_EQ(expected.value(), path.value()); | |
| 298 return net::OK; | |
| 299 } | |
| 300 | |
| 301 private: | |
| 302 int renamed_count_; | |
| 303 }; | |
| 304 | |
| 305 // This is an observer that records what download IDs have opened a select | 292 // This is an observer that records what download IDs have opened a select |
| 306 // file dialog. | 293 // file dialog. |
| 307 class SelectFileObserver : public DownloadManager::Observer { | 294 class SelectFileObserver : public DownloadManager::Observer { |
| 308 public: | 295 public: |
| 309 explicit SelectFileObserver(DownloadManager* download_manager) | 296 explicit SelectFileObserver(DownloadManager* download_manager) |
| 310 : download_manager_(download_manager) { | 297 : download_manager_(download_manager) { |
| 311 DCHECK(download_manager_.get()); | 298 DCHECK(download_manager_.get()); |
| 312 download_manager_->AddObserver(this); | 299 download_manager_->AddObserver(this); |
| 313 } | 300 } |
| 314 | 301 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 // responsible for deleting it. In these unit tests, however, we | 379 // responsible for deleting it. In these unit tests, however, we |
| 393 // don't call the function that deletes it, so we do so ourselves. | 380 // don't call the function that deletes it, so we do so ourselves. |
| 394 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | 381 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); |
| 395 info->download_id = DownloadId(kValidIdDomain, static_cast<int>(i)); | 382 info->download_id = DownloadId(kValidIdDomain, static_cast<int>(i)); |
| 396 info->prompt_user_for_save_location = kStartDownloadCases[i].save_as; | 383 info->prompt_user_for_save_location = kStartDownloadCases[i].save_as; |
| 397 info->url_chain.push_back(GURL(kStartDownloadCases[i].url)); | 384 info->url_chain.push_back(GURL(kStartDownloadCases[i].url)); |
| 398 info->mime_type = kStartDownloadCases[i].mime_type; | 385 info->mime_type = kStartDownloadCases[i].mime_type; |
| 399 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle()); | 386 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle()); |
| 400 | 387 |
| 401 DownloadFile* download_file( | 388 DownloadFile* download_file( |
| 402 new DownloadFile(info.get(), new DownloadRequestHandle(), | 389 new DownloadFileImpl(info.get(), new DownloadRequestHandle(), |
| 403 download_manager_)); | 390 download_manager_)); |
| 404 AddDownloadToFileManager(info->download_id.local(), download_file); | 391 AddDownloadToFileManager(info->download_id.local(), download_file); |
| 405 download_file->Initialize(false); | 392 download_file->Initialize(false); |
| 406 download_manager_->StartDownload(info->download_id.local()); | 393 download_manager_->StartDownload(info->download_id.local()); |
| 407 message_loop_.RunAllPending(); | 394 message_loop_.RunAllPending(); |
| 408 | 395 |
| 409 // SelectFileObserver will have recorded any attempt to open the | 396 // SelectFileObserver will have recorded any attempt to open the |
| 410 // select file dialog. | 397 // select file dialog. |
| 411 // Note that DownloadManager::FileSelectionCanceled() is never called. | 398 // Note that DownloadManager::FileSelectionCanceled() is never called. |
| 412 EXPECT_EQ(kStartDownloadCases[i].expected_save_as, | 399 EXPECT_EQ(kStartDownloadCases[i].expected_save_as, |
| 413 observer.ShowedFileDialogForId(i)); | 400 observer.ShowedFileDialogForId(i)); |
| 414 } | 401 } |
| 415 } | 402 } |
| 416 | 403 |
| 417 TEST_F(DownloadManagerTest, DownloadRenameTest) { | 404 TEST_F(DownloadManagerTest, DownloadRenameTest) { |
| 418 using ::testing::_; | 405 using ::testing::_; |
| 419 using ::testing::CreateFunctor; | 406 using ::testing::CreateFunctor; |
| 420 using ::testing::Invoke; | 407 using ::testing::Invoke; |
| 421 using ::testing::Return; | 408 using ::testing::Return; |
| 422 | 409 |
| 423 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDownloadRenameCases); ++i) { | 410 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDownloadRenameCases); ++i) { |
| 424 // Normally, the download system takes ownership of info, and is | 411 // Normally, the download system takes ownership of info, and is |
| 425 // responsible for deleting it. In these unit tests, however, we | 412 // responsible for deleting it. In these unit tests, however, we |
| 426 // don't call the function that deletes it, so we do so ourselves. | 413 // don't call the function that deletes it, so we do so ourselves. |
| 427 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | 414 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); |
| 428 info->download_id = DownloadId(kValidIdDomain, static_cast<int>(i)); | 415 info->download_id = DownloadId(kValidIdDomain, static_cast<int>(i)); |
| 429 info->prompt_user_for_save_location = false; | 416 info->prompt_user_for_save_location = false; |
| 430 info->url_chain.push_back(GURL()); | 417 info->url_chain.push_back(GURL()); |
| 431 const FilePath new_path(kDownloadRenameCases[i].suggested_path); | 418 const FilePath new_path(kDownloadRenameCases[i].suggested_path); |
| 432 | 419 |
| 420 MockDownloadFile::StatisticsRecorder recorder; |
| 433 MockDownloadFile* download_file( | 421 MockDownloadFile* download_file( |
| 434 new MockDownloadFile(info.get(), download_manager_)); | 422 new MockDownloadFile(info.get(), |
| 423 DownloadRequestHandle(), |
| 424 download_manager_, |
| 425 &recorder)); |
| 435 AddDownloadToFileManager(info->download_id.local(), download_file); | 426 AddDownloadToFileManager(info->download_id.local(), download_file); |
| 436 | 427 |
| 437 // |download_file| is owned by DownloadFileManager. | 428 // |download_file| is owned by DownloadFileManager. |
| 438 ::testing::Mock::AllowLeak(download_file); | |
| 439 EXPECT_CALL(*download_file, Destructed()).Times(1); | |
| 440 | |
| 441 if (kDownloadRenameCases[i].expected_rename_count == 1) { | 429 if (kDownloadRenameCases[i].expected_rename_count == 1) { |
| 442 EXPECT_CALL(*download_file, Rename(new_path)).WillOnce(Return(net::OK)); | 430 download_file->SetExpectedPath(0, new_path); |
| 443 } else { | 431 } else { |
| 444 ASSERT_EQ(2, kDownloadRenameCases[i].expected_rename_count); | 432 ASSERT_EQ(2, kDownloadRenameCases[i].expected_rename_count); |
| 445 FilePath crdownload(download_util::GetCrDownloadPath(new_path)); | 433 FilePath crdownload(download_util::GetCrDownloadPath(new_path)); |
| 446 EXPECT_CALL(*download_file, Rename(_)) | 434 download_file->SetExpectedPath(0, crdownload); |
| 447 .WillOnce(testing::WithArgs<0>(Invoke(CreateFunctor( | 435 download_file->SetExpectedPath(1, new_path); |
| 448 download_file, &MockDownloadFile::TestMultipleRename, | |
| 449 1, crdownload)))) | |
| 450 .WillOnce(testing::WithArgs<0>(Invoke(CreateFunctor( | |
| 451 download_file, &MockDownloadFile::TestMultipleRename, | |
| 452 2, new_path)))); | |
| 453 } | 436 } |
| 454 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle()); | 437 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle()); |
| 455 DownloadItem* download = GetActiveDownloadItem(i); | 438 DownloadItem* download = GetActiveDownloadItem(i); |
| 456 ASSERT_TRUE(download != NULL); | 439 ASSERT_TRUE(download != NULL); |
| 457 if (kDownloadRenameCases[i].is_dangerous_file) | 440 if (kDownloadRenameCases[i].is_dangerous_file) |
| 458 download->MarkFileDangerous(); | 441 download->MarkFileDangerous(); |
| 459 if (kDownloadRenameCases[i].is_dangerous_url) | 442 if (kDownloadRenameCases[i].is_dangerous_url) |
| 460 download->MarkUrlDangerous(); | 443 download->MarkUrlDangerous(); |
| 461 | 444 |
| 462 int32* id_ptr = new int32; | 445 int32* id_ptr = new int32; |
| 463 *id_ptr = i; // Deleted in FileSelected(). | 446 *id_ptr = i; // Deleted in FileSelected(). |
| 464 if (kDownloadRenameCases[i].finish_before_rename) { | 447 if (kDownloadRenameCases[i].finish_before_rename) { |
| 465 OnResponseCompleted(i, 1024, std::string("fake_hash")); | 448 OnResponseCompleted(i, 1024, std::string("fake_hash")); |
| 466 message_loop_.RunAllPending(); | 449 message_loop_.RunAllPending(); |
| 467 FileSelected(new_path, id_ptr); | 450 FileSelected(new_path, id_ptr); |
| 468 } else { | 451 } else { |
| 469 FileSelected(new_path, id_ptr); | 452 FileSelected(new_path, id_ptr); |
| 470 message_loop_.RunAllPending(); | 453 message_loop_.RunAllPending(); |
| 471 OnResponseCompleted(i, 1024, std::string("fake_hash")); | 454 OnResponseCompleted(i, 1024, std::string("fake_hash")); |
| 472 } | 455 } |
| 473 | 456 |
| 474 message_loop_.RunAllPending(); | 457 message_loop_.RunAllPending(); |
| 458 EXPECT_EQ( |
| 459 kDownloadRenameCases[i].expected_rename_count, |
| 460 recorder.Count(MockDownloadFile::StatisticsRecorder::STAT_RENAME)); |
| 475 EXPECT_TRUE(VerifySafetyState(kDownloadRenameCases[i].is_dangerous_file, | 461 EXPECT_TRUE(VerifySafetyState(kDownloadRenameCases[i].is_dangerous_file, |
| 476 kDownloadRenameCases[i].is_dangerous_url, | 462 kDownloadRenameCases[i].is_dangerous_url, |
| 477 i)); | 463 i)); |
| 478 } | 464 } |
| 479 } | 465 } |
| 480 | 466 |
| 481 TEST_F(DownloadManagerTest, DownloadInterruptTest) { | 467 TEST_F(DownloadManagerTest, DownloadInterruptTest) { |
| 482 using ::testing::_; | 468 using ::testing::_; |
| 483 using ::testing::CreateFunctor; | 469 using ::testing::CreateFunctor; |
| 484 using ::testing::Invoke; | 470 using ::testing::Invoke; |
| 485 using ::testing::Return; | 471 using ::testing::Return; |
| 486 | 472 |
| 487 // Normally, the download system takes ownership of info, and is | 473 // Normally, the download system takes ownership of info, and is |
| 488 // responsible for deleting it. In these unit tests, however, we | 474 // responsible for deleting it. In these unit tests, however, we |
| 489 // don't call the function that deletes it, so we do so ourselves. | 475 // don't call the function that deletes it, so we do so ourselves. |
| 490 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | 476 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); |
| 491 info->download_id = DownloadId(kValidIdDomain, 0); | 477 info->download_id = DownloadId(kValidIdDomain, 0); |
| 492 info->prompt_user_for_save_location = false; | 478 info->prompt_user_for_save_location = false; |
| 493 info->url_chain.push_back(GURL()); | 479 info->url_chain.push_back(GURL()); |
| 494 info->total_bytes = static_cast<int64>(kTestDataLen); | 480 info->total_bytes = static_cast<int64>(kTestDataLen); |
| 495 const FilePath new_path(FILE_PATH_LITERAL("foo.zip")); | 481 const FilePath new_path(FILE_PATH_LITERAL("foo.zip")); |
| 496 const FilePath cr_path(download_util::GetCrDownloadPath(new_path)); | 482 const FilePath cr_path(download_util::GetCrDownloadPath(new_path)); |
| 497 | 483 |
| 484 MockDownloadFile::StatisticsRecorder recorder; |
| 498 MockDownloadFile* download_file( | 485 MockDownloadFile* download_file( |
| 499 new MockDownloadFile(info.get(), download_manager_)); | 486 new MockDownloadFile(info.get(), |
| 487 DownloadRequestHandle(), |
| 488 download_manager_, |
| 489 &recorder)); |
| 500 AddDownloadToFileManager(info->download_id.local(), download_file); | 490 AddDownloadToFileManager(info->download_id.local(), download_file); |
| 501 | 491 |
| 502 // |download_file| is owned by DownloadFileManager. | 492 // |download_file| is owned by DownloadFileManager. |
| 503 ::testing::Mock::AllowLeak(download_file); | 493 download_file->SetExpectedPath(0, cr_path); |
| 504 EXPECT_CALL(*download_file, Destructed()).Times(1); | |
| 505 | |
| 506 EXPECT_CALL(*download_file, Rename(cr_path)).WillOnce(Return(net::OK)); | |
| 507 | 494 |
| 508 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle()); | 495 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle()); |
| 509 | 496 |
| 510 DownloadItem* download = GetActiveDownloadItem(0); | 497 DownloadItem* download = GetActiveDownloadItem(0); |
| 511 ASSERT_TRUE(download != NULL); | 498 ASSERT_TRUE(download != NULL); |
| 512 scoped_ptr<DownloadItemModel> download_item_model( | 499 scoped_ptr<DownloadItemModel> download_item_model( |
| 513 new DownloadItemModel(download)); | 500 new DownloadItemModel(download)); |
| 514 | 501 |
| 515 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); | 502 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); |
| 516 scoped_ptr<ItemObserver> observer(new ItemObserver(download)); | 503 scoped_ptr<ItemObserver> observer(new ItemObserver(download)); |
| 517 | 504 |
| 518 download_file->AppendDataToFile(kTestData, kTestDataLen); | 505 download_file->AppendDataToFile(kTestData, kTestDataLen); |
| 519 | 506 |
| 520 ContinueDownloadWithPath(download, new_path); | 507 ContinueDownloadWithPath(download, new_path); |
| 521 message_loop_.RunAllPending(); | 508 message_loop_.RunAllPending(); |
| 509 EXPECT_EQ(1, |
| 510 recorder.Count(MockDownloadFile::StatisticsRecorder::STAT_RENAME)); |
| 522 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL); | 511 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL); |
| 523 | 512 |
| 524 int64 error_size = 3; | 513 int64 error_size = 3; |
| 525 OnDownloadInterrupted(0, error_size, | 514 OnDownloadInterrupted(0, error_size, |
| 526 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); | 515 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); |
| 527 message_loop_.RunAllPending(); | 516 message_loop_.RunAllPending(); |
| 528 | 517 |
| 529 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL); | 518 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL); |
| 530 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS)); | 519 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS)); |
| 531 EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED)); | 520 EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED)); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 562 } | 551 } |
| 563 | 552 |
| 564 // Test the behavior of DownloadFileManager and DownloadManager in the event | 553 // Test the behavior of DownloadFileManager and DownloadManager in the event |
| 565 // of a file error while writing the download to disk. | 554 // of a file error while writing the download to disk. |
| 566 TEST_F(DownloadManagerTest, DownloadFileErrorTest) { | 555 TEST_F(DownloadManagerTest, DownloadFileErrorTest) { |
| 567 // Create a temporary file and a mock stream. | 556 // Create a temporary file and a mock stream. |
| 568 FilePath path; | 557 FilePath path; |
| 569 ASSERT_TRUE(file_util::CreateTemporaryFile(&path)); | 558 ASSERT_TRUE(file_util::CreateTemporaryFile(&path)); |
| 570 | 559 |
| 571 // This file stream will be used, until the first rename occurs. | 560 // This file stream will be used, until the first rename occurs. |
| 572 net::testing::MockFileStream* mock_stream = new net::testing::MockFileStream; | 561 net::FileStream* stream = new net::FileStream; |
| 573 ASSERT_EQ(0, mock_stream->Open( | 562 ASSERT_EQ(0, stream->Open( |
| 574 path, | 563 path, |
| 575 base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE)); | 564 base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE)); |
| 576 | 565 |
| 577 // Normally, the download system takes ownership of info, and is | 566 // Normally, the download system takes ownership of info, and is |
| 578 // responsible for deleting it. In these unit tests, however, we | 567 // responsible for deleting it. In these unit tests, however, we |
| 579 // don't call the function that deletes it, so we do so ourselves. | 568 // don't call the function that deletes it, so we do so ourselves. |
| 580 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | 569 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); |
| 581 static const int32 local_id = 0; | 570 static const int32 local_id = 0; |
| 582 info->download_id = DownloadId(kValidIdDomain, local_id); | 571 info->download_id = DownloadId(kValidIdDomain, local_id); |
| 583 info->prompt_user_for_save_location = false; | 572 info->prompt_user_for_save_location = false; |
| 584 info->url_chain.push_back(GURL()); | 573 info->url_chain.push_back(GURL()); |
| 585 info->total_bytes = static_cast<int64>(kTestDataLen * 3); | 574 info->total_bytes = static_cast<int64>(kTestDataLen * 3); |
| 586 info->save_info.file_path = path; | 575 info->save_info.file_path = path; |
| 576 info->save_info.file_stream.reset(stream); |
| 587 | 577 |
| 588 // Create a download file that we can insert errors into. | 578 // Create a download file that we can insert errors into. |
| 589 DownloadFileWithMockStream* download_file(new DownloadFileWithMockStream( | 579 DownloadFileWithErrors* download_file(new DownloadFileWithErrors( |
| 590 info.get(), download_manager_, mock_stream)); | 580 info.get(), download_manager_)); |
| 591 AddDownloadToFileManager(local_id, download_file); | 581 AddDownloadToFileManager(local_id, download_file); |
| 592 | 582 |
| 593 // |download_file| is owned by DownloadFileManager. | 583 // |download_file| is owned by DownloadFileManager. |
| 594 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle()); | 584 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle()); |
| 595 | 585 |
| 596 DownloadItem* download = GetActiveDownloadItem(0); | 586 DownloadItem* download = GetActiveDownloadItem(0); |
| 597 ASSERT_TRUE(download != NULL); | 587 ASSERT_TRUE(download != NULL); |
| 598 // This will keep track of what should be displayed on the shelf. | 588 // This will keep track of what should be displayed on the shelf. |
| 599 scoped_ptr<DownloadItemModel> download_item_model( | 589 scoped_ptr<DownloadItemModel> download_item_model( |
| 600 new DownloadItemModel(download)); | 590 new DownloadItemModel(download)); |
| 601 | 591 |
| 602 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); | 592 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); |
| 603 scoped_ptr<ItemObserver> observer(new ItemObserver(download)); | 593 scoped_ptr<ItemObserver> observer(new ItemObserver(download)); |
| 604 | 594 |
| 605 // Add some data before finalizing the file name. | 595 // Add some data before finalizing the file name. |
| 606 UpdateData(local_id, kTestData, kTestDataLen); | 596 UpdateData(local_id, kTestData, kTestDataLen); |
| 607 | 597 |
| 608 // Finalize the file name. | 598 // Finalize the file name. |
| 609 ContinueDownloadWithPath(download, path); | 599 ContinueDownloadWithPath(download, path); |
| 610 message_loop_.RunAllPending(); | 600 message_loop_.RunAllPending(); |
| 611 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL); | 601 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL); |
| 612 | 602 |
| 613 // Add more data. | 603 // Add more data. |
| 614 UpdateData(local_id, kTestData, kTestDataLen); | 604 UpdateData(local_id, kTestData, kTestDataLen); |
| 615 | 605 |
| 616 // Add more data, but an error occurs. | 606 // Add more data, but an error occurs. |
| 617 download_file->SetForcedError(net::ERR_FAILED); | 607 download_file->set_forced_error(net::ERR_FAILED); |
| 618 UpdateData(local_id, kTestData, kTestDataLen); | 608 UpdateData(local_id, kTestData, kTestDataLen); |
| 619 | 609 |
| 620 // Check the state. The download should have been interrupted. | 610 // Check the state. The download should have been interrupted. |
| 621 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL); | 611 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL); |
| 622 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS)); | 612 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS)); |
| 623 EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED)); | 613 EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED)); |
| 624 EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE)); | 614 EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE)); |
| 625 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED)); | 615 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED)); |
| 626 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING)); | 616 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING)); |
| 627 EXPECT_TRUE(observer->was_updated()); | 617 EXPECT_TRUE(observer->was_updated()); |
| 628 EXPECT_FALSE(observer->was_opened()); | 618 EXPECT_FALSE(observer->was_opened()); |
| 629 EXPECT_FALSE(download->file_externally_removed()); | 619 EXPECT_FALSE(download->file_externally_removed()); |
| 630 EXPECT_EQ(DownloadItem::INTERRUPTED, download->state()); | 620 EXPECT_EQ(DownloadItem::INTERRUPTED, download->state()); |
| 631 | 621 |
| 632 // Check the download shelf's information. | 622 // Check the download shelf's information. |
| 633 size_t error_size = kTestDataLen * 2; | 623 size_t error_size = kTestDataLen * 3; |
| 634 size_t total_size = kTestDataLen * 3; | 624 size_t total_size = kTestDataLen * 3; |
| 635 ui::DataUnits amount_units = ui::GetByteDisplayUnits(kTestDataLen); | 625 ui::DataUnits amount_units = ui::GetByteDisplayUnits(kTestDataLen); |
| 636 string16 simple_size = | 626 string16 simple_size = |
| 637 ui::FormatBytesWithUnits(error_size, amount_units, false); | 627 ui::FormatBytesWithUnits(error_size, amount_units, false); |
| 638 string16 simple_total = base::i18n::GetDisplayStringInLTRDirectionality( | 628 string16 simple_total = base::i18n::GetDisplayStringInLTRDirectionality( |
| 639 ui::FormatBytesWithUnits(total_size, amount_units, true)); | 629 ui::FormatBytesWithUnits(total_size, amount_units, true)); |
| 640 EXPECT_EQ(l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_INTERRUPTED, | 630 EXPECT_EQ(l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_INTERRUPTED, |
| 641 simple_size, | 631 simple_size, |
| 642 simple_total), | 632 simple_total), |
| 643 download_item_model->GetStatusText()); | 633 download_item_model->GetStatusText()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 657 // responsible for deleting it. In these unit tests, however, we | 647 // responsible for deleting it. In these unit tests, however, we |
| 658 // don't call the function that deletes it, so we do so ourselves. | 648 // don't call the function that deletes it, so we do so ourselves. |
| 659 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); | 649 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo); |
| 660 info->download_id = DownloadId(kValidIdDomain, 0); | 650 info->download_id = DownloadId(kValidIdDomain, 0); |
| 661 info->prompt_user_for_save_location = false; | 651 info->prompt_user_for_save_location = false; |
| 662 info->url_chain.push_back(GURL()); | 652 info->url_chain.push_back(GURL()); |
| 663 const FilePath new_path(FILE_PATH_LITERAL("foo.zip")); | 653 const FilePath new_path(FILE_PATH_LITERAL("foo.zip")); |
| 664 const FilePath cr_path(download_util::GetCrDownloadPath(new_path)); | 654 const FilePath cr_path(download_util::GetCrDownloadPath(new_path)); |
| 665 | 655 |
| 666 MockDownloadFile* download_file( | 656 MockDownloadFile* download_file( |
| 667 new MockDownloadFile(info.get(), download_manager_)); | 657 new MockDownloadFile(info.get(), |
| 658 DownloadRequestHandle(), |
| 659 download_manager_, |
| 660 NULL)); |
| 668 AddDownloadToFileManager(info->download_id.local(), download_file); | 661 AddDownloadToFileManager(info->download_id.local(), download_file); |
| 669 | 662 |
| 670 // |download_file| is owned by DownloadFileManager. | 663 // |download_file| is owned by DownloadFileManager. |
| 671 ::testing::Mock::AllowLeak(download_file); | 664 download_file->SetExpectedPath(0, cr_path); |
| 672 EXPECT_CALL(*download_file, Destructed()).Times(1); | |
| 673 | |
| 674 EXPECT_CALL(*download_file, Rename(cr_path)).WillOnce(Return(net::OK)); | |
| 675 | 665 |
| 676 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle()); | 666 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle()); |
| 677 | 667 |
| 678 DownloadItem* download = GetActiveDownloadItem(0); | 668 DownloadItem* download = GetActiveDownloadItem(0); |
| 679 ASSERT_TRUE(download != NULL); | 669 ASSERT_TRUE(download != NULL); |
| 680 scoped_ptr<DownloadItemModel> download_item_model( | 670 scoped_ptr<DownloadItemModel> download_item_model( |
| 681 new DownloadItemModel(download)); | 671 new DownloadItemModel(download)); |
| 682 | 672 |
| 683 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); | 673 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); |
| 684 scoped_ptr<ItemObserver> observer(new ItemObserver(download)); | 674 scoped_ptr<ItemObserver> observer(new ItemObserver(download)); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 new DownloadItemModel(download)); | 743 new DownloadItemModel(download)); |
| 754 | 744 |
| 755 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); | 745 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); |
| 756 scoped_ptr<ItemObserver> observer(new ItemObserver(download)); | 746 scoped_ptr<ItemObserver> observer(new ItemObserver(download)); |
| 757 | 747 |
| 758 // Create and initialize the download file. We're bypassing the first part | 748 // Create and initialize the download file. We're bypassing the first part |
| 759 // of the download process and skipping to the part after the final file | 749 // of the download process and skipping to the part after the final file |
| 760 // name has been chosen, so we need to initialize the download file | 750 // name has been chosen, so we need to initialize the download file |
| 761 // properly. | 751 // properly. |
| 762 DownloadFile* download_file( | 752 DownloadFile* download_file( |
| 763 new DownloadFile(info.get(), new DownloadRequestHandle(), | 753 new DownloadFileImpl(info.get(), new DownloadRequestHandle(), |
| 764 download_manager_)); | 754 download_manager_)); |
| 765 download_file->Rename(cr_path); | 755 download_file->Rename(cr_path); |
| 766 // This creates the .crdownload version of the file. | 756 // This creates the .crdownload version of the file. |
| 767 download_file->Initialize(false); | 757 download_file->Initialize(false); |
| 768 // |download_file| is owned by DownloadFileManager. | 758 // |download_file| is owned by DownloadFileManager. |
| 769 AddDownloadToFileManager(info->download_id.local(), download_file); | 759 AddDownloadToFileManager(info->download_id.local(), download_file); |
| 770 | 760 |
| 771 ContinueDownloadWithPath(download, new_path); | 761 ContinueDownloadWithPath(download, new_path); |
| 772 message_loop_.RunAllPending(); | 762 message_loop_.RunAllPending(); |
| 773 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL); | 763 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL); |
| 774 | 764 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 new DownloadItemModel(download)); | 820 new DownloadItemModel(download)); |
| 831 | 821 |
| 832 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); | 822 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state()); |
| 833 scoped_ptr<ItemObserver> observer(new ItemObserver(download)); | 823 scoped_ptr<ItemObserver> observer(new ItemObserver(download)); |
| 834 | 824 |
| 835 // Create and initialize the download file. We're bypassing the first part | 825 // Create and initialize the download file. We're bypassing the first part |
| 836 // of the download process and skipping to the part after the final file | 826 // of the download process and skipping to the part after the final file |
| 837 // name has been chosen, so we need to initialize the download file | 827 // name has been chosen, so we need to initialize the download file |
| 838 // properly. | 828 // properly. |
| 839 DownloadFile* download_file( | 829 DownloadFile* download_file( |
| 840 new DownloadFile(info.get(), new DownloadRequestHandle(), | 830 new DownloadFileImpl(info.get(), new DownloadRequestHandle(), |
| 841 download_manager_)); | 831 download_manager_)); |
| 842 download_file->Rename(cr_path); | 832 download_file->Rename(cr_path); |
| 843 // This creates the .crdownload version of the file. | 833 // This creates the .crdownload version of the file. |
| 844 download_file->Initialize(false); | 834 download_file->Initialize(false); |
| 845 // |download_file| is owned by DownloadFileManager. | 835 // |download_file| is owned by DownloadFileManager. |
| 846 AddDownloadToFileManager(info->download_id.local(), download_file); | 836 AddDownloadToFileManager(info->download_id.local(), download_file); |
| 847 | 837 |
| 848 ContinueDownloadWithPath(download, new_path); | 838 ContinueDownloadWithPath(download, new_path); |
| 849 message_loop_.RunAllPending(); | 839 message_loop_.RunAllPending(); |
| 850 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL); | 840 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL); |
| 851 | 841 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING)); | 874 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING)); |
| 885 EXPECT_TRUE(observer->was_updated()); | 875 EXPECT_TRUE(observer->was_updated()); |
| 886 EXPECT_FALSE(observer->was_opened()); | 876 EXPECT_FALSE(observer->was_opened()); |
| 887 EXPECT_TRUE(download->file_externally_removed()); | 877 EXPECT_TRUE(download->file_externally_removed()); |
| 888 EXPECT_EQ(DownloadItem::COMPLETE, download->state()); | 878 EXPECT_EQ(DownloadItem::COMPLETE, download->state()); |
| 889 EXPECT_EQ(download_item_model->GetStatusText(), | 879 EXPECT_EQ(download_item_model->GetStatusText(), |
| 890 l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_REMOVED)); | 880 l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_REMOVED)); |
| 891 | 881 |
| 892 EXPECT_FALSE(file_util::PathExists(new_path)); | 882 EXPECT_FALSE(file_util::PathExists(new_path)); |
| 893 } | 883 } |
| OLD | NEW |