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

Unified Diff: content/browser/download/base_file_unittest.cc

Issue 8404049: Added member data to classes to support download resumption. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merged with trunk Created 9 years 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
« no previous file with comments | « content/browser/download/base_file.cc ('k') | content/browser/download/download_create_info.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 030a635324abb210e79020ea36b249d36a2f04f6..911af194bba2a253d23d35d11eb9205c96eaf95a 100644
--- a/content/browser/download/base_file_unittest.cc
+++ b/content/browser/download/base_file_unittest.cc
@@ -11,6 +11,7 @@
#include "base/string_number_conversions.h"
#include "base/test/test_file_util.h"
#include "content/browser/browser_thread_impl.h"
+#include "crypto/secure_hash.h"
#include "net/base/file_stream.h"
#include "net/base/mock_file_stream.h"
#include "net/base/net_errors.h"
@@ -37,6 +38,9 @@ const base::TimeDelta kElapsedTimeDelta = base::TimeDelta::FromSeconds(
class BaseFileTest : public testing::Test {
public:
+ static const size_t kSha256HashLen = 32;
+ static const unsigned char kEmptySha256Hash[kSha256HashLen];
+
BaseFileTest()
: expect_file_survives_(false),
expect_in_progress_(true),
@@ -45,9 +49,10 @@ class BaseFileTest : public testing::Test {
}
virtual void SetUp() {
+ ResetHash();
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
base_file_.reset(
- new BaseFile(FilePath(), GURL(), GURL(), 0, file_stream_));
+ new BaseFile(FilePath(), GURL(), GURL(), 0, false, "", file_stream_));
}
virtual void TearDown() {
@@ -73,6 +78,28 @@ class BaseFileTest : public testing::Test {
EXPECT_EQ(expect_file_survives_, file_util::PathExists(full_path));
}
+ void ResetHash() {
+ secure_hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256));
+ memcpy(sha256_hash_, kEmptySha256Hash, kSha256HashLen);
+ }
+
+ void UpdateHash(const char* data, size_t length) {
+ secure_hash_->Update(data, length);
+ }
+
+ std::string GetFinalHash() {
+ std::string hash;
+ secure_hash_->Finish(sha256_hash_, kSha256HashLen);
+ hash.assign(reinterpret_cast<const char*>(sha256_hash_),
+ sizeof(sha256_hash_));
+ return hash;
+ }
+
+ void MakeFileWithHash() {
+ base_file_.reset(
+ new BaseFile(FilePath(), GURL(), GURL(), 0, true, "", file_stream_));
+ }
+
bool OpenMockFileStream() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
@@ -121,9 +148,9 @@ class BaseFileTest : public testing::Test {
static FilePath CreateTestFile() {
FilePath file_name;
linked_ptr<net::FileStream> dummy_file_stream;
- BaseFile file(FilePath(), GURL(), GURL(), 0, dummy_file_stream);
+ BaseFile file(FilePath(), GURL(), GURL(), 0, false, "", dummy_file_stream);
- EXPECT_EQ(net::OK, file.Initialize(false));
+ EXPECT_EQ(net::OK, file.Initialize());
file_name = file.full_path();
EXPECT_NE(FilePath::StringType(), file_name.value());
@@ -139,8 +166,9 @@ class BaseFileTest : public testing::Test {
static void CreateFileWithName(const FilePath& file_name) {
EXPECT_NE(FilePath::StringType(), file_name.value());
linked_ptr<net::FileStream> dummy_file_stream;
- BaseFile duplicate_file(file_name, GURL(), GURL(), 0, dummy_file_stream);
- EXPECT_EQ(net::OK, duplicate_file.Initialize(false));
+ BaseFile duplicate_file(
+ file_name, GURL(), GURL(), 0, false, "", dummy_file_stream);
+ EXPECT_EQ(net::OK, duplicate_file.Initialize());
// Write something into it.
duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4);
// Detach the file so it isn't deleted on destruction of |duplicate_file|.
@@ -173,6 +201,11 @@ class BaseFileTest : public testing::Test {
// Expect the file to be in progress.
bool expect_in_progress_;
+ // Hash calculator.
+ scoped_ptr<crypto::SecureHash> secure_hash_;
+
+ unsigned char sha256_hash_[kSha256HashLen];
+
private:
// Keep track of what data should be saved to the disk file.
std::string expected_data_;
@@ -183,6 +216,9 @@ class BaseFileTest : public testing::Test {
BrowserThreadImpl file_thread_;
};
+// This will initialize the entire array to zero.
+const unsigned char BaseFileTest::kEmptySha256Hash[] = { 0 };
+
// Test the most basic scenario: just create the object and do a sanity check
// on all its accessors. This is actually a case that rarely happens
// in production, where we would at least Initialize it.
@@ -192,7 +228,7 @@ TEST_F(BaseFileTest, CreateDestroy) {
// Cancel the download explicitly.
TEST_F(BaseFileTest, Cancel) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
EXPECT_TRUE(file_util::PathExists(base_file_->full_path()));
base_file_->Cancel();
EXPECT_FALSE(file_util::PathExists(base_file_->full_path()));
@@ -202,7 +238,7 @@ TEST_F(BaseFileTest, Cancel) {
// Write data to the file and detach it, so it doesn't get deleted
// automatically when base_file_ is destructed.
TEST_F(BaseFileTest, WriteAndDetach) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
base_file_->Finish();
base_file_->Detach();
@@ -211,14 +247,23 @@ TEST_F(BaseFileTest, WriteAndDetach) {
// Write data to the file and detach it, and calculate its sha256 hash.
TEST_F(BaseFileTest, WriteWithHashAndDetach) {
- ASSERT_EQ(net::OK, base_file_->Initialize(true));
+ // Calculate the final hash.
+ ResetHash();
+ UpdateHash(kTestData1, kTestDataLength1);
+ std::string expected_hash = GetFinalHash();
+ std::string expected_hash_hex =
+ base::HexEncode(expected_hash.data(), expected_hash.size());
+
+ MakeFileWithHash();
+ ASSERT_EQ(net::OK, base_file_->Initialize());
ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
base_file_->Finish();
std::string hash;
- base_file_->GetSha256Hash(&hash);
+ base_file_->GetHash(&hash);
EXPECT_EQ("0B2D3F3F7943AD64B860DF94D05CB56A8A97C6EC5768B5B70B930C5AA7FA9ADE",
- base::HexEncode(hash.data(), hash.size()));
+ expected_hash_hex);
+ EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size()));
base_file_->Detach();
expect_file_survives_ = true;
@@ -226,7 +271,7 @@ TEST_F(BaseFileTest, WriteWithHashAndDetach) {
// Rename the file after writing to it, then detach.
TEST_F(BaseFileTest, WriteThenRenameAndDetach) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
FilePath initial_path(base_file_->full_path());
EXPECT_TRUE(file_util::PathExists(initial_path));
@@ -246,54 +291,118 @@ TEST_F(BaseFileTest, WriteThenRenameAndDetach) {
// Write data to the file once.
TEST_F(BaseFileTest, SingleWrite) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
base_file_->Finish();
}
// Write data to the file multiple times.
TEST_F(BaseFileTest, MultipleWrites) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
ASSERT_EQ(net::OK, AppendDataToFile(kTestData2));
ASSERT_EQ(net::OK, AppendDataToFile(kTestData3));
std::string hash;
- EXPECT_FALSE(base_file_->GetSha256Hash(&hash));
+ EXPECT_FALSE(base_file_->GetHash(&hash));
base_file_->Finish();
}
// Write data to the file once and calculate its sha256 hash.
TEST_F(BaseFileTest, SingleWriteWithHash) {
- ASSERT_EQ(net::OK, base_file_->Initialize(true));
+ // Calculate the final hash.
+ ResetHash();
+ UpdateHash(kTestData1, kTestDataLength1);
+ std::string expected_hash = GetFinalHash();
+ std::string expected_hash_hex =
+ base::HexEncode(expected_hash.data(), expected_hash.size());
+
+ MakeFileWithHash();
+ ASSERT_EQ(net::OK, base_file_->Initialize());
+ // Can get partial hash states before Finish() is called.
+ EXPECT_STRNE(std::string().c_str(), base_file_->GetHashState().c_str());
ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
+ EXPECT_STRNE(std::string().c_str(), base_file_->GetHashState().c_str());
base_file_->Finish();
std::string hash;
- base_file_->GetSha256Hash(&hash);
- EXPECT_EQ("0B2D3F3F7943AD64B860DF94D05CB56A8A97C6EC5768B5B70B930C5AA7FA9ADE",
- base::HexEncode(hash.data(), hash.size()));
+ base_file_->GetHash(&hash);
+ EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size()));
}
// Write data to the file multiple times and calculate its sha256 hash.
TEST_F(BaseFileTest, MultipleWritesWithHash) {
- std::string hash;
+ // Calculate the final hash.
+ ResetHash();
+ UpdateHash(kTestData1, kTestDataLength1);
+ UpdateHash(kTestData2, kTestDataLength2);
+ UpdateHash(kTestData3, kTestDataLength3);
+ std::string expected_hash = GetFinalHash();
+ std::string expected_hash_hex =
+ base::HexEncode(expected_hash.data(), expected_hash.size());
- ASSERT_EQ(net::OK, base_file_->Initialize(true));
+ std::string hash;
+ MakeFileWithHash();
+ ASSERT_EQ(net::OK, base_file_->Initialize());
ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
ASSERT_EQ(net::OK, AppendDataToFile(kTestData2));
ASSERT_EQ(net::OK, AppendDataToFile(kTestData3));
- // no hash before Finish() is called either.
- EXPECT_FALSE(base_file_->GetSha256Hash(&hash));
+ // No hash before Finish() is called.
+ EXPECT_FALSE(base_file_->GetHash(&hash));
base_file_->Finish();
- EXPECT_TRUE(base_file_->GetSha256Hash(&hash));
+ EXPECT_TRUE(base_file_->GetHash(&hash));
EXPECT_EQ("CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8",
- base::HexEncode(hash.data(), hash.size()));
+ expected_hash_hex);
+ EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size()));
+}
+
+// Write data to the file multiple times, interrupt it, and continue using
+// another file. Calculate the resulting combined sha256 hash.
+TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) {
+ // Calculate the final hash.
+ ResetHash();
+ UpdateHash(kTestData1, kTestDataLength1);
+ UpdateHash(kTestData2, kTestDataLength2);
+ UpdateHash(kTestData3, kTestDataLength3);
+ std::string expected_hash = GetFinalHash();
+ std::string expected_hash_hex =
+ base::HexEncode(expected_hash.data(), expected_hash.size());
+
+ MakeFileWithHash();
+ ASSERT_EQ(net::OK, base_file_->Initialize());
+ // Write some data
+ ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
+ ASSERT_EQ(net::OK, AppendDataToFile(kTestData2));
+ // Get the hash state and file name.
+ std::string hash_state;
+ hash_state = base_file_->GetHashState();
+ // Finish the file.
+ base_file_->Finish();
+
+ // Create another file
+ linked_ptr<net::FileStream> second_stream;
+ BaseFile second_file(FilePath(),
+ GURL(),
+ GURL(),
+ base_file_->bytes_so_far(),
+ true,
+ hash_state,
+ second_stream);
+ ASSERT_EQ(net::OK, second_file.Initialize());
+ std::string data(kTestData3);
+ EXPECT_EQ(net::OK, second_file.AppendDataToFile(data.data(), data.size()));
+ second_file.Finish();
+
+ std::string hash;
+ EXPECT_TRUE(second_file.GetHash(&hash));
+ // This will fail until getting the hash state is supported in SecureHash.
+ EXPECT_STREQ(expected_hash_hex.c_str(),
+ base::HexEncode(hash.data(), hash.size()).c_str());
}
// Rename the file after all writes to it.
TEST_F(BaseFileTest, WriteThenRename) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
FilePath initial_path(base_file_->full_path());
EXPECT_TRUE(file_util::PathExists(initial_path));
@@ -311,7 +420,7 @@ TEST_F(BaseFileTest, WriteThenRename) {
// Rename the file while the download is still in progress.
TEST_F(BaseFileTest, RenameWhileInProgress) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
FilePath initial_path(base_file_->full_path());
EXPECT_TRUE(file_util::PathExists(initial_path));
@@ -334,14 +443,19 @@ TEST_F(BaseFileTest, RenameWhileInProgress) {
TEST_F(BaseFileTest, MultipleWritesWithError) {
ASSERT_TRUE(OpenMockFileStream());
base_file_.reset(new BaseFile(mock_file_stream_->get_path(),
- GURL(), GURL(), 0, mock_file_stream_));
- EXPECT_EQ(net::OK, base_file_->Initialize(false));
+ GURL(),
+ GURL(),
+ 0,
+ false,
+ "",
+ mock_file_stream_));
+ EXPECT_EQ(net::OK, base_file_->Initialize());
ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
ASSERT_EQ(net::OK, AppendDataToFile(kTestData2));
ForceError(net::ERR_ACCESS_DENIED);
ASSERT_NE(net::OK, AppendDataToFile(kTestData3));
std::string hash;
- EXPECT_FALSE(base_file_->GetSha256Hash(&hash));
+ EXPECT_FALSE(base_file_->GetHash(&hash));
base_file_->Finish();
}
@@ -355,7 +469,7 @@ TEST_F(BaseFileTest, UninitializedFile) {
// Overwrite base_file_ with another file with the same name and
// non-zero contents, and make sure the last file to close 'wins'.
TEST_F(BaseFileTest, DuplicateBaseFile) {
- EXPECT_EQ(net::OK, base_file_->Initialize(false));
+ EXPECT_EQ(net::OK, base_file_->Initialize());
// Create another |BaseFile| referring to the file that |base_file_| owns.
CreateFileWithName(base_file_->full_path());
@@ -372,11 +486,15 @@ TEST_F(BaseFileTest, AppendToBaseFile) {
set_expected_data(kTestData4);
// Use the file we've just created.
- base_file_.reset(
- new BaseFile(existing_file_name, GURL(), GURL(), kTestDataLength4,
- file_stream_));
+ base_file_.reset(new BaseFile(existing_file_name,
+ GURL(),
+ GURL(),
+ kTestDataLength4,
+ false,
+ "",
+ file_stream_));
- EXPECT_EQ(net::OK, base_file_->Initialize(false));
+ EXPECT_EQ(net::OK, base_file_->Initialize());
const FilePath file_name = base_file_->full_path();
EXPECT_NE(FilePath::StringType(), file_name.value());
@@ -398,12 +516,17 @@ TEST_F(BaseFileTest, ReadonlyBaseFile) {
EXPECT_TRUE(file_util::MakeFileUnwritable(readonly_file_name));
// Try to overwrite it.
- base_file_.reset(
- new BaseFile(readonly_file_name, GURL(), GURL(), 0, file_stream_));
+ base_file_.reset(new BaseFile(readonly_file_name,
+ GURL(),
+ GURL(),
+ 0,
+ false,
+ "",
+ file_stream_));
expect_in_progress_ = false;
- int init_error = base_file_->Initialize(false);
+ int init_error = base_file_->Initialize();
DVLOG(1) << " init_error = " << init_error;
EXPECT_NE(net::OK, init_error);
@@ -418,17 +541,17 @@ TEST_F(BaseFileTest, ReadonlyBaseFile) {
expect_file_survives_ = true;
}
-TEST_F(BaseFileTest, IsEmptySha256Hash) {
+TEST_F(BaseFileTest, IsEmptyHash) {
std::string empty(BaseFile::kSha256HashLen, '\x00');
- EXPECT_TRUE(BaseFile::IsEmptySha256Hash(empty));
+ EXPECT_TRUE(BaseFile::IsEmptyHash(empty));
std::string not_empty(BaseFile::kSha256HashLen, '\x01');
- EXPECT_FALSE(BaseFile::IsEmptySha256Hash(not_empty));
- EXPECT_FALSE(BaseFile::IsEmptySha256Hash(""));
+ EXPECT_FALSE(BaseFile::IsEmptyHash(not_empty));
+ EXPECT_FALSE(BaseFile::IsEmptyHash(""));
}
// Test that calculating speed after no writes.
TEST_F(BaseFileTest, SpeedWithoutWrite) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
base::TimeTicks current = StartTick() + kElapsedTimeDelta;
ASSERT_EQ(0, CurrentSpeedAtTime(current));
base_file_->Finish();
@@ -436,7 +559,7 @@ TEST_F(BaseFileTest, SpeedWithoutWrite) {
// Test that calculating speed after a single write.
TEST_F(BaseFileTest, SpeedAfterSingleWrite) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
base::TimeTicks current = StartTick() + kElapsedTimeDelta;
int64 expected_speed = kTestDataLength1 / kElapsedTimeSeconds;
@@ -446,7 +569,7 @@ TEST_F(BaseFileTest, SpeedAfterSingleWrite) {
// Test that calculating speed after a multiple writes.
TEST_F(BaseFileTest, SpeedAfterMultipleWrite) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
ASSERT_EQ(net::OK, AppendDataToFile(kTestData2));
ASSERT_EQ(net::OK, AppendDataToFile(kTestData3));
@@ -460,7 +583,7 @@ TEST_F(BaseFileTest, SpeedAfterMultipleWrite) {
// Test that calculating speed after no delay - should not divide by 0.
TEST_F(BaseFileTest, SpeedAfterNoElapsedTime) {
- ASSERT_EQ(net::OK, base_file_->Initialize(false));
+ ASSERT_EQ(net::OK, base_file_->Initialize());
ASSERT_EQ(net::OK, AppendDataToFile(kTestData1));
ASSERT_EQ(0, CurrentSpeedAtTime(StartTick()));
base_file_->Finish();
« no previous file with comments | « content/browser/download/base_file.cc ('k') | content/browser/download/download_create_info.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698