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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/download/base_file_unittest.cc
diff --git a/content/browser/download/base_file_unittest.cc b/content/browser/download/base_file_unittest.cc
index 6b07d8d1315cc0b3fa6f58abba4f35f515dffcf8..ef3f7f554d89e1f32e32897234b4a7dae1cbf476 100644
--- a/content/browser/download/base_file_unittest.cc
+++ b/content/browser/download/base_file_unittest.cc
@@ -66,7 +66,7 @@ class BaseFileTest : public testing::Test {
EXPECT_FALSE(base_file_->in_progress());
if (!expected_error_) {
EXPECT_EQ(static_cast<int64_t>(expected_data_.size()),
- base_file_->bytes_so_far());
+ base_file_->offset());
}
base::FilePath full_path = base_file_->full_path();
@@ -88,15 +88,15 @@ class BaseFileTest : public testing::Test {
bool InitializeFile() {
DownloadInterruptReason result = base_file_->Initialize(
base::FilePath(), temp_dir_.GetPath(), base::File(), 0, std::string(),
- std::unique_ptr<crypto::SecureHash>());
+ std::unique_ptr<crypto::SecureHash>(), BaseFile::EXCLUSIVE);
EXPECT_EQ(expected_error_, result);
return result == DOWNLOAD_INTERRUPT_REASON_NONE;
}
- bool AppendDataToFile(const std::string& data) {
+ bool WriteDataToFile(const std::string& data) {
EXPECT_EQ(expect_in_progress_, base_file_->in_progress());
DownloadInterruptReason result =
- base_file_->AppendDataToFile(data.data(), data.size());
+ base_file_->WriteDataToFile(data.data(), data.size());
if (result == DOWNLOAD_INTERRUPT_REASON_NONE)
EXPECT_TRUE(expect_in_progress_) << " result = " << result;
@@ -105,7 +105,7 @@ class BaseFileTest : public testing::Test {
expected_data_ += data;
if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) {
EXPECT_EQ(static_cast<int64_t>(expected_data_.size()),
- base_file_->bytes_so_far());
+ base_file_->offset());
}
}
return result == DOWNLOAD_INTERRUPT_REASON_NONE;
@@ -122,12 +122,13 @@ class BaseFileTest : public testing::Test {
EXPECT_EQ(
DOWNLOAD_INTERRUPT_REASON_NONE,
file.Initialize(base::FilePath(), temp_dir_.GetPath(), base::File(), 0,
- std::string(), std::unique_ptr<crypto::SecureHash>()));
+ std::string(), std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
file_name = file.full_path();
EXPECT_NE(base::FilePath::StringType(), file_name.value());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
- file.AppendDataToFile(kTestData4, kTestDataLength4));
+ file.WriteDataToFile(kTestData4, kTestDataLength4));
// Keep the file from getting deleted when existing_file_name is deleted.
file.Detach();
@@ -142,9 +143,10 @@ class BaseFileTest : public testing::Test {
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
duplicate_file.Initialize(file_name, temp_dir_.GetPath(),
base::File(), 0, std::string(),
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
// Write something into it.
- duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4);
+ duplicate_file.WriteDataToFile(kTestData4, kTestDataLength4);
// Detach the file so it isn't deleted on destruction of |duplicate_file|.
duplicate_file.Detach();
}
@@ -222,7 +224,7 @@ TEST_F(BaseFileTest, Cancel) {
// automatically when base_file_ is destructed.
TEST_F(BaseFileTest, WriteAndDetach) {
ASSERT_TRUE(InitializeFile());
- ASSERT_TRUE(AppendDataToFile(kTestData1));
+ ASSERT_TRUE(WriteDataToFile(kTestData1));
base_file_->Finish();
base_file_->Detach();
expect_file_survives_ = true;
@@ -231,7 +233,7 @@ TEST_F(BaseFileTest, WriteAndDetach) {
// Write data to the file and detach it, and calculate its sha256 hash.
TEST_F(BaseFileTest, WriteWithHashAndDetach) {
ASSERT_TRUE(InitializeFile());
- ASSERT_TRUE(AppendDataToFile(kTestData1));
+ ASSERT_TRUE(WriteDataToFile(kTestData1));
ExpectHashValue(kHashOfTestData1, base_file_->Finish());
base_file_->Detach();
expect_file_survives_ = true;
@@ -246,7 +248,7 @@ TEST_F(BaseFileTest, WriteThenRenameAndDetach) {
base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile"));
EXPECT_FALSE(base::PathExists(new_path));
- ASSERT_TRUE(AppendDataToFile(kTestData1));
+ ASSERT_TRUE(WriteDataToFile(kTestData1));
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
EXPECT_FALSE(base::PathExists(initial_path));
@@ -260,16 +262,16 @@ TEST_F(BaseFileTest, WriteThenRenameAndDetach) {
// Write data to the file once.
TEST_F(BaseFileTest, SingleWrite) {
ASSERT_TRUE(InitializeFile());
- ASSERT_TRUE(AppendDataToFile(kTestData1));
+ ASSERT_TRUE(WriteDataToFile(kTestData1));
ExpectHashValue(kHashOfTestData1, base_file_->Finish());
}
// Write data to the file multiple times.
TEST_F(BaseFileTest, MultipleWrites) {
ASSERT_TRUE(InitializeFile());
- ASSERT_TRUE(AppendDataToFile(kTestData1));
- ASSERT_TRUE(AppendDataToFile(kTestData2));
- ASSERT_TRUE(AppendDataToFile(kTestData3));
+ ASSERT_TRUE(WriteDataToFile(kTestData1));
+ ASSERT_TRUE(WriteDataToFile(kTestData2));
+ ASSERT_TRUE(WriteDataToFile(kTestData3));
ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}
@@ -278,8 +280,8 @@ TEST_F(BaseFileTest, MultipleWrites) {
TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) {
ASSERT_TRUE(InitializeFile());
// Write some data
- ASSERT_TRUE(AppendDataToFile(kTestData1));
- ASSERT_TRUE(AppendDataToFile(kTestData2));
+ ASSERT_TRUE(WriteDataToFile(kTestData1));
+ ASSERT_TRUE(WriteDataToFile(kTestData2));
// Get the hash state and file name.
std::unique_ptr<crypto::SecureHash> hash_state = base_file_->Finish();
@@ -296,10 +298,11 @@ TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) {
base::File(),
base_file_->bytes_so_far(),
std::string(),
- std::move(hash_state)));
+ std::move(hash_state),
+ BaseFile::EXCLUSIVE));
std::string data(kTestData3);
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
- second_file.AppendDataToFile(data.data(), data.size()));
+ second_file.WriteDataToFile(data.data(), data.size()));
ExpectHashValue(kHashOfTestData1To3, second_file.Finish());
}
@@ -312,7 +315,7 @@ TEST_F(BaseFileTest, WriteThenRename) {
base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile"));
EXPECT_FALSE(base::PathExists(new_path));
- ASSERT_TRUE(AppendDataToFile(kTestData1));
+ ASSERT_TRUE(WriteDataToFile(kTestData1));
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
base_file_->Rename(new_path));
@@ -331,15 +334,15 @@ TEST_F(BaseFileTest, RenameWhileInProgress) {
base::FilePath new_path(temp_dir_.GetPath().AppendASCII("NewFile"));
EXPECT_FALSE(base::PathExists(new_path));
- ASSERT_TRUE(AppendDataToFile(kTestData1));
+ ASSERT_TRUE(WriteDataToFile(kTestData1));
EXPECT_TRUE(base_file_->in_progress());
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
EXPECT_FALSE(base::PathExists(initial_path));
EXPECT_TRUE(base::PathExists(new_path));
- ASSERT_TRUE(AppendDataToFile(kTestData2));
- ASSERT_TRUE(AppendDataToFile(kTestData3));
+ ASSERT_TRUE(WriteDataToFile(kTestData2));
+ ASSERT_TRUE(WriteDataToFile(kTestData3));
ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}
@@ -377,7 +380,7 @@ TEST_F(BaseFileTest, RenameWithErrorInProgress) {
EXPECT_FALSE(base::PathExists(new_path));
// Write some data to start with.
- ASSERT_TRUE(AppendDataToFile(kTestData1));
+ ASSERT_TRUE(WriteDataToFile(kTestData1));
ASSERT_TRUE(base_file_->in_progress());
base::FilePath old_path = base_file_->full_path();
@@ -390,7 +393,7 @@ TEST_F(BaseFileTest, RenameWithErrorInProgress) {
// The file should still be open and we should be able to continue writing
// to it.
ASSERT_TRUE(base_file_->in_progress());
- ASSERT_TRUE(AppendDataToFile(kTestData2));
+ ASSERT_TRUE(WriteDataToFile(kTestData2));
ASSERT_EQ(old_path.value(), base_file_->full_path().value());
// Try to rename again, just for kicks. It should still fail.
@@ -401,7 +404,7 @@ TEST_F(BaseFileTest, RenameWithErrorInProgress) {
// rename the file.
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path));
ASSERT_EQ(new_path.value(), base_file_->full_path().value());
- ASSERT_TRUE(AppendDataToFile(kTestData3));
+ ASSERT_TRUE(WriteDataToFile(kTestData3));
ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}
@@ -418,13 +421,14 @@ TEST_F(BaseFileTest, WriteWithError) {
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
base_file_->Initialize(path, base::FilePath(), std::move(file), 0,
std::string(),
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
#if defined(OS_WIN)
set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
#elif defined (OS_POSIX)
set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
#endif
- ASSERT_FALSE(AppendDataToFile(kTestData1));
+ ASSERT_FALSE(WriteDataToFile(kTestData1));
base_file_->Finish();
}
@@ -432,7 +436,7 @@ TEST_F(BaseFileTest, WriteWithError) {
TEST_F(BaseFileTest, UninitializedFile) {
expect_in_progress_ = false;
set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
- EXPECT_FALSE(AppendDataToFile(kTestData1));
+ EXPECT_FALSE(WriteDataToFile(kTestData1));
}
// Create two |BaseFile|s with the same file, and attempt to write to both.
@@ -444,7 +448,7 @@ TEST_F(BaseFileTest, DuplicateBaseFile) {
// Create another |BaseFile| referring to the file that |base_file_| owns.
CreateFileWithName(base_file_->full_path());
- ASSERT_TRUE(AppendDataToFile(kTestData1));
+ ASSERT_TRUE(WriteDataToFile(kTestData1));
base_file_->Finish();
}
@@ -460,13 +464,14 @@ TEST_F(BaseFileTest, AppendToBaseFile) {
DOWNLOAD_INTERRUPT_REASON_NONE,
base_file_->Initialize(existing_file_name, base::FilePath(), base::File(),
kTestDataLength4, std::string(),
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
const base::FilePath file_name = base_file_->full_path();
EXPECT_NE(base::FilePath::StringType(), file_name.value());
// Write into the file.
- EXPECT_TRUE(AppendDataToFile(kTestData1));
+ EXPECT_TRUE(WriteDataToFile(kTestData1));
base_file_->Finish();
base_file_->Detach();
@@ -489,7 +494,8 @@ TEST_F(BaseFileTest, ReadonlyBaseFile) {
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED,
base_file_->Initialize(readonly_file_name, base::FilePath(),
base::File(), 0, std::string(),
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
expect_in_progress_ = false;
@@ -498,7 +504,7 @@ TEST_F(BaseFileTest, ReadonlyBaseFile) {
// Write into the file.
set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
- EXPECT_FALSE(AppendDataToFile(kTestData1));
+ EXPECT_FALSE(WriteDataToFile(kTestData1));
base_file_->Finish();
base_file_->Detach();
@@ -517,10 +523,11 @@ TEST_F(BaseFileTest, ExistingBaseFileKnownHash) {
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
base_file_->Initialize(file_path, base::FilePath(), base::File(),
kTestDataLength1, hash_so_far,
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
set_expected_data(kTestData1);
- ASSERT_TRUE(AppendDataToFile(kTestData2));
- ASSERT_TRUE(AppendDataToFile(kTestData3));
+ ASSERT_TRUE(WriteDataToFile(kTestData2));
+ ASSERT_TRUE(WriteDataToFile(kTestData3));
ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}
@@ -534,10 +541,11 @@ TEST_F(BaseFileTest, ExistingBaseFileUnknownHash) {
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
base_file_->Initialize(file_path, base::FilePath(), base::File(),
kTestDataLength1, std::string(),
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
set_expected_data(kTestData1);
- ASSERT_TRUE(AppendDataToFile(kTestData2));
- ASSERT_TRUE(AppendDataToFile(kTestData3));
+ ASSERT_TRUE(WriteDataToFile(kTestData2));
+ ASSERT_TRUE(WriteDataToFile(kTestData3));
ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}
@@ -552,7 +560,8 @@ TEST_F(BaseFileTest, ExistingBaseFileIncorrectHash) {
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH,
base_file_->Initialize(file_path, base::FilePath(), base::File(),
kTestDataLength2, hash_so_far,
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH);
}
@@ -580,9 +589,10 @@ TEST_F(BaseFileTest, ExistingBaseFileLargeSizeKnownHash) {
big_buffer.size(),
std::string(std::begin(kExpectedPartialHash),
std::end(kExpectedPartialHash)),
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
set_expected_data(big_buffer); // Contents of the file on Open.
- ASSERT_TRUE(AppendDataToFile(big_buffer));
+ ASSERT_TRUE(WriteDataToFile(big_buffer));
ExpectHashValue(kExpectedFullHash, base_file_->Finish());
}
@@ -604,7 +614,8 @@ TEST_F(BaseFileTest, ExistingBaseFileLargeSizeIncorrectHash) {
big_buffer.size(),
std::string(std::begin(kExpectedPartialHash),
std::end(kExpectedPartialHash)),
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH);
}
@@ -617,7 +628,8 @@ TEST_F(BaseFileTest, ExistingBaseFileTooShort) {
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT,
base_file_->Initialize(file_path, base::FilePath(), base::File(),
kTestDataLength1 + 1, std::string(),
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT);
}
@@ -635,10 +647,11 @@ TEST_F(BaseFileTest, ExistingBaseFileKnownHashTooLong) {
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
base_file_->Initialize(file_path, base::FilePath(), base::File(),
kTestDataLength1, hash_so_far,
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
set_expected_data(kTestData1); // Our starting position.
- ASSERT_TRUE(AppendDataToFile(kTestData2));
- ASSERT_TRUE(AppendDataToFile(kTestData3));
+ ASSERT_TRUE(WriteDataToFile(kTestData2));
+ ASSERT_TRUE(WriteDataToFile(kTestData3));
ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}
@@ -655,10 +668,11 @@ TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLong) {
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
base_file_->Initialize(file_path, base::FilePath(), base::File(),
kTestDataLength1, std::string(),
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
set_expected_data(kTestData1);
- ASSERT_TRUE(AppendDataToFile(kTestData2));
- ASSERT_TRUE(AppendDataToFile(kTestData3));
+ ASSERT_TRUE(WriteDataToFile(kTestData2));
+ ASSERT_TRUE(WriteDataToFile(kTestData3));
ExpectHashValue(kHashOfTestData1To3, base_file_->Finish());
}
@@ -678,12 +692,13 @@ TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLongForLargeFile) {
EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
base_file_->Initialize(file_path, base::FilePath(), base::File(),
kIntermediateSize, std::string(),
- std::unique_ptr<crypto::SecureHash>()));
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::EXCLUSIVE));
// The extra bytes should be stripped during Initialize().
contents.resize(kIntermediateSize, 'a');
set_expected_data(contents);
std::string new_data(kFileSize - kIntermediateSize, 'a');
- ASSERT_TRUE(AppendDataToFile(new_data));
+ ASSERT_TRUE(WriteDataToFile(new_data));
const uint8_t kExpectedHash[] = {
0x9b, 0xc1, 0xb2, 0xa2, 0x88, 0xb2, 0x6a, 0xf7, 0x25, 0x7a, 0x36,
0x27, 0x7a, 0xe3, 0x81, 0x6a, 0x7d, 0x4f, 0x16, 0xe8, 0x9c, 0x1e,
@@ -728,4 +743,57 @@ TEST_F(BaseFileTest, NoDoubleDeleteAfterCancel) {
expect_file_survives_ = true;
}
+// Test that a it is ok to initialize a shared file with offset larger than the
+// file size.
+TEST_F(BaseFileTest, InitializeSharedFileWithOffsetLargerThanFileSize) {
+ base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
+ std::string contents = kTestData1;
+ ASSERT_EQ(static_cast<int>(contents.size()),
+ base::WriteFile(file_path, contents.data(), contents.size()));
+
+ std::string empty_data = "\0\0\0\0\0";
+ EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
+ base_file_->Initialize(file_path, base::FilePath(), base::File(),
+ contents.size() + empty_data.size(),
+ std::string(),
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::SHARED));
+ set_expected_data(kTestData1 + empty_data);
+ ASSERT_TRUE(WriteDataToFile(kTestData2));
+ EXPECT_EQ(kTestDataLength2, base_file_->bytes_so_far());
+ base_file_->Finish();
+}
+
+// Test that multiple writers can share the same file and write data to it.
+TEST_F(BaseFileTest, MultipleWriters) {
+ base::FilePath file_path = temp_dir_.GetPath().AppendASCII("existing");
+ std::string contents = kTestData1;
+ ASSERT_EQ(static_cast<int>(contents.size()),
+ base::WriteFile(file_path, contents.data(), contents.size()));
+
+ // Create another file.
+ BaseFile second_file((net::NetLogWithSource()));
+ EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
+ second_file.Initialize(file_path, base::FilePath(), base::File(),
+ contents.size(), std::string(),
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::SHARED));
+
+ 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
+ base_file_->Initialize(file_path, base::FilePath(), base::File(),
+ contents.size() + kTestDataLength2,
+ std::string(),
+ std::unique_ptr<crypto::SecureHash>(),
+ BaseFile::SHARED));
+
+ EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE,
+ second_file.WriteDataToFile(kTestData2, kTestDataLength2));
+ EXPECT_EQ(kTestDataLength2, second_file.bytes_so_far());
+
+ set_expected_data(contents + kTestData2);
+ ASSERT_TRUE(WriteDataToFile(kTestData4));
+ base_file_->Finish();
+ second_file.Detach();
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698