Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Side by Side Diff: content/browser/download/base_file_unittest.cc

Issue 2695153002: Refactor BaseFile class to support sparse files (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 59
60 void SetUp() override { 60 void SetUp() override {
61 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 61 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
62 base_file_.reset(new BaseFile(net::NetLogWithSource())); 62 base_file_.reset(new BaseFile(net::NetLogWithSource()));
63 } 63 }
64 64
65 void TearDown() override { 65 void TearDown() override {
66 EXPECT_FALSE(base_file_->in_progress()); 66 EXPECT_FALSE(base_file_->in_progress());
67 if (!expected_error_) { 67 if (!expected_error_) {
68 EXPECT_EQ(static_cast<int64_t>(expected_data_.size()), 68 EXPECT_EQ(static_cast<int64_t>(expected_data_.size()),
69 base_file_->bytes_so_far()); 69 base_file_->offset());
70 } 70 }
71 71
72 base::FilePath full_path = base_file_->full_path(); 72 base::FilePath full_path = base_file_->full_path();
73 73
74 if (!expected_data_.empty() && !expected_error_) { 74 if (!expected_data_.empty() && !expected_error_) {
75 // Make sure the data has been properly written to disk. 75 // Make sure the data has been properly written to disk.
76 std::string disk_data; 76 std::string disk_data;
77 EXPECT_TRUE(base::ReadFileToString(full_path, &disk_data)); 77 EXPECT_TRUE(base::ReadFileToString(full_path, &disk_data));
78 EXPECT_EQ(expected_data_, disk_data); 78 EXPECT_EQ(expected_data_, disk_data);
79 } 79 }
80 80
81 // Make sure the mock BrowserThread outlives the BaseFile to satisfy 81 // Make sure the mock BrowserThread outlives the BaseFile to satisfy
82 // thread checks inside it. 82 // thread checks inside it.
83 base_file_.reset(); 83 base_file_.reset();
84 84
85 EXPECT_EQ(expect_file_survives_, base::PathExists(full_path)); 85 EXPECT_EQ(expect_file_survives_, base::PathExists(full_path));
86 } 86 }
87 87
88 bool InitializeFile() { 88 bool InitializeFile() {
89 DownloadInterruptReason result = base_file_->Initialize( 89 DownloadInterruptReason result = base_file_->Initialize(
90 base::FilePath(), temp_dir_.GetPath(), base::File(), 0, std::string(), 90 base::FilePath(), temp_dir_.GetPath(), base::File(), 0, std::string(),
91 std::unique_ptr<crypto::SecureHash>()); 91 std::unique_ptr<crypto::SecureHash>(), BaseFile::EXCLUSIVE);
92 EXPECT_EQ(expected_error_, result); 92 EXPECT_EQ(expected_error_, result);
93 return result == DOWNLOAD_INTERRUPT_REASON_NONE; 93 return result == DOWNLOAD_INTERRUPT_REASON_NONE;
94 } 94 }
95 95
96 bool AppendDataToFile(const std::string& data) { 96 bool WriteDataToFile(const std::string& data) {
97 EXPECT_EQ(expect_in_progress_, base_file_->in_progress()); 97 EXPECT_EQ(expect_in_progress_, base_file_->in_progress());
98 DownloadInterruptReason result = 98 DownloadInterruptReason result =
99 base_file_->AppendDataToFile(data.data(), data.size()); 99 base_file_->WriteDataToFile(data.data(), data.size());
100 if (result == DOWNLOAD_INTERRUPT_REASON_NONE) 100 if (result == DOWNLOAD_INTERRUPT_REASON_NONE)
101 EXPECT_TRUE(expect_in_progress_) << " result = " << result; 101 EXPECT_TRUE(expect_in_progress_) << " result = " << result;
102 102
103 EXPECT_EQ(expected_error_, result); 103 EXPECT_EQ(expected_error_, result);
104 if (base_file_->in_progress()) { 104 if (base_file_->in_progress()) {
105 expected_data_ += data; 105 expected_data_ += data;
106 if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) { 106 if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) {
107 EXPECT_EQ(static_cast<int64_t>(expected_data_.size()), 107 EXPECT_EQ(static_cast<int64_t>(expected_data_.size()),
108 base_file_->bytes_so_far()); 108 base_file_->offset());
109 } 109 }
110 } 110 }
111 return result == DOWNLOAD_INTERRUPT_REASON_NONE; 111 return result == DOWNLOAD_INTERRUPT_REASON_NONE;
112 } 112 }
113 113
114 void set_expected_data(const std::string& data) { expected_data_ = data; } 114 void set_expected_data(const std::string& data) { expected_data_ = data; }
115 115
116 // Helper functions. 116 // Helper functions.
117 // Create a file. Returns the complete file path. 117 // Create a file. Returns the complete file path.
118 base::FilePath CreateTestFile() { 118 base::FilePath CreateTestFile() {
119 base::FilePath file_name; 119 base::FilePath file_name;
120 BaseFile file((net::NetLogWithSource())); 120 BaseFile file((net::NetLogWithSource()));
121 121
122 EXPECT_EQ( 122 EXPECT_EQ(
123 DOWNLOAD_INTERRUPT_REASON_NONE, 123 DOWNLOAD_INTERRUPT_REASON_NONE,
124 file.Initialize(base::FilePath(), temp_dir_.GetPath(), base::File(), 0, 124 file.Initialize(base::FilePath(), temp_dir_.GetPath(), base::File(), 0,
125 std::string(), std::unique_ptr<crypto::SecureHash>())); 125 std::string(), std::unique_ptr<crypto::SecureHash>(),
126 BaseFile::EXCLUSIVE));
126 file_name = file.full_path(); 127 file_name = file.full_path();
127 EXPECT_NE(base::FilePath::StringType(), file_name.value()); 128 EXPECT_NE(base::FilePath::StringType(), file_name.value());
128 129
129 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 130 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
130 file.AppendDataToFile(kTestData4, kTestDataLength4)); 131 file.WriteDataToFile(kTestData4, kTestDataLength4));
131 132
132 // Keep the file from getting deleted when existing_file_name is deleted. 133 // Keep the file from getting deleted when existing_file_name is deleted.
133 file.Detach(); 134 file.Detach();
134 135
135 return file_name; 136 return file_name;
136 } 137 }
137 138
138 // Create a file with the specified file name. 139 // Create a file with the specified file name.
139 void CreateFileWithName(const base::FilePath& file_name) { 140 void CreateFileWithName(const base::FilePath& file_name) {
140 EXPECT_NE(base::FilePath::StringType(), file_name.value()); 141 EXPECT_NE(base::FilePath::StringType(), file_name.value());
141 BaseFile duplicate_file((net::NetLogWithSource())); 142 BaseFile duplicate_file((net::NetLogWithSource()));
142 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 143 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
143 duplicate_file.Initialize(file_name, temp_dir_.GetPath(), 144 duplicate_file.Initialize(file_name, temp_dir_.GetPath(),
144 base::File(), 0, std::string(), 145 base::File(), 0, std::string(),
145 std::unique_ptr<crypto::SecureHash>())); 146 std::unique_ptr<crypto::SecureHash>(),
147 BaseFile::EXCLUSIVE));
146 // Write something into it. 148 // Write something into it.
147 duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4); 149 duplicate_file.WriteDataToFile(kTestData4, kTestDataLength4);
148 // Detach the file so it isn't deleted on destruction of |duplicate_file|. 150 // Detach the file so it isn't deleted on destruction of |duplicate_file|.
149 duplicate_file.Detach(); 151 duplicate_file.Detach();
150 } 152 }
151 153
152 int64_t CurrentSpeedAtTime(base::TimeTicks current_time) { 154 int64_t CurrentSpeedAtTime(base::TimeTicks current_time) {
153 EXPECT_TRUE(base_file_.get()); 155 EXPECT_TRUE(base_file_.get());
154 return base_file_->CurrentSpeedAtTime(current_time); 156 return base_file_->CurrentSpeedAtTime(current_time);
155 } 157 }
156 158
157 base::TimeTicks StartTick() { 159 base::TimeTicks StartTick() {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 EXPECT_TRUE(base::PathExists(base_file_->full_path())); 217 EXPECT_TRUE(base::PathExists(base_file_->full_path()));
216 base_file_->Cancel(); 218 base_file_->Cancel();
217 EXPECT_FALSE(base::PathExists(base_file_->full_path())); 219 EXPECT_FALSE(base::PathExists(base_file_->full_path()));
218 EXPECT_NE(base::FilePath().value(), base_file_->full_path().value()); 220 EXPECT_NE(base::FilePath().value(), base_file_->full_path().value());
219 } 221 }
220 222
221 // Write data to the file and detach it, so it doesn't get deleted 223 // Write data to the file and detach it, so it doesn't get deleted
222 // automatically when base_file_ is destructed. 224 // automatically when base_file_ is destructed.
223 TEST_F(BaseFileTest, WriteAndDetach) { 225 TEST_F(BaseFileTest, WriteAndDetach) {
224 ASSERT_TRUE(InitializeFile()); 226 ASSERT_TRUE(InitializeFile());
225 ASSERT_TRUE(AppendDataToFile(kTestData1)); 227 ASSERT_TRUE(WriteDataToFile(kTestData1));
226 base_file_->Finish(); 228 base_file_->Finish();
227 base_file_->Detach(); 229 base_file_->Detach();
228 expect_file_survives_ = true; 230 expect_file_survives_ = true;
229 } 231 }
230 232
231 // Write data to the file and detach it, and calculate its sha256 hash. 233 // Write data to the file and detach it, and calculate its sha256 hash.
232 TEST_F(BaseFileTest, WriteWithHashAndDetach) { 234 TEST_F(BaseFileTest, WriteWithHashAndDetach) {
233 ASSERT_TRUE(InitializeFile()); 235 ASSERT_TRUE(InitializeFile());
234 ASSERT_TRUE(AppendDataToFile(kTestData1)); 236 ASSERT_TRUE(WriteDataToFile(kTestData1));
235 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); 237 ExpectHashValue(kHashOfTestData1, base_file_->Finish());
236 base_file_->Detach(); 238 base_file_->Detach();
237 expect_file_survives_ = true; 239 expect_file_survives_ = true;
238 } 240 }
239 241
240 // Rename the file after writing to it, then detach. 242 // Rename the file after writing to it, then detach.
241 TEST_F(BaseFileTest, WriteThenRenameAndDetach) { 243 TEST_F(BaseFileTest, WriteThenRenameAndDetach) {
242 ASSERT_TRUE(InitializeFile()); 244 ASSERT_TRUE(InitializeFile());
243 245
244 base::FilePath initial_path(base_file_->full_path()); 246 base::FilePath initial_path(base_file_->full_path());
245 EXPECT_TRUE(base::PathExists(initial_path)); 247 EXPECT_TRUE(base::PathExists(initial_path));
246 base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile")); 248 base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile"));
247 EXPECT_FALSE(base::PathExists(new_path)); 249 EXPECT_FALSE(base::PathExists(new_path));
248 250
249 ASSERT_TRUE(AppendDataToFile(kTestData1)); 251 ASSERT_TRUE(WriteDataToFile(kTestData1));
250 252
251 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); 253 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
252 EXPECT_FALSE(base::PathExists(initial_path)); 254 EXPECT_FALSE(base::PathExists(initial_path));
253 EXPECT_TRUE(base::PathExists(new_path)); 255 EXPECT_TRUE(base::PathExists(new_path));
254 256
255 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); 257 ExpectHashValue(kHashOfTestData1, base_file_->Finish());
256 base_file_->Detach(); 258 base_file_->Detach();
257 expect_file_survives_ = true; 259 expect_file_survives_ = true;
258 } 260 }
259 261
260 // Write data to the file once. 262 // Write data to the file once.
261 TEST_F(BaseFileTest, SingleWrite) { 263 TEST_F(BaseFileTest, SingleWrite) {
262 ASSERT_TRUE(InitializeFile()); 264 ASSERT_TRUE(InitializeFile());
263 ASSERT_TRUE(AppendDataToFile(kTestData1)); 265 ASSERT_TRUE(WriteDataToFile(kTestData1));
264 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); 266 ExpectHashValue(kHashOfTestData1, base_file_->Finish());
265 } 267 }
266 268
267 // Write data to the file multiple times. 269 // Write data to the file multiple times.
268 TEST_F(BaseFileTest, MultipleWrites) { 270 TEST_F(BaseFileTest, MultipleWrites) {
269 ASSERT_TRUE(InitializeFile()); 271 ASSERT_TRUE(InitializeFile());
270 ASSERT_TRUE(AppendDataToFile(kTestData1)); 272 ASSERT_TRUE(WriteDataToFile(kTestData1));
271 ASSERT_TRUE(AppendDataToFile(kTestData2)); 273 ASSERT_TRUE(WriteDataToFile(kTestData2));
272 ASSERT_TRUE(AppendDataToFile(kTestData3)); 274 ASSERT_TRUE(WriteDataToFile(kTestData3));
273 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); 275 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
274 } 276 }
275 277
276 // Write data to the file multiple times, interrupt it, and continue using 278 // Write data to the file multiple times, interrupt it, and continue using
277 // another file. Calculate the resulting combined sha256 hash. 279 // another file. Calculate the resulting combined sha256 hash.
278 TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) { 280 TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) {
279 ASSERT_TRUE(InitializeFile()); 281 ASSERT_TRUE(InitializeFile());
280 // Write some data 282 // Write some data
281 ASSERT_TRUE(AppendDataToFile(kTestData1)); 283 ASSERT_TRUE(WriteDataToFile(kTestData1));
282 ASSERT_TRUE(AppendDataToFile(kTestData2)); 284 ASSERT_TRUE(WriteDataToFile(kTestData2));
283 // Get the hash state and file name. 285 // Get the hash state and file name.
284 std::unique_ptr<crypto::SecureHash> hash_state = base_file_->Finish(); 286 std::unique_ptr<crypto::SecureHash> hash_state = base_file_->Finish();
285 287
286 base::FilePath new_file_path(temp_dir_.GetPath().Append( 288 base::FilePath new_file_path(temp_dir_.GetPath().Append(
287 base::FilePath(FILE_PATH_LITERAL("second_file")))); 289 base::FilePath(FILE_PATH_LITERAL("second_file"))));
288 290
289 ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path)); 291 ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path));
290 292
291 // Create another file 293 // Create another file
292 BaseFile second_file((net::NetLogWithSource())); 294 BaseFile second_file((net::NetLogWithSource()));
293 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 295 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
294 second_file.Initialize(new_file_path, 296 second_file.Initialize(new_file_path,
295 base::FilePath(), 297 base::FilePath(),
296 base::File(), 298 base::File(),
297 base_file_->bytes_so_far(), 299 base_file_->bytes_so_far(),
298 std::string(), 300 std::string(),
299 std::move(hash_state))); 301 std::move(hash_state),
302 BaseFile::EXCLUSIVE));
300 std::string data(kTestData3); 303 std::string data(kTestData3);
301 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 304 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
302 second_file.AppendDataToFile(data.data(), data.size())); 305 second_file.WriteDataToFile(data.data(), data.size()));
303 ExpectHashValue(kHashOfTestData1To3, second_file.Finish()); 306 ExpectHashValue(kHashOfTestData1To3, second_file.Finish());
304 } 307 }
305 308
306 // Rename the file after all writes to it. 309 // Rename the file after all writes to it.
307 TEST_F(BaseFileTest, WriteThenRename) { 310 TEST_F(BaseFileTest, WriteThenRename) {
308 ASSERT_TRUE(InitializeFile()); 311 ASSERT_TRUE(InitializeFile());
309 312
310 base::FilePath initial_path(base_file_->full_path()); 313 base::FilePath initial_path(base_file_->full_path());
311 EXPECT_TRUE(base::PathExists(initial_path)); 314 EXPECT_TRUE(base::PathExists(initial_path));
312 base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile")); 315 base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile"));
313 EXPECT_FALSE(base::PathExists(new_path)); 316 EXPECT_FALSE(base::PathExists(new_path));
314 317
315 ASSERT_TRUE(AppendDataToFile(kTestData1)); 318 ASSERT_TRUE(WriteDataToFile(kTestData1));
316 319
317 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 320 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
318 base_file_->Rename(new_path)); 321 base_file_->Rename(new_path));
319 EXPECT_FALSE(base::PathExists(initial_path)); 322 EXPECT_FALSE(base::PathExists(initial_path));
320 EXPECT_TRUE(base::PathExists(new_path)); 323 EXPECT_TRUE(base::PathExists(new_path));
321 324
322 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); 325 ExpectHashValue(kHashOfTestData1, base_file_->Finish());
323 } 326 }
324 327
325 // Rename the file while the download is still in progress. 328 // Rename the file while the download is still in progress.
326 TEST_F(BaseFileTest, RenameWhileInProgress) { 329 TEST_F(BaseFileTest, RenameWhileInProgress) {
327 ASSERT_TRUE(InitializeFile()); 330 ASSERT_TRUE(InitializeFile());
328 331
329 base::FilePath initial_path(base_file_->full_path()); 332 base::FilePath initial_path(base_file_->full_path());
330 EXPECT_TRUE(base::PathExists(initial_path)); 333 EXPECT_TRUE(base::PathExists(initial_path));
331 base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile")); 334 base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile"));
332 EXPECT_FALSE(base::PathExists(new_path)); 335 EXPECT_FALSE(base::PathExists(new_path));
333 336
334 ASSERT_TRUE(AppendDataToFile(kTestData1)); 337 ASSERT_TRUE(WriteDataToFile(kTestData1));
335 338
336 EXPECT_TRUE(base_file_->in_progress()); 339 EXPECT_TRUE(base_file_->in_progress());
337 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); 340 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
338 EXPECT_FALSE(base::PathExists(initial_path)); 341 EXPECT_FALSE(base::PathExists(initial_path));
339 EXPECT_TRUE(base::PathExists(new_path)); 342 EXPECT_TRUE(base::PathExists(new_path));
340 343
341 ASSERT_TRUE(AppendDataToFile(kTestData2)); 344 ASSERT_TRUE(WriteDataToFile(kTestData2));
342 ASSERT_TRUE(AppendDataToFile(kTestData3)); 345 ASSERT_TRUE(WriteDataToFile(kTestData3));
343 346
344 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); 347 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
345 } 348 }
346 349
347 // Test that a failed rename reports the correct error. 350 // Test that a failed rename reports the correct error.
348 TEST_F(BaseFileTest, RenameWithError) { 351 TEST_F(BaseFileTest, RenameWithError) {
349 ASSERT_TRUE(InitializeFile()); 352 ASSERT_TRUE(InitializeFile());
350 353
351 // TestDir is a subdirectory in |temp_dir_| that we will make read-only so 354 // TestDir is a subdirectory in |temp_dir_| that we will make read-only so
352 // that the rename will fail. 355 // that the rename will fail.
(...skipping 17 matching lines...) Expand all
370 TEST_F(BaseFileTest, RenameWithErrorInProgress) { 373 TEST_F(BaseFileTest, RenameWithErrorInProgress) {
371 ASSERT_TRUE(InitializeFile()); 374 ASSERT_TRUE(InitializeFile());
372 375
373 base::FilePath test_dir(temp_dir_.GetPath().AppendASCII("TestDir")); 376 base::FilePath test_dir(temp_dir_.GetPath().AppendASCII("TestDir"));
374 ASSERT_TRUE(base::CreateDirectory(test_dir)); 377 ASSERT_TRUE(base::CreateDirectory(test_dir));
375 378
376 base::FilePath new_path(test_dir.AppendASCII("TestFile")); 379 base::FilePath new_path(test_dir.AppendASCII("TestFile"));
377 EXPECT_FALSE(base::PathExists(new_path)); 380 EXPECT_FALSE(base::PathExists(new_path));
378 381
379 // Write some data to start with. 382 // Write some data to start with.
380 ASSERT_TRUE(AppendDataToFile(kTestData1)); 383 ASSERT_TRUE(WriteDataToFile(kTestData1));
381 ASSERT_TRUE(base_file_->in_progress()); 384 ASSERT_TRUE(base_file_->in_progress());
382 385
383 base::FilePath old_path = base_file_->full_path(); 386 base::FilePath old_path = base_file_->full_path();
384 387
385 { 388 {
386 base::FilePermissionRestorer restore_permissions_for(test_dir); 389 base::FilePermissionRestorer restore_permissions_for(test_dir);
387 ASSERT_TRUE(base::MakeFileUnwritable(test_dir)); 390 ASSERT_TRUE(base::MakeFileUnwritable(test_dir));
388 ExpectPermissionError(base_file_->Rename(new_path)); 391 ExpectPermissionError(base_file_->Rename(new_path));
389 392
390 // The file should still be open and we should be able to continue writing 393 // The file should still be open and we should be able to continue writing
391 // to it. 394 // to it.
392 ASSERT_TRUE(base_file_->in_progress()); 395 ASSERT_TRUE(base_file_->in_progress());
393 ASSERT_TRUE(AppendDataToFile(kTestData2)); 396 ASSERT_TRUE(WriteDataToFile(kTestData2));
394 ASSERT_EQ(old_path.value(), base_file_->full_path().value()); 397 ASSERT_EQ(old_path.value(), base_file_->full_path().value());
395 398
396 // Try to rename again, just for kicks. It should still fail. 399 // Try to rename again, just for kicks. It should still fail.
397 ExpectPermissionError(base_file_->Rename(new_path)); 400 ExpectPermissionError(base_file_->Rename(new_path));
398 } 401 }
399 402
400 // Now that TestDir is writeable again, we should be able to successfully 403 // Now that TestDir is writeable again, we should be able to successfully
401 // rename the file. 404 // rename the file.
402 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); 405 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
403 ASSERT_EQ(new_path.value(), base_file_->full_path().value()); 406 ASSERT_EQ(new_path.value(), base_file_->full_path().value());
404 ASSERT_TRUE(AppendDataToFile(kTestData3)); 407 ASSERT_TRUE(WriteDataToFile(kTestData3));
405 408
406 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); 409 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
407 } 410 }
408 411
409 // Test that a failed write reports an error. 412 // Test that a failed write reports an error.
410 TEST_F(BaseFileTest, WriteWithError) { 413 TEST_F(BaseFileTest, WriteWithError) {
411 base::FilePath path; 414 base::FilePath path;
412 ASSERT_TRUE(base::CreateTemporaryFile(&path)); 415 ASSERT_TRUE(base::CreateTemporaryFile(&path));
413 416
414 // Pass a file handle which was opened without the WRITE flag. 417 // Pass a file handle which was opened without the WRITE flag.
415 // This should result in an error when writing. 418 // This should result in an error when writing.
416 base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ); 419 base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ);
417 base_file_.reset(new BaseFile(net::NetLogWithSource())); 420 base_file_.reset(new BaseFile(net::NetLogWithSource()));
418 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 421 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
419 base_file_->Initialize(path, base::FilePath(), std::move(file), 0, 422 base_file_->Initialize(path, base::FilePath(), std::move(file), 0,
420 std::string(), 423 std::string(),
421 std::unique_ptr<crypto::SecureHash>())); 424 std::unique_ptr<crypto::SecureHash>(),
425 BaseFile::EXCLUSIVE));
422 #if defined(OS_WIN) 426 #if defined(OS_WIN)
423 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); 427 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
424 #elif defined (OS_POSIX) 428 #elif defined (OS_POSIX)
425 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 429 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
426 #endif 430 #endif
427 ASSERT_FALSE(AppendDataToFile(kTestData1)); 431 ASSERT_FALSE(WriteDataToFile(kTestData1));
428 base_file_->Finish(); 432 base_file_->Finish();
429 } 433 }
430 434
431 // Try to write to uninitialized file. 435 // Try to write to uninitialized file.
432 TEST_F(BaseFileTest, UninitializedFile) { 436 TEST_F(BaseFileTest, UninitializedFile) {
433 expect_in_progress_ = false; 437 expect_in_progress_ = false;
434 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 438 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
435 EXPECT_FALSE(AppendDataToFile(kTestData1)); 439 EXPECT_FALSE(WriteDataToFile(kTestData1));
436 } 440 }
437 441
438 // Create two |BaseFile|s with the same file, and attempt to write to both. 442 // Create two |BaseFile|s with the same file, and attempt to write to both.
439 // Overwrite base_file_ with another file with the same name and 443 // Overwrite base_file_ with another file with the same name and
440 // non-zero contents, and make sure the last file to close 'wins'. 444 // non-zero contents, and make sure the last file to close 'wins'.
441 TEST_F(BaseFileTest, DuplicateBaseFile) { 445 TEST_F(BaseFileTest, DuplicateBaseFile) {
442 ASSERT_TRUE(InitializeFile()); 446 ASSERT_TRUE(InitializeFile());
443 447
444 // Create another |BaseFile| referring to the file that |base_file_| owns. 448 // Create another |BaseFile| referring to the file that |base_file_| owns.
445 CreateFileWithName(base_file_->full_path()); 449 CreateFileWithName(base_file_->full_path());
446 450
447 ASSERT_TRUE(AppendDataToFile(kTestData1)); 451 ASSERT_TRUE(WriteDataToFile(kTestData1));
448 base_file_->Finish(); 452 base_file_->Finish();
449 } 453 }
450 454
451 // Create a file and append to it. 455 // Create a file and append to it.
452 TEST_F(BaseFileTest, AppendToBaseFile) { 456 TEST_F(BaseFileTest, AppendToBaseFile) {
453 // Create a new file. 457 // Create a new file.
454 base::FilePath existing_file_name = CreateTestFile(); 458 base::FilePath existing_file_name = CreateTestFile();
455 set_expected_data(kTestData4); 459 set_expected_data(kTestData4);
456 460
457 // Use the file we've just created. 461 // Use the file we've just created.
458 base_file_.reset(new BaseFile(net::NetLogWithSource())); 462 base_file_.reset(new BaseFile(net::NetLogWithSource()));
459 ASSERT_EQ( 463 ASSERT_EQ(
460 DOWNLOAD_INTERRUPT_REASON_NONE, 464 DOWNLOAD_INTERRUPT_REASON_NONE,
461 base_file_->Initialize(existing_file_name, base::FilePath(), base::File(), 465 base_file_->Initialize(existing_file_name, base::FilePath(), base::File(),
462 kTestDataLength4, std::string(), 466 kTestDataLength4, std::string(),
463 std::unique_ptr<crypto::SecureHash>())); 467 std::unique_ptr<crypto::SecureHash>(),
468 BaseFile::EXCLUSIVE));
464 469
465 const base::FilePath file_name = base_file_->full_path(); 470 const base::FilePath file_name = base_file_->full_path();
466 EXPECT_NE(base::FilePath::StringType(), file_name.value()); 471 EXPECT_NE(base::FilePath::StringType(), file_name.value());
467 472
468 // Write into the file. 473 // Write into the file.
469 EXPECT_TRUE(AppendDataToFile(kTestData1)); 474 EXPECT_TRUE(WriteDataToFile(kTestData1));
470 475
471 base_file_->Finish(); 476 base_file_->Finish();
472 base_file_->Detach(); 477 base_file_->Detach();
473 expect_file_survives_ = true; 478 expect_file_survives_ = true;
474 } 479 }
475 480
476 // Create a read-only file and attempt to write to it. 481 // Create a read-only file and attempt to write to it.
477 TEST_F(BaseFileTest, ReadonlyBaseFile) { 482 TEST_F(BaseFileTest, ReadonlyBaseFile) {
478 // Create a new file. 483 // Create a new file.
479 base::FilePath readonly_file_name = CreateTestFile(); 484 base::FilePath readonly_file_name = CreateTestFile();
480 485
481 // Restore permissions to the file when we are done with this test. 486 // Restore permissions to the file when we are done with this test.
482 base::FilePermissionRestorer restore_permissions(readonly_file_name); 487 base::FilePermissionRestorer restore_permissions(readonly_file_name);
483 488
484 // Make it read-only. 489 // Make it read-only.
485 EXPECT_TRUE(base::MakeFileUnwritable(readonly_file_name)); 490 EXPECT_TRUE(base::MakeFileUnwritable(readonly_file_name));
486 491
487 // Try to overwrite it. 492 // Try to overwrite it.
488 base_file_.reset(new BaseFile(net::NetLogWithSource())); 493 base_file_.reset(new BaseFile(net::NetLogWithSource()));
489 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, 494 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
490 base_file_->Initialize(readonly_file_name, base::FilePath(), 495 base_file_->Initialize(readonly_file_name, base::FilePath(),
491 base::File(), 0, std::string(), 496 base::File(), 0, std::string(),
492 std::unique_ptr<crypto::SecureHash>())); 497 std::unique_ptr<crypto::SecureHash>(),
498 BaseFile::EXCLUSIVE));
493 499
494 expect_in_progress_ = false; 500 expect_in_progress_ = false;
495 501
496 const base::FilePath file_name = base_file_->full_path(); 502 const base::FilePath file_name = base_file_->full_path();
497 EXPECT_NE(base::FilePath::StringType(), file_name.value()); 503 EXPECT_NE(base::FilePath::StringType(), file_name.value());
498 504
499 // Write into the file. 505 // Write into the file.
500 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 506 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
501 EXPECT_FALSE(AppendDataToFile(kTestData1)); 507 EXPECT_FALSE(WriteDataToFile(kTestData1));
502 508
503 base_file_->Finish(); 509 base_file_->Finish();
504 base_file_->Detach(); 510 base_file_->Detach();
505 expect_file_survives_ = true; 511 expect_file_survives_ = true;
506 } 512 }
507 513
508 // Open an existing file and continue writing to it. The hash of the partial 514 // Open an existing file and continue writing to it. The hash of the partial
509 // file is known and matches the existing contents. 515 // file is known and matches the existing contents.
510 TEST_F(BaseFileTest, ExistingBaseFileKnownHash) { 516 TEST_F(BaseFileTest, ExistingBaseFileKnownHash) {
511 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing"); 517 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
512 ASSERT_EQ(kTestDataLength1, 518 ASSERT_EQ(kTestDataLength1,
513 base::WriteFile(file_path, kTestData1, kTestDataLength1)); 519 base::WriteFile(file_path, kTestData1, kTestDataLength1));
514 520
515 std::string hash_so_far(std::begin(kHashOfTestData1), 521 std::string hash_so_far(std::begin(kHashOfTestData1),
516 std::end(kHashOfTestData1)); 522 std::end(kHashOfTestData1));
517 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 523 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
518 base_file_->Initialize(file_path, base::FilePath(), base::File(), 524 base_file_->Initialize(file_path, base::FilePath(), base::File(),
519 kTestDataLength1, hash_so_far, 525 kTestDataLength1, hash_so_far,
520 std::unique_ptr<crypto::SecureHash>())); 526 std::unique_ptr<crypto::SecureHash>(),
527 BaseFile::EXCLUSIVE));
521 set_expected_data(kTestData1); 528 set_expected_data(kTestData1);
522 ASSERT_TRUE(AppendDataToFile(kTestData2)); 529 ASSERT_TRUE(WriteDataToFile(kTestData2));
523 ASSERT_TRUE(AppendDataToFile(kTestData3)); 530 ASSERT_TRUE(WriteDataToFile(kTestData3));
524 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); 531 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
525 } 532 }
526 533
527 // Open an existing file and continue writing to it. The hash of the partial 534 // Open an existing file and continue writing to it. The hash of the partial
528 // file is unknown. 535 // file is unknown.
529 TEST_F(BaseFileTest, ExistingBaseFileUnknownHash) { 536 TEST_F(BaseFileTest, ExistingBaseFileUnknownHash) {
530 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing"); 537 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
531 ASSERT_EQ(kTestDataLength1, 538 ASSERT_EQ(kTestDataLength1,
532 base::WriteFile(file_path, kTestData1, kTestDataLength1)); 539 base::WriteFile(file_path, kTestData1, kTestDataLength1));
533 540
534 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 541 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
535 base_file_->Initialize(file_path, base::FilePath(), base::File(), 542 base_file_->Initialize(file_path, base::FilePath(), base::File(),
536 kTestDataLength1, std::string(), 543 kTestDataLength1, std::string(),
537 std::unique_ptr<crypto::SecureHash>())); 544 std::unique_ptr<crypto::SecureHash>(),
545 BaseFile::EXCLUSIVE));
538 set_expected_data(kTestData1); 546 set_expected_data(kTestData1);
539 ASSERT_TRUE(AppendDataToFile(kTestData2)); 547 ASSERT_TRUE(WriteDataToFile(kTestData2));
540 ASSERT_TRUE(AppendDataToFile(kTestData3)); 548 ASSERT_TRUE(WriteDataToFile(kTestData3));
541 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); 549 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
542 } 550 }
543 551
544 // Open an existing file. The contentsof the file doesn't match the known hash. 552 // Open an existing file. The contentsof the file doesn't match the known hash.
545 TEST_F(BaseFileTest, ExistingBaseFileIncorrectHash) { 553 TEST_F(BaseFileTest, ExistingBaseFileIncorrectHash) {
546 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing"); 554 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
547 ASSERT_EQ(kTestDataLength2, 555 ASSERT_EQ(kTestDataLength2,
548 base::WriteFile(file_path, kTestData2, kTestDataLength2)); 556 base::WriteFile(file_path, kTestData2, kTestDataLength2));
549 557
550 std::string hash_so_far(std::begin(kHashOfTestData1), 558 std::string hash_so_far(std::begin(kHashOfTestData1),
551 std::end(kHashOfTestData1)); 559 std::end(kHashOfTestData1));
552 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, 560 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH,
553 base_file_->Initialize(file_path, base::FilePath(), base::File(), 561 base_file_->Initialize(file_path, base::FilePath(), base::File(),
554 kTestDataLength2, hash_so_far, 562 kTestDataLength2, hash_so_far,
555 std::unique_ptr<crypto::SecureHash>())); 563 std::unique_ptr<crypto::SecureHash>(),
564 BaseFile::EXCLUSIVE));
556 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); 565 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH);
557 } 566 }
558 567
559 // Open a large existing file with a known hash and continue writing to it. 568 // Open a large existing file with a known hash and continue writing to it.
560 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeKnownHash) { 569 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeKnownHash) {
561 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing"); 570 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
562 std::string big_buffer(1024 * 200, 'a'); 571 std::string big_buffer(1024 * 200, 'a');
563 ASSERT_EQ(static_cast<int>(big_buffer.size()), 572 ASSERT_EQ(static_cast<int>(big_buffer.size()),
564 base::WriteFile(file_path, big_buffer.data(), big_buffer.size())); 573 base::WriteFile(file_path, big_buffer.data(), big_buffer.size()));
565 574
566 // Hash of partial file (1024*200 * 'a') 575 // Hash of partial file (1024*200 * 'a')
567 const uint8_t kExpectedPartialHash[] = { 576 const uint8_t kExpectedPartialHash[] = {
568 0x4b, 0x4f, 0x0f, 0x46, 0xac, 0x02, 0xd1, 0x77, 0xde, 0xa0, 0xab, 577 0x4b, 0x4f, 0x0f, 0x46, 0xac, 0x02, 0xd1, 0x77, 0xde, 0xa0, 0xab,
569 0x36, 0xa6, 0x6a, 0x65, 0x78, 0x40, 0xe2, 0xfb, 0x98, 0xb2, 0x0b, 578 0x36, 0xa6, 0x6a, 0x65, 0x78, 0x40, 0xe2, 0xfb, 0x98, 0xb2, 0x0b,
570 0xb2, 0x7a, 0x68, 0x8d, 0xb4, 0xd8, 0xea, 0x9c, 0xd2, 0x2c}; 579 0xb2, 0x7a, 0x68, 0x8d, 0xb4, 0xd8, 0xea, 0x9c, 0xd2, 0x2c};
571 580
572 // Hash of entire file (1024*400 * 'a') 581 // Hash of entire file (1024*400 * 'a')
573 const uint8_t kExpectedFullHash[] = { 582 const uint8_t kExpectedFullHash[] = {
574 0x0c, 0xe9, 0xf6, 0x78, 0x6b, 0x0f, 0x58, 0x49, 0x36, 0xe8, 0x83, 583 0x0c, 0xe9, 0xf6, 0x78, 0x6b, 0x0f, 0x58, 0x49, 0x36, 0xe8, 0x83,
575 0xc5, 0x09, 0x16, 0xbc, 0x5e, 0x2d, 0x07, 0x95, 0xb9, 0x42, 0x20, 584 0xc5, 0x09, 0x16, 0xbc, 0x5e, 0x2d, 0x07, 0x95, 0xb9, 0x42, 0x20,
576 0x41, 0x7c, 0xb3, 0x38, 0xd3, 0xf4, 0xe0, 0x78, 0x89, 0x46}; 585 0x41, 0x7c, 0xb3, 0x38, 0xd3, 0xf4, 0xe0, 0x78, 0x89, 0x46};
577 586
578 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 587 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
579 base_file_->Initialize(file_path, base::FilePath(), base::File(), 588 base_file_->Initialize(file_path, base::FilePath(), base::File(),
580 big_buffer.size(), 589 big_buffer.size(),
581 std::string(std::begin(kExpectedPartialHash), 590 std::string(std::begin(kExpectedPartialHash),
582 std::end(kExpectedPartialHash)), 591 std::end(kExpectedPartialHash)),
583 std::unique_ptr<crypto::SecureHash>())); 592 std::unique_ptr<crypto::SecureHash>(),
593 BaseFile::EXCLUSIVE));
584 set_expected_data(big_buffer); // Contents of the file on Open. 594 set_expected_data(big_buffer); // Contents of the file on Open.
585 ASSERT_TRUE(AppendDataToFile(big_buffer)); 595 ASSERT_TRUE(WriteDataToFile(big_buffer));
586 ExpectHashValue(kExpectedFullHash, base_file_->Finish()); 596 ExpectHashValue(kExpectedFullHash, base_file_->Finish());
587 } 597 }
588 598
589 // Open a large existing file. The contents doesn't match the known hash. 599 // Open a large existing file. The contents doesn't match the known hash.
590 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeIncorrectHash) { 600 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeIncorrectHash) {
591 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing"); 601 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
592 std::string big_buffer(1024 * 200, 'a'); 602 std::string big_buffer(1024 * 200, 'a');
593 ASSERT_EQ(static_cast<int>(big_buffer.size()), 603 ASSERT_EQ(static_cast<int>(big_buffer.size()),
594 base::WriteFile(file_path, big_buffer.data(), big_buffer.size())); 604 base::WriteFile(file_path, big_buffer.data(), big_buffer.size()));
595 605
596 // Incorrect hash of partial file (1024*200 * 'a') 606 // Incorrect hash of partial file (1024*200 * 'a')
597 const uint8_t kExpectedPartialHash[] = { 607 const uint8_t kExpectedPartialHash[] = {
598 0xc2, 0xa9, 0x08, 0xd9, 0x8f, 0x5d, 0xf9, 0x87, 0xad, 0xe4, 0x1b, 608 0xc2, 0xa9, 0x08, 0xd9, 0x8f, 0x5d, 0xf9, 0x87, 0xad, 0xe4, 0x1b,
599 0x5f, 0xce, 0x21, 0x30, 0x67, 0xef, 0x6c, 0xc2, 0x1e, 0xf2, 0x24, 609 0x5f, 0xce, 0x21, 0x30, 0x67, 0xef, 0x6c, 0xc2, 0x1e, 0xf2, 0x24,
600 0x02, 0x12, 0xa4, 0x1e, 0x54, 0xb5, 0xe7, 0xc2, 0x8a, 0xe5}; 610 0x02, 0x12, 0xa4, 0x1e, 0x54, 0xb5, 0xe7, 0xc2, 0x8a, 0xe5};
601 611
602 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, 612 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH,
603 base_file_->Initialize(file_path, base::FilePath(), base::File(), 613 base_file_->Initialize(file_path, base::FilePath(), base::File(),
604 big_buffer.size(), 614 big_buffer.size(),
605 std::string(std::begin(kExpectedPartialHash), 615 std::string(std::begin(kExpectedPartialHash),
606 std::end(kExpectedPartialHash)), 616 std::end(kExpectedPartialHash)),
607 std::unique_ptr<crypto::SecureHash>())); 617 std::unique_ptr<crypto::SecureHash>(),
618 BaseFile::EXCLUSIVE));
608 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); 619 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH);
609 } 620 }
610 621
611 // Open an existing file. The size of the file is too short. 622 // Open an existing file. The size of the file is too short.
612 TEST_F(BaseFileTest, ExistingBaseFileTooShort) { 623 TEST_F(BaseFileTest, ExistingBaseFileTooShort) {
613 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing"); 624 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
614 ASSERT_EQ(kTestDataLength1, 625 ASSERT_EQ(kTestDataLength1,
615 base::WriteFile(file_path, kTestData1, kTestDataLength1)); 626 base::WriteFile(file_path, kTestData1, kTestDataLength1));
616 627
617 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT, 628 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT,
618 base_file_->Initialize(file_path, base::FilePath(), base::File(), 629 base_file_->Initialize(file_path, base::FilePath(), base::File(),
619 kTestDataLength1 + 1, std::string(), 630 kTestDataLength1 + 1, std::string(),
620 std::unique_ptr<crypto::SecureHash>())); 631 std::unique_ptr<crypto::SecureHash>(),
632 BaseFile::EXCLUSIVE));
621 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT); 633 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT);
622 } 634 }
623 635
624 // Open an existing file. The size is larger than expected. 636 // Open an existing file. The size is larger than expected.
625 TEST_F(BaseFileTest, ExistingBaseFileKnownHashTooLong) { 637 TEST_F(BaseFileTest, ExistingBaseFileKnownHashTooLong) {
626 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing"); 638 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
627 std::string contents; 639 std::string contents;
628 contents.append(kTestData1); 640 contents.append(kTestData1);
629 contents.append("Something extra"); 641 contents.append("Something extra");
630 ASSERT_EQ(static_cast<int>(contents.size()), 642 ASSERT_EQ(static_cast<int>(contents.size()),
631 base::WriteFile(file_path, contents.data(), contents.size())); 643 base::WriteFile(file_path, contents.data(), contents.size()));
632 644
633 std::string hash_so_far(std::begin(kHashOfTestData1), 645 std::string hash_so_far(std::begin(kHashOfTestData1),
634 std::end(kHashOfTestData1)); 646 std::end(kHashOfTestData1));
635 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 647 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
636 base_file_->Initialize(file_path, base::FilePath(), base::File(), 648 base_file_->Initialize(file_path, base::FilePath(), base::File(),
637 kTestDataLength1, hash_so_far, 649 kTestDataLength1, hash_so_far,
638 std::unique_ptr<crypto::SecureHash>())); 650 std::unique_ptr<crypto::SecureHash>(),
651 BaseFile::EXCLUSIVE));
639 set_expected_data(kTestData1); // Our starting position. 652 set_expected_data(kTestData1); // Our starting position.
640 ASSERT_TRUE(AppendDataToFile(kTestData2)); 653 ASSERT_TRUE(WriteDataToFile(kTestData2));
641 ASSERT_TRUE(AppendDataToFile(kTestData3)); 654 ASSERT_TRUE(WriteDataToFile(kTestData3));
642 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); 655 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
643 } 656 }
644 657
645 // Open an existing file. The size is large than expected and the hash is 658 // Open an existing file. The size is large than expected and the hash is
646 // unknown. 659 // unknown.
647 TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLong) { 660 TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLong) {
648 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing"); 661 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
649 std::string contents; 662 std::string contents;
650 contents.append(kTestData1); 663 contents.append(kTestData1);
651 contents.append("Something extra"); 664 contents.append("Something extra");
652 ASSERT_EQ(static_cast<int>(contents.size()), 665 ASSERT_EQ(static_cast<int>(contents.size()),
653 base::WriteFile(file_path, contents.data(), contents.size())); 666 base::WriteFile(file_path, contents.data(), contents.size()));
654 667
655 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 668 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
656 base_file_->Initialize(file_path, base::FilePath(), base::File(), 669 base_file_->Initialize(file_path, base::FilePath(), base::File(),
657 kTestDataLength1, std::string(), 670 kTestDataLength1, std::string(),
658 std::unique_ptr<crypto::SecureHash>())); 671 std::unique_ptr<crypto::SecureHash>(),
672 BaseFile::EXCLUSIVE));
659 set_expected_data(kTestData1); 673 set_expected_data(kTestData1);
660 ASSERT_TRUE(AppendDataToFile(kTestData2)); 674 ASSERT_TRUE(WriteDataToFile(kTestData2));
661 ASSERT_TRUE(AppendDataToFile(kTestData3)); 675 ASSERT_TRUE(WriteDataToFile(kTestData3));
662 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); 676 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
663 } 677 }
664 678
665 // Similar to ExistingBaseFileKnownHashTooLong test, but with a file large 679 // Similar to ExistingBaseFileKnownHashTooLong test, but with a file large
666 // enough to requre multiple Read()s to complete. This provides additional code 680 // enough to requre multiple Read()s to complete. This provides additional code
667 // coverage for the CalculatePartialHash() logic. 681 // coverage for the CalculatePartialHash() logic.
668 TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLongForLargeFile) { 682 TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLongForLargeFile) {
669 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing"); 683 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
670 const size_t kFileSize = 1024 * 1024; 684 const size_t kFileSize = 1024 * 1024;
671 const size_t kIntermediateSize = kFileSize / 2 + 111; 685 const size_t kIntermediateSize = kFileSize / 2 + 111;
672 // |contents| is 100 bytes longer than kIntermediateSize. The latter is the 686 // |contents| is 100 bytes longer than kIntermediateSize. The latter is the
673 // expected size. 687 // expected size.
674 std::string contents(kIntermediateSize + 100, 'a'); 688 std::string contents(kIntermediateSize + 100, 'a');
675 ASSERT_EQ(static_cast<int>(contents.size()), 689 ASSERT_EQ(static_cast<int>(contents.size()),
676 base::WriteFile(file_path, contents.data(), contents.size())); 690 base::WriteFile(file_path, contents.data(), contents.size()));
677 691
678 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 692 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
679 base_file_->Initialize(file_path, base::FilePath(), base::File(), 693 base_file_->Initialize(file_path, base::FilePath(), base::File(),
680 kIntermediateSize, std::string(), 694 kIntermediateSize, std::string(),
681 std::unique_ptr<crypto::SecureHash>())); 695 std::unique_ptr<crypto::SecureHash>(),
696 BaseFile::EXCLUSIVE));
682 // The extra bytes should be stripped during Initialize(). 697 // The extra bytes should be stripped during Initialize().
683 contents.resize(kIntermediateSize, 'a'); 698 contents.resize(kIntermediateSize, 'a');
684 set_expected_data(contents); 699 set_expected_data(contents);
685 std::string new_data(kFileSize - kIntermediateSize, 'a'); 700 std::string new_data(kFileSize - kIntermediateSize, 'a');
686 ASSERT_TRUE(AppendDataToFile(new_data)); 701 ASSERT_TRUE(WriteDataToFile(new_data));
687 const uint8_t kExpectedHash[] = { 702 const uint8_t kExpectedHash[] = {
688 0x9b, 0xc1, 0xb2, 0xa2, 0x88, 0xb2, 0x6a, 0xf7, 0x25, 0x7a, 0x36, 703 0x9b, 0xc1, 0xb2, 0xa2, 0x88, 0xb2, 0x6a, 0xf7, 0x25, 0x7a, 0x36,
689 0x27, 0x7a, 0xe3, 0x81, 0x6a, 0x7d, 0x4f, 0x16, 0xe8, 0x9c, 0x1e, 704 0x27, 0x7a, 0xe3, 0x81, 0x6a, 0x7d, 0x4f, 0x16, 0xe8, 0x9c, 0x1e,
690 0x7e, 0x77, 0xd0, 0xa5, 0xc4, 0x8b, 0xad, 0x62, 0xb3, 0x60, 705 0x7e, 0x77, 0xd0, 0xa5, 0xc4, 0x8b, 0xad, 0x62, 0xb3, 0x60,
691 }; 706 };
692 ExpectHashValue(kExpectedHash, base_file_->Finish()); 707 ExpectHashValue(kExpectedHash, base_file_->Finish());
693 } 708 }
694 709
695 // Test that a temporary file is created in the default download directory. 710 // Test that a temporary file is created in the default download directory.
696 TEST_F(BaseFileTest, CreatedInDefaultDirectory) { 711 TEST_F(BaseFileTest, CreatedInDefaultDirectory) {
(...skipping 24 matching lines...) Expand all
721 ASSERT_FALSE(base::PathExists(full_path)); 736 ASSERT_FALSE(base::PathExists(full_path));
722 737
723 const char kData[] = "hello"; 738 const char kData[] = "hello";
724 const int kDataLength = static_cast<int>(arraysize(kData) - 1); 739 const int kDataLength = static_cast<int>(arraysize(kData) - 1);
725 ASSERT_EQ(kDataLength, base::WriteFile(full_path, kData, kDataLength)); 740 ASSERT_EQ(kDataLength, base::WriteFile(full_path, kData, kDataLength));
726 // The file that we created here should stick around when the BaseFile is 741 // The file that we created here should stick around when the BaseFile is
727 // destroyed during TearDown. 742 // destroyed during TearDown.
728 expect_file_survives_ = true; 743 expect_file_survives_ = true;
729 } 744 }
730 745
746 // Test that a it is ok to initialize a shared file with offset larger than the
747 // file size.
748 TEST_F(BaseFileTest, InitializeSharedFileWithOffsetLargerThanFileSize) {
749 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
750 std::string contents = kTestData1;
751 ASSERT_EQ(static_cast<int>(contents.size()),
752 base::WriteFile(file_path, contents.data(), contents.size()));
753
754 std::string empty_data = "\0\0\0\0\0";
755 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
756 base_file_->Initialize(file_path, base::FilePath(), base::File(),
757 contents.size() + empty_data.size(),
758 std::string(),
759 std::unique_ptr<crypto::SecureHash>(),
760 BaseFile::SHARED));
761 set_expected_data(kTestData1 + empty_data);
762 ASSERT_TRUE(WriteDataToFile(kTestData2));
763 EXPECT_EQ(kTestDataLength2, base_file_->bytes_so_far());
764 base_file_->Finish();
765 }
766
767 // Test that multiple writers can share the same file and write data to it.
768 TEST_F(BaseFileTest, MultipleWriters) {
769 base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
770 std::string contents = kTestData1;
771 ASSERT_EQ(static_cast<int>(contents.size()),
772 base::WriteFile(file_path, contents.data(), contents.size()));
773
774 // Create another file.
775 BaseFile second_file((net::NetLogWithSource()));
776 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
777 second_file.Initialize(file_path, base::FilePath(), base::File(),
778 contents.size(), std::string(),
779 std::unique_ptr<crypto::SecureHash>(),
780 BaseFile::SHARED));
781
782 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
xingliu 2017/02/15 19:13:20 In this way, each parallel download worker class w
qinmin 2017/02/15 20:00:43 An alternative is to provide a write(int64_t offs
xingliu 2017/02/15 20:43:57 Yeah, make sense, we can reuse the meta data with
783 base_file_->Initialize(file_path, base::FilePath(), base::File(),
784 contents.size() + kTestDataLength2,
785 std::string(),
786 std::unique_ptr<crypto::SecureHash>(),
787 BaseFile::SHARED));
788
789 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
790 second_file.WriteDataToFile(kTestData2, kTestDataLength2));
791 EXPECT_EQ(kTestDataLength2, second_file.bytes_so_far());
792
793 set_expected_data(contents + kTestData2);
794 ASSERT_TRUE(WriteDataToFile(kTestData4));
795 base_file_->Finish();
796 second_file.Detach();
797 }
798
731 } // namespace content 799 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698