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/base_file.h" | 5 #include "content/browser/download/base_file.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/logging.h" | 8 #include "base/logging.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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 | 50 |
51 virtual void SetUp() { | 51 virtual void SetUp() { |
52 ResetHash(); | 52 ResetHash(); |
53 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 53 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
54 base_file_.reset(new BaseFile(FilePath(), | 54 base_file_.reset(new BaseFile(FilePath(), |
55 GURL(), | 55 GURL(), |
56 GURL(), | 56 GURL(), |
57 0, | 57 0, |
58 false, | 58 false, |
59 "", | 59 "", |
60 file_stream_, | 60 scoped_ptr<net::FileStream>(), |
61 net::BoundNetLog())); | 61 net::BoundNetLog())); |
62 } | 62 } |
63 | 63 |
64 virtual void TearDown() { | 64 virtual void TearDown() { |
65 EXPECT_FALSE(base_file_->in_progress()); | 65 EXPECT_FALSE(base_file_->in_progress()); |
66 if (!expected_error_) { | 66 if (!expected_error_) { |
67 EXPECT_EQ(static_cast<int64>(expected_data_.size()), | 67 EXPECT_EQ(static_cast<int64>(expected_data_.size()), |
68 base_file_->bytes_so_far()); | 68 base_file_->bytes_so_far()); |
69 } | 69 } |
70 | 70 |
(...skipping 30 matching lines...) Expand all Loading... |
101 return hash; | 101 return hash; |
102 } | 102 } |
103 | 103 |
104 void MakeFileWithHash() { | 104 void MakeFileWithHash() { |
105 base_file_.reset(new BaseFile(FilePath(), | 105 base_file_.reset(new BaseFile(FilePath(), |
106 GURL(), | 106 GURL(), |
107 GURL(), | 107 GURL(), |
108 0, | 108 0, |
109 true, | 109 true, |
110 "", | 110 "", |
111 file_stream_, | 111 scoped_ptr<net::FileStream>(), |
112 net::BoundNetLog())); | 112 net::BoundNetLog())); |
113 } | 113 } |
114 | 114 |
115 bool OpenMockFileStream() { | |
116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
117 | |
118 FilePath path; | |
119 if (!file_util::CreateTemporaryFile(&path)) | |
120 return false; | |
121 | |
122 // Create a new file stream. | |
123 mock_file_stream_.reset(new net::testing::MockFileStream(NULL)); | |
124 if (mock_file_stream_->OpenSync( | |
125 path, | |
126 base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE) != 0) { | |
127 mock_file_stream_.reset(); | |
128 return false; | |
129 } | |
130 | |
131 return true; | |
132 } | |
133 | |
134 void ForceError(net::Error error) { | |
135 mock_file_stream_->set_forced_error(error); | |
136 } | |
137 | |
138 int AppendDataToFile(const std::string& data) { | 115 int AppendDataToFile(const std::string& data) { |
139 EXPECT_EQ(expect_in_progress_, base_file_->in_progress()); | 116 EXPECT_EQ(expect_in_progress_, base_file_->in_progress()); |
140 expected_error_ = mock_file_stream_.get() && | |
141 (mock_file_stream_->forced_error() != net::OK); | |
142 int appended = base_file_->AppendDataToFile(data.data(), data.size()); | 117 int appended = base_file_->AppendDataToFile(data.data(), data.size()); |
143 if (appended == net::OK) | 118 if (appended == net::OK) |
144 EXPECT_TRUE(expect_in_progress_) | 119 EXPECT_TRUE(expect_in_progress_) |
145 << " appended = " << appended; | 120 << " appended = " << appended; |
146 if (base_file_->in_progress()) { | 121 if (base_file_->in_progress()) { |
147 expected_data_ += data; | 122 expected_data_ += data; |
148 if (!expected_error_) { | 123 if (!expected_error_) { |
149 EXPECT_EQ(static_cast<int64>(expected_data_.size()), | 124 EXPECT_EQ(static_cast<int64>(expected_data_.size()), |
150 base_file_->bytes_so_far()); | 125 base_file_->bytes_so_far()); |
151 } | 126 } |
152 } | 127 } |
153 return appended; | 128 return appended; |
154 } | 129 } |
155 | 130 |
156 void set_expected_data(const std::string& data) { expected_data_ = data; } | 131 void set_expected_data(const std::string& data) { expected_data_ = data; } |
157 | 132 |
158 // Helper functions. | 133 // Helper functions. |
159 // Create a file. Returns the complete file path. | 134 // Create a file. Returns the complete file path. |
160 FilePath CreateTestFile() { | 135 FilePath CreateTestFile() { |
161 FilePath file_name; | 136 FilePath file_name; |
162 linked_ptr<net::FileStream> dummy_file_stream; | |
163 BaseFile file(FilePath(), | 137 BaseFile file(FilePath(), |
164 GURL(), | 138 GURL(), |
165 GURL(), | 139 GURL(), |
166 0, | 140 0, |
167 false, | 141 false, |
168 "", | 142 "", |
169 dummy_file_stream, | 143 scoped_ptr<net::FileStream>(), |
170 net::BoundNetLog()); | 144 net::BoundNetLog()); |
171 | 145 |
172 EXPECT_EQ(net::OK, file.Initialize(temp_dir_.path())); | 146 EXPECT_EQ(net::OK, file.Initialize(temp_dir_.path())); |
173 file_name = file.full_path(); | 147 file_name = file.full_path(); |
174 EXPECT_NE(FilePath::StringType(), file_name.value()); | 148 EXPECT_NE(FilePath::StringType(), file_name.value()); |
175 | 149 |
176 EXPECT_EQ(net::OK, file.AppendDataToFile(kTestData4, kTestDataLength4)); | 150 EXPECT_EQ(net::OK, file.AppendDataToFile(kTestData4, kTestDataLength4)); |
177 | 151 |
178 // Keep the file from getting deleted when existing_file_name is deleted. | 152 // Keep the file from getting deleted when existing_file_name is deleted. |
179 file.Detach(); | 153 file.Detach(); |
180 | 154 |
181 return file_name; | 155 return file_name; |
182 } | 156 } |
183 | 157 |
184 // Create a file with the specified file name. | 158 // Create a file with the specified file name. |
185 void CreateFileWithName(const FilePath& file_name) { | 159 void CreateFileWithName(const FilePath& file_name) { |
186 EXPECT_NE(FilePath::StringType(), file_name.value()); | 160 EXPECT_NE(FilePath::StringType(), file_name.value()); |
187 linked_ptr<net::FileStream> dummy_file_stream; | |
188 BaseFile duplicate_file(file_name, | 161 BaseFile duplicate_file(file_name, |
189 GURL(), | 162 GURL(), |
190 GURL(), | 163 GURL(), |
191 0, | 164 0, |
192 false, | 165 false, |
193 "", | 166 "", |
194 dummy_file_stream, | 167 scoped_ptr<net::FileStream>(), |
195 net::BoundNetLog()); | 168 net::BoundNetLog()); |
196 EXPECT_EQ(net::OK, duplicate_file.Initialize(temp_dir_.path())); | 169 EXPECT_EQ(net::OK, duplicate_file.Initialize(temp_dir_.path())); |
197 // Write something into it. | 170 // Write something into it. |
198 duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4); | 171 duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4); |
199 // Detach the file so it isn't deleted on destruction of |duplicate_file|. | 172 // Detach the file so it isn't deleted on destruction of |duplicate_file|. |
200 duplicate_file.Detach(); | 173 duplicate_file.Detach(); |
201 } | 174 } |
202 | 175 |
203 int64 CurrentSpeedAtTime(base::TimeTicks current_time) { | 176 int64 CurrentSpeedAtTime(base::TimeTicks current_time) { |
204 EXPECT_TRUE(base_file_.get()); | 177 EXPECT_TRUE(base_file_.get()); |
205 return base_file_->CurrentSpeedAtTime(current_time); | 178 return base_file_->CurrentSpeedAtTime(current_time); |
206 } | 179 } |
207 | 180 |
208 base::TimeTicks StartTick() { | 181 base::TimeTicks StartTick() { |
209 EXPECT_TRUE(base_file_.get()); | 182 EXPECT_TRUE(base_file_.get()); |
210 return base_file_->start_tick_; | 183 return base_file_->start_tick_; |
211 } | 184 } |
212 | 185 |
| 186 void set_expected_error(net::Error err) { |
| 187 expected_error_ = err; |
| 188 } |
| 189 |
213 protected: | 190 protected: |
214 linked_ptr<net::FileStream> file_stream_; | |
215 linked_ptr<net::testing::MockFileStream> mock_file_stream_; | 191 linked_ptr<net::testing::MockFileStream> mock_file_stream_; |
216 | 192 |
217 // BaseClass instance we are testing. | 193 // BaseClass instance we are testing. |
218 scoped_ptr<BaseFile> base_file_; | 194 scoped_ptr<BaseFile> base_file_; |
219 | 195 |
220 // Temporary directory for renamed downloads. | 196 // Temporary directory for renamed downloads. |
221 ScopedTempDir temp_dir_; | 197 ScopedTempDir temp_dir_; |
222 | 198 |
223 // Expect the file to survive deletion of the BaseFile instance. | 199 // Expect the file to survive deletion of the BaseFile instance. |
224 bool expect_file_survives_; | 200 bool expect_file_survives_; |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 // Write some data | 374 // Write some data |
399 ASSERT_EQ(net::OK, AppendDataToFile(kTestData1)); | 375 ASSERT_EQ(net::OK, AppendDataToFile(kTestData1)); |
400 ASSERT_EQ(net::OK, AppendDataToFile(kTestData2)); | 376 ASSERT_EQ(net::OK, AppendDataToFile(kTestData2)); |
401 // Get the hash state and file name. | 377 // Get the hash state and file name. |
402 std::string hash_state; | 378 std::string hash_state; |
403 hash_state = base_file_->GetHashState(); | 379 hash_state = base_file_->GetHashState(); |
404 // Finish the file. | 380 // Finish the file. |
405 base_file_->Finish(); | 381 base_file_->Finish(); |
406 | 382 |
407 // Create another file | 383 // Create another file |
408 linked_ptr<net::FileStream> second_stream; | |
409 BaseFile second_file(FilePath(), | 384 BaseFile second_file(FilePath(), |
410 GURL(), | 385 GURL(), |
411 GURL(), | 386 GURL(), |
412 base_file_->bytes_so_far(), | 387 base_file_->bytes_so_far(), |
413 true, | 388 true, |
414 hash_state, | 389 hash_state, |
415 second_stream, | 390 scoped_ptr<net::FileStream>(), |
416 net::BoundNetLog()); | 391 net::BoundNetLog()); |
417 ASSERT_EQ(net::OK, second_file.Initialize(temp_dir_.path())); | 392 ASSERT_EQ(net::OK, second_file.Initialize(temp_dir_.path())); |
418 std::string data(kTestData3); | 393 std::string data(kTestData3); |
419 EXPECT_EQ(net::OK, second_file.AppendDataToFile(data.data(), data.size())); | 394 EXPECT_EQ(net::OK, second_file.AppendDataToFile(data.data(), data.size())); |
420 second_file.Finish(); | 395 second_file.Finish(); |
421 | 396 |
422 std::string hash; | 397 std::string hash; |
423 EXPECT_TRUE(second_file.GetHash(&hash)); | 398 EXPECT_TRUE(second_file.GetHash(&hash)); |
424 // This will fail until getting the hash state is supported in SecureHash. | 399 // This will fail until getting the hash state is supported in SecureHash. |
425 EXPECT_STREQ(expected_hash_hex.c_str(), | 400 EXPECT_STREQ(expected_hash_hex.c_str(), |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 file_util::PermissionRestorer restore_permissions_for(test_dir); | 456 file_util::PermissionRestorer restore_permissions_for(test_dir); |
482 ASSERT_TRUE(file_util::MakeFileUnwritable(test_dir)); | 457 ASSERT_TRUE(file_util::MakeFileUnwritable(test_dir)); |
483 EXPECT_EQ(net::ERR_ACCESS_DENIED, base_file_->Rename(new_path)); | 458 EXPECT_EQ(net::ERR_ACCESS_DENIED, base_file_->Rename(new_path)); |
484 } | 459 } |
485 | 460 |
486 base_file_->Finish(); | 461 base_file_->Finish(); |
487 } | 462 } |
488 | 463 |
489 // Write data to the file multiple times. | 464 // Write data to the file multiple times. |
490 TEST_F(BaseFileTest, MultipleWritesWithError) { | 465 TEST_F(BaseFileTest, MultipleWritesWithError) { |
491 ASSERT_TRUE(OpenMockFileStream()); | 466 FilePath path; |
492 base_file_.reset(new BaseFile(mock_file_stream_->get_path(), | 467 ASSERT_TRUE(file_util::CreateTemporaryFile(&path)); |
| 468 // Create a new file stream. scoped_ptr takes ownership and passes it to |
| 469 // BaseFile; we use the pointer anyway and rely on the BaseFile not |
| 470 // deleting the MockFileStream until the BaseFile is reset. |
| 471 net::testing::MockFileStream* mock_file_stream( |
| 472 new net::testing::MockFileStream(NULL)); |
| 473 scoped_ptr<net::FileStream> mock_file_stream_scoped_ptr(mock_file_stream); |
| 474 |
| 475 ASSERT_EQ(0, |
| 476 mock_file_stream->OpenSync( |
| 477 path, |
| 478 base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE)); |
| 479 |
| 480 // Copy of mock_file_stream; we pass ownership and rely on the BaseFile |
| 481 // not deleting it until it is reset. |
| 482 |
| 483 base_file_.reset(new BaseFile(mock_file_stream->get_path(), |
493 GURL(), | 484 GURL(), |
494 GURL(), | 485 GURL(), |
495 0, | 486 0, |
496 false, | 487 false, |
497 "", | 488 "", |
498 mock_file_stream_, | 489 mock_file_stream_scoped_ptr.Pass(), |
499 net::BoundNetLog())); | 490 net::BoundNetLog())); |
500 EXPECT_EQ(net::OK, base_file_->Initialize(temp_dir_.path())); | 491 EXPECT_EQ(net::OK, base_file_->Initialize(temp_dir_.path())); |
501 ASSERT_EQ(net::OK, AppendDataToFile(kTestData1)); | 492 ASSERT_EQ(net::OK, AppendDataToFile(kTestData1)); |
502 ASSERT_EQ(net::OK, AppendDataToFile(kTestData2)); | 493 ASSERT_EQ(net::OK, AppendDataToFile(kTestData2)); |
503 ForceError(net::ERR_ACCESS_DENIED); | 494 mock_file_stream->set_forced_error(net::ERR_ACCESS_DENIED); |
| 495 set_expected_error(net::ERR_ACCESS_DENIED); |
504 ASSERT_NE(net::OK, AppendDataToFile(kTestData3)); | 496 ASSERT_NE(net::OK, AppendDataToFile(kTestData3)); |
505 std::string hash; | 497 std::string hash; |
506 EXPECT_FALSE(base_file_->GetHash(&hash)); | 498 EXPECT_FALSE(base_file_->GetHash(&hash)); |
507 base_file_->Finish(); | 499 base_file_->Finish(); |
508 } | 500 } |
509 | 501 |
510 // Try to write to uninitialized file. | 502 // Try to write to uninitialized file. |
511 TEST_F(BaseFileTest, UninitializedFile) { | 503 TEST_F(BaseFileTest, UninitializedFile) { |
512 expect_in_progress_ = false; | 504 expect_in_progress_ = false; |
513 EXPECT_EQ(net::ERR_INVALID_HANDLE, AppendDataToFile(kTestData1)); | 505 EXPECT_EQ(net::ERR_INVALID_HANDLE, AppendDataToFile(kTestData1)); |
(...skipping 19 matching lines...) Expand all Loading... |
533 | 525 |
534 set_expected_data(kTestData4); | 526 set_expected_data(kTestData4); |
535 | 527 |
536 // Use the file we've just created. | 528 // Use the file we've just created. |
537 base_file_.reset(new BaseFile(existing_file_name, | 529 base_file_.reset(new BaseFile(existing_file_name, |
538 GURL(), | 530 GURL(), |
539 GURL(), | 531 GURL(), |
540 kTestDataLength4, | 532 kTestDataLength4, |
541 false, | 533 false, |
542 "", | 534 "", |
543 file_stream_, | 535 scoped_ptr<net::FileStream>(), |
544 net::BoundNetLog())); | 536 net::BoundNetLog())); |
545 | 537 |
546 EXPECT_EQ(net::OK, base_file_->Initialize(temp_dir_.path())); | 538 EXPECT_EQ(net::OK, base_file_->Initialize(temp_dir_.path())); |
547 | 539 |
548 const FilePath file_name = base_file_->full_path(); | 540 const FilePath file_name = base_file_->full_path(); |
549 EXPECT_NE(FilePath::StringType(), file_name.value()); | 541 EXPECT_NE(FilePath::StringType(), file_name.value()); |
550 | 542 |
551 // Write into the file. | 543 // Write into the file. |
552 EXPECT_EQ(net::OK, AppendDataToFile(kTestData1)); | 544 EXPECT_EQ(net::OK, AppendDataToFile(kTestData1)); |
553 | 545 |
(...skipping 13 matching lines...) Expand all Loading... |
567 // Make it read-only. | 559 // Make it read-only. |
568 EXPECT_TRUE(file_util::MakeFileUnwritable(readonly_file_name)); | 560 EXPECT_TRUE(file_util::MakeFileUnwritable(readonly_file_name)); |
569 | 561 |
570 // Try to overwrite it. | 562 // Try to overwrite it. |
571 base_file_.reset(new BaseFile(readonly_file_name, | 563 base_file_.reset(new BaseFile(readonly_file_name, |
572 GURL(), | 564 GURL(), |
573 GURL(), | 565 GURL(), |
574 0, | 566 0, |
575 false, | 567 false, |
576 "", | 568 "", |
577 file_stream_, | 569 scoped_ptr<net::FileStream>(), |
578 net::BoundNetLog())); | 570 net::BoundNetLog())); |
579 | 571 |
580 expect_in_progress_ = false; | 572 expect_in_progress_ = false; |
581 | 573 |
582 int init_error = base_file_->Initialize(temp_dir_.path()); | 574 int init_error = base_file_->Initialize(temp_dir_.path()); |
583 DVLOG(1) << " init_error = " << init_error; | 575 DVLOG(1) << " init_error = " << init_error; |
584 EXPECT_NE(net::OK, init_error); | 576 EXPECT_NE(net::OK, init_error); |
585 | 577 |
586 const FilePath file_name = base_file_->full_path(); | 578 const FilePath file_name = base_file_->full_path(); |
587 EXPECT_NE(FilePath::StringType(), file_name.value()); | 579 EXPECT_NE(FilePath::StringType(), file_name.value()); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 // be a string-wise match to base_file_->full_path().DirName() even though | 645 // be a string-wise match to base_file_->full_path().DirName() even though |
654 // they are in the same directory. | 646 // they are in the same directory. |
655 FilePath temp_file; | 647 FilePath temp_file; |
656 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(), | 648 ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(), |
657 &temp_file)); | 649 &temp_file)); |
658 ASSERT_FALSE(temp_file.empty()); | 650 ASSERT_FALSE(temp_file.empty()); |
659 EXPECT_STREQ(temp_file.DirName().value().c_str(), | 651 EXPECT_STREQ(temp_file.DirName().value().c_str(), |
660 base_file_->full_path().DirName().value().c_str()); | 652 base_file_->full_path().DirName().value().c_str()); |
661 base_file_->Finish(); | 653 base_file_->Finish(); |
662 } | 654 } |
OLD | NEW |