| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 | 25 |
| 26 namespace content { | 26 namespace content { |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 const char kTestData1[] = "Let's write some data to the file!\n"; | 29 const char kTestData1[] = "Let's write some data to the file!\n"; |
| 30 const char kTestData2[] = "Writing more data.\n"; | 30 const char kTestData2[] = "Writing more data.\n"; |
| 31 const char kTestData3[] = "Final line."; | 31 const char kTestData3[] = "Final line."; |
| 32 const char kTestData4[] = "supercalifragilisticexpialidocious"; | 32 const char kTestData4[] = "supercalifragilisticexpialidocious"; |
| 33 const int kTestDataLength1 = arraysize(kTestData1) - 1; | 33 const int kTestDataLength1 = arraysize(kTestData1) - 1; |
| 34 const int kTestDataLength2 = arraysize(kTestData2) - 1; | 34 const int kTestDataLength2 = arraysize(kTestData2) - 1; |
| 35 const int kTestDataLength3 = arraysize(kTestData3) - 1; | |
| 36 const int kTestDataLength4 = arraysize(kTestData4) - 1; | 35 const int kTestDataLength4 = arraysize(kTestData4) - 1; |
| 37 const int kElapsedTimeSeconds = 5; | 36 const int kElapsedTimeSeconds = 5; |
| 38 const base::TimeDelta kElapsedTimeDelta = base::TimeDelta::FromSeconds( | 37 const base::TimeDelta kElapsedTimeDelta = base::TimeDelta::FromSeconds( |
| 39 kElapsedTimeSeconds); | 38 kElapsedTimeSeconds); |
| 40 | 39 |
| 40 // SHA-256 hash of kTestData1 (excluding terminating NUL). |
| 41 const uint8_t kHashOfTestData1[] = { |
| 42 0x0b, 0x2d, 0x3f, 0x3f, 0x79, 0x43, 0xad, 0x64, 0xb8, 0x60, 0xdf, |
| 43 0x94, 0xd0, 0x5c, 0xb5, 0x6a, 0x8a, 0x97, 0xc6, 0xec, 0x57, 0x68, |
| 44 0xb5, 0xb7, 0x0b, 0x93, 0x0c, 0x5a, 0xa7, 0xfa, 0x9a, 0xde}; |
| 45 |
| 46 // SHA-256 hash of kTestData1 ++ kTestData2 ++ kTestData3 (excluding terminating |
| 47 // NUL). |
| 48 const uint8_t kHashOfTestData1To3[] = { |
| 49 0xcb, 0xf6, 0x8b, 0xf1, 0x0f, 0x80, 0x03, 0xdb, 0x86, 0xb3, 0x13, |
| 50 0x43, 0xaf, 0xac, 0x8c, 0x71, 0x75, 0xbd, 0x03, 0xfb, 0x5f, 0xc9, |
| 51 0x05, 0x65, 0x0f, 0x8c, 0x80, 0xaf, 0x08, 0x74, 0x43, 0xa8}; |
| 52 |
| 41 } // namespace | 53 } // namespace |
| 42 | 54 |
| 43 class BaseFileTest : public testing::Test { | 55 class BaseFileTest : public testing::Test { |
| 44 public: | 56 public: |
| 45 static const unsigned char kEmptySha256Hash[crypto::kSHA256Length]; | 57 static const unsigned char kEmptySha256Hash[crypto::kSHA256Length]; |
| 46 | 58 |
| 47 BaseFileTest() | 59 BaseFileTest() |
| 48 : expect_file_survives_(false), | 60 : expect_file_survives_(false), |
| 49 expect_in_progress_(true), | 61 expect_in_progress_(true), |
| 50 expected_error_(DOWNLOAD_INTERRUPT_REASON_NONE), | 62 expected_error_(DOWNLOAD_INTERRUPT_REASON_NONE), |
| 51 file_thread_(BrowserThread::FILE, &message_loop_) { | 63 file_thread_(BrowserThread::FILE, &message_loop_) { |
| 52 } | 64 } |
| 53 | 65 |
| 54 void SetUp() override { | 66 void SetUp() override { |
| 55 ResetHash(); | |
| 56 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 67 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 57 base_file_.reset(new BaseFile(base::FilePath(), | 68 base_file_.reset(new BaseFile(net::BoundNetLog())); |
| 58 GURL(), | |
| 59 GURL(), | |
| 60 0, | |
| 61 false, | |
| 62 std::string(), | |
| 63 base::File(), | |
| 64 net::BoundNetLog())); | |
| 65 } | 69 } |
| 66 | 70 |
| 67 void TearDown() override { | 71 void TearDown() override { |
| 68 EXPECT_FALSE(base_file_->in_progress()); | 72 EXPECT_FALSE(base_file_->in_progress()); |
| 69 if (!expected_error_) { | 73 if (!expected_error_) { |
| 70 EXPECT_EQ(static_cast<int64_t>(expected_data_.size()), | 74 EXPECT_EQ(static_cast<int64_t>(expected_data_.size()), |
| 71 base_file_->bytes_so_far()); | 75 base_file_->bytes_so_far()); |
| 72 } | 76 } |
| 73 | 77 |
| 74 base::FilePath full_path = base_file_->full_path(); | 78 base::FilePath full_path = base_file_->full_path(); |
| 75 | 79 |
| 76 if (!expected_data_.empty() && !expected_error_) { | 80 if (!expected_data_.empty() && !expected_error_) { |
| 77 // Make sure the data has been properly written to disk. | 81 // Make sure the data has been properly written to disk. |
| 78 std::string disk_data; | 82 std::string disk_data; |
| 79 EXPECT_TRUE(base::ReadFileToString(full_path, &disk_data)); | 83 EXPECT_TRUE(base::ReadFileToString(full_path, &disk_data)); |
| 80 EXPECT_EQ(expected_data_, disk_data); | 84 EXPECT_EQ(expected_data_, disk_data); |
| 81 } | 85 } |
| 82 | 86 |
| 83 // Make sure the mock BrowserThread outlives the BaseFile to satisfy | 87 // Make sure the mock BrowserThread outlives the BaseFile to satisfy |
| 84 // thread checks inside it. | 88 // thread checks inside it. |
| 85 base_file_.reset(); | 89 base_file_.reset(); |
| 86 | 90 |
| 87 EXPECT_EQ(expect_file_survives_, base::PathExists(full_path)); | 91 EXPECT_EQ(expect_file_survives_, base::PathExists(full_path)); |
| 88 } | 92 } |
| 89 | 93 |
| 90 void ResetHash() { | |
| 91 secure_hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256)); | |
| 92 memcpy(sha256_hash_, kEmptySha256Hash, crypto::kSHA256Length); | |
| 93 } | |
| 94 | |
| 95 void UpdateHash(const char* data, size_t length) { | |
| 96 secure_hash_->Update(data, length); | |
| 97 } | |
| 98 | |
| 99 std::string GetFinalHash() { | |
| 100 std::string hash; | |
| 101 secure_hash_->Finish(sha256_hash_, crypto::kSHA256Length); | |
| 102 hash.assign(reinterpret_cast<const char*>(sha256_hash_), | |
| 103 sizeof(sha256_hash_)); | |
| 104 return hash; | |
| 105 } | |
| 106 | |
| 107 void MakeFileWithHash() { | |
| 108 base_file_.reset(new BaseFile(base::FilePath(), | |
| 109 GURL(), | |
| 110 GURL(), | |
| 111 0, | |
| 112 true, | |
| 113 std::string(), | |
| 114 base::File(), | |
| 115 net::BoundNetLog())); | |
| 116 } | |
| 117 | |
| 118 bool InitializeFile() { | 94 bool InitializeFile() { |
| 119 DownloadInterruptReason result = base_file_->Initialize(temp_dir_.path()); | 95 DownloadInterruptReason result = |
| 96 base_file_->Initialize(base::FilePath(), |
| 97 temp_dir_.path(), |
| 98 base::File(), |
| 99 0, |
| 100 std::string(), |
| 101 scoped_ptr<crypto::SecureHash>()); |
| 120 EXPECT_EQ(expected_error_, result); | 102 EXPECT_EQ(expected_error_, result); |
| 121 return result == DOWNLOAD_INTERRUPT_REASON_NONE; | 103 return result == DOWNLOAD_INTERRUPT_REASON_NONE; |
| 122 } | 104 } |
| 123 | 105 |
| 124 bool AppendDataToFile(const std::string& data) { | 106 bool AppendDataToFile(const std::string& data) { |
| 125 EXPECT_EQ(expect_in_progress_, base_file_->in_progress()); | 107 EXPECT_EQ(expect_in_progress_, base_file_->in_progress()); |
| 126 DownloadInterruptReason result = | 108 DownloadInterruptReason result = |
| 127 base_file_->AppendDataToFile(data.data(), data.size()); | 109 base_file_->AppendDataToFile(data.data(), data.size()); |
| 128 if (result == DOWNLOAD_INTERRUPT_REASON_NONE) | 110 if (result == DOWNLOAD_INTERRUPT_REASON_NONE) |
| 129 EXPECT_TRUE(expect_in_progress_) << " result = " << result; | 111 EXPECT_TRUE(expect_in_progress_) << " result = " << result; |
| 130 | 112 |
| 131 EXPECT_EQ(expected_error_, result); | 113 EXPECT_EQ(expected_error_, result); |
| 132 if (base_file_->in_progress()) { | 114 if (base_file_->in_progress()) { |
| 133 expected_data_ += data; | 115 expected_data_ += data; |
| 134 if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) { | 116 if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) { |
| 135 EXPECT_EQ(static_cast<int64_t>(expected_data_.size()), | 117 EXPECT_EQ(static_cast<int64_t>(expected_data_.size()), |
| 136 base_file_->bytes_so_far()); | 118 base_file_->bytes_so_far()); |
| 137 } | 119 } |
| 138 } | 120 } |
| 139 return result == DOWNLOAD_INTERRUPT_REASON_NONE; | 121 return result == DOWNLOAD_INTERRUPT_REASON_NONE; |
| 140 } | 122 } |
| 141 | 123 |
| 142 void set_expected_data(const std::string& data) { expected_data_ = data; } | 124 void set_expected_data(const std::string& data) { expected_data_ = data; } |
| 143 | 125 |
| 144 // Helper functions. | 126 // Helper functions. |
| 145 // Create a file. Returns the complete file path. | 127 // Create a file. Returns the complete file path. |
| 146 base::FilePath CreateTestFile() { | 128 base::FilePath CreateTestFile() { |
| 147 base::FilePath file_name; | 129 base::FilePath file_name; |
| 148 BaseFile file(base::FilePath(), | 130 BaseFile file((net::BoundNetLog())); |
| 149 GURL(), | |
| 150 GURL(), | |
| 151 0, | |
| 152 false, | |
| 153 std::string(), | |
| 154 base::File(), | |
| 155 net::BoundNetLog()); | |
| 156 | 131 |
| 157 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 132 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 158 file.Initialize(temp_dir_.path())); | 133 file.Initialize(base::FilePath(), |
| 134 temp_dir_.path(), |
| 135 base::File(), |
| 136 0, |
| 137 std::string(), |
| 138 scoped_ptr<crypto::SecureHash>())); |
| 159 file_name = file.full_path(); | 139 file_name = file.full_path(); |
| 160 EXPECT_NE(base::FilePath::StringType(), file_name.value()); | 140 EXPECT_NE(base::FilePath::StringType(), file_name.value()); |
| 161 | 141 |
| 162 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 142 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 163 file.AppendDataToFile(kTestData4, kTestDataLength4)); | 143 file.AppendDataToFile(kTestData4, kTestDataLength4)); |
| 164 | 144 |
| 165 // Keep the file from getting deleted when existing_file_name is deleted. | 145 // Keep the file from getting deleted when existing_file_name is deleted. |
| 166 file.Detach(); | 146 file.Detach(); |
| 167 | 147 |
| 168 return file_name; | 148 return file_name; |
| 169 } | 149 } |
| 170 | 150 |
| 171 // Create a file with the specified file name. | 151 // Create a file with the specified file name. |
| 172 void CreateFileWithName(const base::FilePath& file_name) { | 152 void CreateFileWithName(const base::FilePath& file_name) { |
| 173 EXPECT_NE(base::FilePath::StringType(), file_name.value()); | 153 EXPECT_NE(base::FilePath::StringType(), file_name.value()); |
| 174 BaseFile duplicate_file(file_name, | 154 BaseFile duplicate_file((net::BoundNetLog())); |
| 175 GURL(), | |
| 176 GURL(), | |
| 177 0, | |
| 178 false, | |
| 179 std::string(), | |
| 180 base::File(), | |
| 181 net::BoundNetLog()); | |
| 182 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 155 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 183 duplicate_file.Initialize(temp_dir_.path())); | 156 duplicate_file.Initialize(file_name, |
| 157 temp_dir_.path(), |
| 158 base::File(), |
| 159 0, |
| 160 std::string(), |
| 161 scoped_ptr<crypto::SecureHash>())); |
| 184 // Write something into it. | 162 // Write something into it. |
| 185 duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4); | 163 duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4); |
| 186 // Detach the file so it isn't deleted on destruction of |duplicate_file|. | 164 // Detach the file so it isn't deleted on destruction of |duplicate_file|. |
| 187 duplicate_file.Detach(); | 165 duplicate_file.Detach(); |
| 188 } | 166 } |
| 189 | 167 |
| 190 int64_t CurrentSpeedAtTime(base::TimeTicks current_time) { | 168 int64_t CurrentSpeedAtTime(base::TimeTicks current_time) { |
| 191 EXPECT_TRUE(base_file_.get()); | 169 EXPECT_TRUE(base_file_.get()); |
| 192 return base_file_->CurrentSpeedAtTime(current_time); | 170 return base_file_->CurrentSpeedAtTime(current_time); |
| 193 } | 171 } |
| 194 | 172 |
| 195 base::TimeTicks StartTick() { | 173 base::TimeTicks StartTick() { |
| 196 EXPECT_TRUE(base_file_.get()); | 174 EXPECT_TRUE(base_file_.get()); |
| 197 return base_file_->start_tick_; | 175 return base_file_->start_tick_; |
| 198 } | 176 } |
| 199 | 177 |
| 200 void set_expected_error(DownloadInterruptReason err) { | 178 void set_expected_error(DownloadInterruptReason err) { |
| 201 expected_error_ = err; | 179 expected_error_ = err; |
| 202 } | 180 } |
| 203 | 181 |
| 204 void ExpectPermissionError(DownloadInterruptReason err) { | 182 void ExpectPermissionError(DownloadInterruptReason err) { |
| 205 EXPECT_TRUE(err == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR || | 183 EXPECT_TRUE(err == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR || |
| 206 err == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED) | 184 err == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED) |
| 207 << "Interrupt reason = " << err; | 185 << "Interrupt reason = " << err; |
| 208 } | 186 } |
| 209 | 187 |
| 188 template <size_t SZ> |
| 189 static void ExpectHashValue(const uint8_t (&expected_hash)[SZ], |
| 190 scoped_ptr<crypto::SecureHash> hash_state) { |
| 191 std::vector<uint8_t> hash_value(hash_state->GetHashLength()); |
| 192 hash_state->Finish(&hash_value.front(), hash_value.size()); |
| 193 ASSERT_EQ(SZ, hash_value.size()); |
| 194 EXPECT_EQ(0, memcmp(expected_hash, &hash_value.front(), hash_value.size())); |
| 195 } |
| 196 |
| 210 protected: | 197 protected: |
| 211 // BaseClass instance we are testing. | 198 // BaseClass instance we are testing. |
| 212 scoped_ptr<BaseFile> base_file_; | 199 scoped_ptr<BaseFile> base_file_; |
| 213 | 200 |
| 214 // Temporary directory for renamed downloads. | 201 // Temporary directory for renamed downloads. |
| 215 base::ScopedTempDir temp_dir_; | 202 base::ScopedTempDir temp_dir_; |
| 216 | 203 |
| 217 // Expect the file to survive deletion of the BaseFile instance. | 204 // Expect the file to survive deletion of the BaseFile instance. |
| 218 bool expect_file_survives_; | 205 bool expect_file_survives_; |
| 219 | 206 |
| 220 // Expect the file to be in progress. | 207 // Expect the file to be in progress. |
| 221 bool expect_in_progress_; | 208 bool expect_in_progress_; |
| 222 | 209 |
| 223 // Hash calculator. | |
| 224 scoped_ptr<crypto::SecureHash> secure_hash_; | |
| 225 | |
| 226 unsigned char sha256_hash_[crypto::kSHA256Length]; | |
| 227 | |
| 228 private: | 210 private: |
| 229 // Keep track of what data should be saved to the disk file. | 211 // Keep track of what data should be saved to the disk file. |
| 230 std::string expected_data_; | 212 std::string expected_data_; |
| 231 DownloadInterruptReason expected_error_; | 213 DownloadInterruptReason expected_error_; |
| 232 | 214 |
| 233 // Mock file thread to satisfy debug checks in BaseFile. | 215 // Mock file thread to satisfy debug checks in BaseFile. |
| 234 base::MessageLoop message_loop_; | 216 base::MessageLoop message_loop_; |
| 235 BrowserThreadImpl file_thread_; | 217 BrowserThreadImpl file_thread_; |
| 236 }; | 218 }; |
| 237 | 219 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 259 TEST_F(BaseFileTest, WriteAndDetach) { | 241 TEST_F(BaseFileTest, WriteAndDetach) { |
| 260 ASSERT_TRUE(InitializeFile()); | 242 ASSERT_TRUE(InitializeFile()); |
| 261 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 243 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
| 262 base_file_->Finish(); | 244 base_file_->Finish(); |
| 263 base_file_->Detach(); | 245 base_file_->Detach(); |
| 264 expect_file_survives_ = true; | 246 expect_file_survives_ = true; |
| 265 } | 247 } |
| 266 | 248 |
| 267 // Write data to the file and detach it, and calculate its sha256 hash. | 249 // Write data to the file and detach it, and calculate its sha256 hash. |
| 268 TEST_F(BaseFileTest, WriteWithHashAndDetach) { | 250 TEST_F(BaseFileTest, WriteWithHashAndDetach) { |
| 269 // Calculate the final hash. | |
| 270 ResetHash(); | |
| 271 UpdateHash(kTestData1, kTestDataLength1); | |
| 272 std::string expected_hash = GetFinalHash(); | |
| 273 std::string expected_hash_hex = | |
| 274 base::HexEncode(expected_hash.data(), expected_hash.size()); | |
| 275 | |
| 276 MakeFileWithHash(); | |
| 277 ASSERT_TRUE(InitializeFile()); | 251 ASSERT_TRUE(InitializeFile()); |
| 278 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 252 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
| 279 base_file_->Finish(); | 253 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); |
| 280 | |
| 281 std::string hash; | |
| 282 base_file_->GetHash(&hash); | |
| 283 EXPECT_EQ("0B2D3F3F7943AD64B860DF94D05CB56A8A97C6EC5768B5B70B930C5AA7FA9ADE", | |
| 284 expected_hash_hex); | |
| 285 EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size())); | |
| 286 | |
| 287 base_file_->Detach(); | 254 base_file_->Detach(); |
| 288 expect_file_survives_ = true; | 255 expect_file_survives_ = true; |
| 289 } | 256 } |
| 290 | 257 |
| 291 // Rename the file after writing to it, then detach. | 258 // Rename the file after writing to it, then detach. |
| 292 TEST_F(BaseFileTest, WriteThenRenameAndDetach) { | 259 TEST_F(BaseFileTest, WriteThenRenameAndDetach) { |
| 293 ASSERT_TRUE(InitializeFile()); | 260 ASSERT_TRUE(InitializeFile()); |
| 294 | 261 |
| 295 base::FilePath initial_path(base_file_->full_path()); | 262 base::FilePath initial_path(base_file_->full_path()); |
| 296 EXPECT_TRUE(base::PathExists(initial_path)); | 263 EXPECT_TRUE(base::PathExists(initial_path)); |
| 297 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); | 264 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); |
| 298 EXPECT_FALSE(base::PathExists(new_path)); | 265 EXPECT_FALSE(base::PathExists(new_path)); |
| 299 | 266 |
| 300 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 267 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
| 301 | 268 |
| 302 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); | 269 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); |
| 303 EXPECT_FALSE(base::PathExists(initial_path)); | 270 EXPECT_FALSE(base::PathExists(initial_path)); |
| 304 EXPECT_TRUE(base::PathExists(new_path)); | 271 EXPECT_TRUE(base::PathExists(new_path)); |
| 305 | 272 |
| 306 base_file_->Finish(); | 273 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); |
| 307 base_file_->Detach(); | 274 base_file_->Detach(); |
| 308 expect_file_survives_ = true; | 275 expect_file_survives_ = true; |
| 309 } | 276 } |
| 310 | 277 |
| 311 // Write data to the file once. | 278 // Write data to the file once. |
| 312 TEST_F(BaseFileTest, SingleWrite) { | 279 TEST_F(BaseFileTest, SingleWrite) { |
| 313 ASSERT_TRUE(InitializeFile()); | 280 ASSERT_TRUE(InitializeFile()); |
| 314 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 281 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
| 315 base_file_->Finish(); | 282 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); |
| 316 } | 283 } |
| 317 | 284 |
| 318 // Write data to the file multiple times. | 285 // Write data to the file multiple times. |
| 319 TEST_F(BaseFileTest, MultipleWrites) { | 286 TEST_F(BaseFileTest, MultipleWrites) { |
| 320 ASSERT_TRUE(InitializeFile()); | 287 ASSERT_TRUE(InitializeFile()); |
| 321 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 288 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
| 322 ASSERT_TRUE(AppendDataToFile(kTestData2)); | 289 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 323 ASSERT_TRUE(AppendDataToFile(kTestData3)); | 290 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 324 std::string hash; | 291 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 325 EXPECT_FALSE(base_file_->GetHash(&hash)); | |
| 326 base_file_->Finish(); | |
| 327 } | |
| 328 | |
| 329 // Write data to the file once and calculate its sha256 hash. | |
| 330 TEST_F(BaseFileTest, SingleWriteWithHash) { | |
| 331 // Calculate the final hash. | |
| 332 ResetHash(); | |
| 333 UpdateHash(kTestData1, kTestDataLength1); | |
| 334 std::string expected_hash = GetFinalHash(); | |
| 335 std::string expected_hash_hex = | |
| 336 base::HexEncode(expected_hash.data(), expected_hash.size()); | |
| 337 | |
| 338 MakeFileWithHash(); | |
| 339 ASSERT_TRUE(InitializeFile()); | |
| 340 // Can get partial hash states before Finish() is called. | |
| 341 EXPECT_STRNE(std::string().c_str(), base_file_->GetHashState().c_str()); | |
| 342 ASSERT_TRUE(AppendDataToFile(kTestData1)); | |
| 343 EXPECT_STRNE(std::string().c_str(), base_file_->GetHashState().c_str()); | |
| 344 base_file_->Finish(); | |
| 345 | |
| 346 std::string hash; | |
| 347 base_file_->GetHash(&hash); | |
| 348 EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size())); | |
| 349 } | |
| 350 | |
| 351 // Write data to the file multiple times and calculate its sha256 hash. | |
| 352 TEST_F(BaseFileTest, MultipleWritesWithHash) { | |
| 353 // Calculate the final hash. | |
| 354 ResetHash(); | |
| 355 UpdateHash(kTestData1, kTestDataLength1); | |
| 356 UpdateHash(kTestData2, kTestDataLength2); | |
| 357 UpdateHash(kTestData3, kTestDataLength3); | |
| 358 std::string expected_hash = GetFinalHash(); | |
| 359 std::string expected_hash_hex = | |
| 360 base::HexEncode(expected_hash.data(), expected_hash.size()); | |
| 361 | |
| 362 std::string hash; | |
| 363 MakeFileWithHash(); | |
| 364 ASSERT_TRUE(InitializeFile()); | |
| 365 ASSERT_TRUE(AppendDataToFile(kTestData1)); | |
| 366 ASSERT_TRUE(AppendDataToFile(kTestData2)); | |
| 367 ASSERT_TRUE(AppendDataToFile(kTestData3)); | |
| 368 // No hash before Finish() is called. | |
| 369 EXPECT_FALSE(base_file_->GetHash(&hash)); | |
| 370 base_file_->Finish(); | |
| 371 | |
| 372 EXPECT_TRUE(base_file_->GetHash(&hash)); | |
| 373 EXPECT_EQ("CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8", | |
| 374 expected_hash_hex); | |
| 375 EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size())); | |
| 376 } | 292 } |
| 377 | 293 |
| 378 // Write data to the file multiple times, interrupt it, and continue using | 294 // Write data to the file multiple times, interrupt it, and continue using |
| 379 // another file. Calculate the resulting combined sha256 hash. | 295 // another file. Calculate the resulting combined sha256 hash. |
| 380 TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) { | 296 TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) { |
| 381 // Calculate the final hash. | |
| 382 ResetHash(); | |
| 383 UpdateHash(kTestData1, kTestDataLength1); | |
| 384 UpdateHash(kTestData2, kTestDataLength2); | |
| 385 UpdateHash(kTestData3, kTestDataLength3); | |
| 386 std::string expected_hash = GetFinalHash(); | |
| 387 std::string expected_hash_hex = | |
| 388 base::HexEncode(expected_hash.data(), expected_hash.size()); | |
| 389 | |
| 390 MakeFileWithHash(); | |
| 391 ASSERT_TRUE(InitializeFile()); | 297 ASSERT_TRUE(InitializeFile()); |
| 392 // Write some data | 298 // Write some data |
| 393 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 299 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
| 394 ASSERT_TRUE(AppendDataToFile(kTestData2)); | 300 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 395 // Get the hash state and file name. | 301 // Get the hash state and file name. |
| 396 std::string hash_state; | 302 scoped_ptr<crypto::SecureHash> hash_state = base_file_->Finish(); |
| 397 hash_state = base_file_->GetHashState(); | |
| 398 // Finish the file. | |
| 399 base_file_->Finish(); | |
| 400 | 303 |
| 401 base::FilePath new_file_path(temp_dir_.path().Append( | 304 base::FilePath new_file_path(temp_dir_.path().Append( |
| 402 base::FilePath(FILE_PATH_LITERAL("second_file")))); | 305 base::FilePath(FILE_PATH_LITERAL("second_file")))); |
| 403 | 306 |
| 404 ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path)); | 307 ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path)); |
| 405 | 308 |
| 406 // Create another file | 309 // Create another file |
| 407 BaseFile second_file(new_file_path, | 310 BaseFile second_file((net::BoundNetLog())); |
| 408 GURL(), | |
| 409 GURL(), | |
| 410 base_file_->bytes_so_far(), | |
| 411 true, | |
| 412 hash_state, | |
| 413 base::File(), | |
| 414 net::BoundNetLog()); | |
| 415 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 311 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 416 second_file.Initialize(base::FilePath())); | 312 second_file.Initialize(new_file_path, |
| 313 base::FilePath(), |
| 314 base::File(), |
| 315 base_file_->bytes_so_far(), |
| 316 std::string(), |
| 317 std::move(hash_state))); |
| 417 std::string data(kTestData3); | 318 std::string data(kTestData3); |
| 418 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 319 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 419 second_file.AppendDataToFile(data.data(), data.size())); | 320 second_file.AppendDataToFile(data.data(), data.size())); |
| 420 second_file.Finish(); | 321 ExpectHashValue(kHashOfTestData1To3, second_file.Finish()); |
| 421 | |
| 422 std::string hash; | |
| 423 EXPECT_TRUE(second_file.GetHash(&hash)); | |
| 424 // This will fail until getting the hash state is supported in SecureHash. | |
| 425 EXPECT_STREQ(expected_hash_hex.c_str(), | |
| 426 base::HexEncode(hash.data(), hash.size()).c_str()); | |
| 427 } | 322 } |
| 428 | 323 |
| 429 // Rename the file after all writes to it. | 324 // Rename the file after all writes to it. |
| 430 TEST_F(BaseFileTest, WriteThenRename) { | 325 TEST_F(BaseFileTest, WriteThenRename) { |
| 431 ASSERT_TRUE(InitializeFile()); | 326 ASSERT_TRUE(InitializeFile()); |
| 432 | 327 |
| 433 base::FilePath initial_path(base_file_->full_path()); | 328 base::FilePath initial_path(base_file_->full_path()); |
| 434 EXPECT_TRUE(base::PathExists(initial_path)); | 329 EXPECT_TRUE(base::PathExists(initial_path)); |
| 435 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); | 330 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); |
| 436 EXPECT_FALSE(base::PathExists(new_path)); | 331 EXPECT_FALSE(base::PathExists(new_path)); |
| 437 | 332 |
| 438 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 333 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
| 439 | 334 |
| 440 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 335 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 441 base_file_->Rename(new_path)); | 336 base_file_->Rename(new_path)); |
| 442 EXPECT_FALSE(base::PathExists(initial_path)); | 337 EXPECT_FALSE(base::PathExists(initial_path)); |
| 443 EXPECT_TRUE(base::PathExists(new_path)); | 338 EXPECT_TRUE(base::PathExists(new_path)); |
| 444 | 339 |
| 445 base_file_->Finish(); | 340 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); |
| 446 } | 341 } |
| 447 | 342 |
| 448 // Rename the file while the download is still in progress. | 343 // Rename the file while the download is still in progress. |
| 449 TEST_F(BaseFileTest, RenameWhileInProgress) { | 344 TEST_F(BaseFileTest, RenameWhileInProgress) { |
| 450 ASSERT_TRUE(InitializeFile()); | 345 ASSERT_TRUE(InitializeFile()); |
| 451 | 346 |
| 452 base::FilePath initial_path(base_file_->full_path()); | 347 base::FilePath initial_path(base_file_->full_path()); |
| 453 EXPECT_TRUE(base::PathExists(initial_path)); | 348 EXPECT_TRUE(base::PathExists(initial_path)); |
| 454 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); | 349 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); |
| 455 EXPECT_FALSE(base::PathExists(new_path)); | 350 EXPECT_FALSE(base::PathExists(new_path)); |
| 456 | 351 |
| 457 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 352 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
| 458 | 353 |
| 459 EXPECT_TRUE(base_file_->in_progress()); | 354 EXPECT_TRUE(base_file_->in_progress()); |
| 460 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); | 355 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); |
| 461 EXPECT_FALSE(base::PathExists(initial_path)); | 356 EXPECT_FALSE(base::PathExists(initial_path)); |
| 462 EXPECT_TRUE(base::PathExists(new_path)); | 357 EXPECT_TRUE(base::PathExists(new_path)); |
| 463 | 358 |
| 464 ASSERT_TRUE(AppendDataToFile(kTestData2)); | 359 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 360 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 465 | 361 |
| 466 base_file_->Finish(); | 362 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 467 } | 363 } |
| 468 | 364 |
| 469 // Test that a failed rename reports the correct error. | 365 // Test that a failed rename reports the correct error. |
| 470 TEST_F(BaseFileTest, RenameWithError) { | 366 TEST_F(BaseFileTest, RenameWithError) { |
| 471 ASSERT_TRUE(InitializeFile()); | 367 ASSERT_TRUE(InitializeFile()); |
| 472 | 368 |
| 473 // TestDir is a subdirectory in |temp_dir_| that we will make read-only so | 369 // TestDir is a subdirectory in |temp_dir_| that we will make read-only so |
| 474 // that the rename will fail. | 370 // that the rename will fail. |
| 475 base::FilePath test_dir(temp_dir_.path().AppendASCII("TestDir")); | 371 base::FilePath test_dir(temp_dir_.path().AppendASCII("TestDir")); |
| 476 ASSERT_TRUE(base::CreateDirectory(test_dir)); | 372 ASSERT_TRUE(base::CreateDirectory(test_dir)); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 // Try to rename again, just for kicks. It should still fail. | 414 // Try to rename again, just for kicks. It should still fail. |
| 519 ExpectPermissionError(base_file_->Rename(new_path)); | 415 ExpectPermissionError(base_file_->Rename(new_path)); |
| 520 } | 416 } |
| 521 | 417 |
| 522 // Now that TestDir is writeable again, we should be able to successfully | 418 // Now that TestDir is writeable again, we should be able to successfully |
| 523 // rename the file. | 419 // rename the file. |
| 524 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); | 420 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); |
| 525 ASSERT_EQ(new_path.value(), base_file_->full_path().value()); | 421 ASSERT_EQ(new_path.value(), base_file_->full_path().value()); |
| 526 ASSERT_TRUE(AppendDataToFile(kTestData3)); | 422 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 527 | 423 |
| 528 base_file_->Finish(); | 424 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 529 | |
| 530 // The contents of the file should be intact. | |
| 531 std::string file_contents; | |
| 532 std::string expected_contents(kTestData1); | |
| 533 expected_contents += kTestData2; | |
| 534 expected_contents += kTestData3; | |
| 535 ASSERT_TRUE(base::ReadFileToString(new_path, &file_contents)); | |
| 536 EXPECT_EQ(expected_contents, file_contents); | |
| 537 } | 425 } |
| 538 | 426 |
| 539 // Test that a failed write reports an error. | 427 // Test that a failed write reports an error. |
| 540 TEST_F(BaseFileTest, WriteWithError) { | 428 TEST_F(BaseFileTest, WriteWithError) { |
| 541 base::FilePath path; | 429 base::FilePath path; |
| 542 ASSERT_TRUE(base::CreateTemporaryFile(&path)); | 430 ASSERT_TRUE(base::CreateTemporaryFile(&path)); |
| 543 | 431 |
| 544 // Pass a file handle which was opened without the WRITE flag. | 432 // Pass a file handle which was opened without the WRITE flag. |
| 545 // This should result in an error when writing. | 433 // This should result in an error when writing. |
| 546 base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ); | 434 base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ); |
| 547 base_file_.reset(new BaseFile(path, GURL(), GURL(), 0, false, std::string(), | 435 base_file_.reset(new BaseFile(net::BoundNetLog())); |
| 548 std::move(file), net::BoundNetLog())); | 436 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 549 ASSERT_TRUE(InitializeFile()); | 437 base_file_->Initialize(path, |
| 438 base::FilePath(), |
| 439 std::move(file), |
| 440 0, |
| 441 std::string(), |
| 442 scoped_ptr<crypto::SecureHash>())); |
| 550 #if defined(OS_WIN) | 443 #if defined(OS_WIN) |
| 551 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); | 444 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); |
| 552 #elif defined (OS_POSIX) | 445 #elif defined (OS_POSIX) |
| 553 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 446 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
| 554 #endif | 447 #endif |
| 555 ASSERT_FALSE(AppendDataToFile(kTestData1)); | 448 ASSERT_FALSE(AppendDataToFile(kTestData1)); |
| 556 base_file_->Finish(); | 449 base_file_->Finish(); |
| 557 } | 450 } |
| 558 | 451 |
| 559 // Try to write to uninitialized file. | 452 // Try to write to uninitialized file. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 573 CreateFileWithName(base_file_->full_path()); | 466 CreateFileWithName(base_file_->full_path()); |
| 574 | 467 |
| 575 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 468 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
| 576 base_file_->Finish(); | 469 base_file_->Finish(); |
| 577 } | 470 } |
| 578 | 471 |
| 579 // Create a file and append to it. | 472 // Create a file and append to it. |
| 580 TEST_F(BaseFileTest, AppendToBaseFile) { | 473 TEST_F(BaseFileTest, AppendToBaseFile) { |
| 581 // Create a new file. | 474 // Create a new file. |
| 582 base::FilePath existing_file_name = CreateTestFile(); | 475 base::FilePath existing_file_name = CreateTestFile(); |
| 583 | |
| 584 set_expected_data(kTestData4); | 476 set_expected_data(kTestData4); |
| 585 | 477 |
| 586 // Use the file we've just created. | 478 // Use the file we've just created. |
| 587 base_file_.reset(new BaseFile(existing_file_name, | 479 base_file_.reset(new BaseFile(net::BoundNetLog())); |
| 588 GURL(), | 480 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 589 GURL(), | 481 base_file_->Initialize(existing_file_name, |
| 590 kTestDataLength4, | 482 base::FilePath(), |
| 591 false, | 483 base::File(), |
| 592 std::string(), | 484 kTestDataLength4, |
| 593 base::File(), | 485 std::string(), |
| 594 net::BoundNetLog())); | 486 scoped_ptr<crypto::SecureHash>())); |
| 595 | |
| 596 ASSERT_TRUE(InitializeFile()); | |
| 597 | 487 |
| 598 const base::FilePath file_name = base_file_->full_path(); | 488 const base::FilePath file_name = base_file_->full_path(); |
| 599 EXPECT_NE(base::FilePath::StringType(), file_name.value()); | 489 EXPECT_NE(base::FilePath::StringType(), file_name.value()); |
| 600 | 490 |
| 601 // Write into the file. | 491 // Write into the file. |
| 602 EXPECT_TRUE(AppendDataToFile(kTestData1)); | 492 EXPECT_TRUE(AppendDataToFile(kTestData1)); |
| 603 | 493 |
| 604 base_file_->Finish(); | 494 base_file_->Finish(); |
| 605 base_file_->Detach(); | 495 base_file_->Detach(); |
| 606 expect_file_survives_ = true; | 496 expect_file_survives_ = true; |
| 607 } | 497 } |
| 608 | 498 |
| 609 // Create a read-only file and attempt to write to it. | 499 // Create a read-only file and attempt to write to it. |
| 610 TEST_F(BaseFileTest, ReadonlyBaseFile) { | 500 TEST_F(BaseFileTest, ReadonlyBaseFile) { |
| 611 // Create a new file. | 501 // Create a new file. |
| 612 base::FilePath readonly_file_name = CreateTestFile(); | 502 base::FilePath readonly_file_name = CreateTestFile(); |
| 613 | 503 |
| 614 // Restore permissions to the file when we are done with this test. | 504 // Restore permissions to the file when we are done with this test. |
| 615 base::FilePermissionRestorer restore_permissions(readonly_file_name); | 505 base::FilePermissionRestorer restore_permissions(readonly_file_name); |
| 616 | 506 |
| 617 // Make it read-only. | 507 // Make it read-only. |
| 618 EXPECT_TRUE(base::MakeFileUnwritable(readonly_file_name)); | 508 EXPECT_TRUE(base::MakeFileUnwritable(readonly_file_name)); |
| 619 | 509 |
| 620 // Try to overwrite it. | 510 // Try to overwrite it. |
| 621 base_file_.reset(new BaseFile(readonly_file_name, | 511 base_file_.reset(new BaseFile(net::BoundNetLog())); |
| 622 GURL(), | 512 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, |
| 623 GURL(), | 513 base_file_->Initialize(readonly_file_name, |
| 624 0, | 514 base::FilePath(), |
| 625 false, | 515 base::File(), |
| 626 std::string(), | 516 0, |
| 627 base::File(), | 517 std::string(), |
| 628 net::BoundNetLog())); | 518 scoped_ptr<crypto::SecureHash>())); |
| 629 | 519 |
| 630 expect_in_progress_ = false; | 520 expect_in_progress_ = false; |
| 631 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); | |
| 632 EXPECT_FALSE(InitializeFile()); | |
| 633 | 521 |
| 634 const base::FilePath file_name = base_file_->full_path(); | 522 const base::FilePath file_name = base_file_->full_path(); |
| 635 EXPECT_NE(base::FilePath::StringType(), file_name.value()); | 523 EXPECT_NE(base::FilePath::StringType(), file_name.value()); |
| 636 | 524 |
| 637 // Write into the file. | 525 // Write into the file. |
| 638 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 526 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
| 639 EXPECT_FALSE(AppendDataToFile(kTestData1)); | 527 EXPECT_FALSE(AppendDataToFile(kTestData1)); |
| 640 | 528 |
| 641 base_file_->Finish(); | 529 base_file_->Finish(); |
| 642 base_file_->Detach(); | 530 base_file_->Detach(); |
| 643 expect_file_survives_ = true; | 531 expect_file_survives_ = true; |
| 644 } | 532 } |
| 645 | 533 |
| 646 TEST_F(BaseFileTest, IsEmptyHash) { | 534 // Open an existing file and continue writing to it. The hash of the partial |
| 647 std::string empty(crypto::kSHA256Length, '\x00'); | 535 // file is known and matches the existing contents. |
| 648 EXPECT_TRUE(BaseFile::IsEmptyHash(empty)); | 536 TEST_F(BaseFileTest, ExistingBaseFileKnownHash) { |
| 649 std::string not_empty(crypto::kSHA256Length, '\x01'); | 537 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 650 EXPECT_FALSE(BaseFile::IsEmptyHash(not_empty)); | 538 ASSERT_TRUE(base::WriteFile(file_path, kTestData1, kTestDataLength1)); |
| 651 EXPECT_FALSE(BaseFile::IsEmptyHash(std::string())); | |
| 652 | 539 |
| 653 std::string also_not_empty = empty; | 540 std::string hash_so_far(std::begin(kHashOfTestData1), |
| 654 also_not_empty[crypto::kSHA256Length - 1] = '\x01'; | 541 std::end(kHashOfTestData1)); |
| 655 EXPECT_FALSE(BaseFile::IsEmptyHash(also_not_empty)); | 542 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 543 base_file_->Initialize(file_path, |
| 544 base::FilePath(), |
| 545 base::File(), |
| 546 kTestDataLength1, |
| 547 hash_so_far, |
| 548 scoped_ptr<crypto::SecureHash>())); |
| 549 set_expected_data(kTestData1); |
| 550 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 551 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 552 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 553 } |
| 554 |
| 555 // Open an existing file and continue writing to it. The hash of the partial |
| 556 // file is unknown. |
| 557 TEST_F(BaseFileTest, ExistingBaseFileUnknownHash) { |
| 558 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 559 ASSERT_TRUE(base::WriteFile(file_path, kTestData1, kTestDataLength1)); |
| 560 |
| 561 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 562 base_file_->Initialize(file_path, |
| 563 base::FilePath(), |
| 564 base::File(), |
| 565 kTestDataLength1, |
| 566 std::string(), |
| 567 scoped_ptr<crypto::SecureHash>())); |
| 568 set_expected_data(kTestData1); |
| 569 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 570 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 571 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 572 } |
| 573 |
| 574 // Open an existing file. The contentsof the file doesn't match the known hash. |
| 575 TEST_F(BaseFileTest, ExistingBaseFileIncorrectHash) { |
| 576 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 577 ASSERT_TRUE(base::WriteFile(file_path, kTestData2, kTestDataLength2)); |
| 578 |
| 579 std::string hash_so_far(std::begin(kHashOfTestData1), |
| 580 std::end(kHashOfTestData1)); |
| 581 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, |
| 582 base_file_->Initialize(file_path, |
| 583 base::FilePath(), |
| 584 base::File(), |
| 585 kTestDataLength2, |
| 586 hash_so_far, |
| 587 scoped_ptr<crypto::SecureHash>())); |
| 588 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); |
| 589 } |
| 590 |
| 591 // Open a large existing file with a known hash and continue writing to it. |
| 592 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeKnownHash) { |
| 593 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 594 std::string big_buffer(1024 * 200, 'a'); |
| 595 ASSERT_TRUE(base::WriteFile(file_path, big_buffer.data(), big_buffer.size())); |
| 596 |
| 597 // Hash of partial file (1024*200 * 'a') |
| 598 const uint8_t kExpectedPartialHash[] = { |
| 599 0x4b, 0x4f, 0x0f, 0x46, 0xac, 0x02, 0xd1, 0x77, 0xde, 0xa0, 0xab, |
| 600 0x36, 0xa6, 0x6a, 0x65, 0x78, 0x40, 0xe2, 0xfb, 0x98, 0xb2, 0x0b, |
| 601 0xb2, 0x7a, 0x68, 0x8d, 0xb4, 0xd8, 0xea, 0x9c, 0xd2, 0x2c}; |
| 602 |
| 603 // Hash of entire file (1024*400 * 'a') |
| 604 const uint8_t kExpectedFullHash[] = { |
| 605 0x0c, 0xe9, 0xf6, 0x78, 0x6b, 0x0f, 0x58, 0x49, 0x36, 0xe8, 0x83, |
| 606 0xc5, 0x09, 0x16, 0xbc, 0x5e, 0x2d, 0x07, 0x95, 0xb9, 0x42, 0x20, |
| 607 0x41, 0x7c, 0xb3, 0x38, 0xd3, 0xf4, 0xe0, 0x78, 0x89, 0x46}; |
| 608 |
| 609 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 610 base_file_->Initialize(file_path, |
| 611 base::FilePath(), |
| 612 base::File(), |
| 613 big_buffer.size(), |
| 614 std::string(std::begin(kExpectedPartialHash), |
| 615 std::end(kExpectedPartialHash)), |
| 616 scoped_ptr<crypto::SecureHash>())); |
| 617 set_expected_data(big_buffer); // Contents of the file on Open. |
| 618 ASSERT_TRUE(AppendDataToFile(big_buffer)); |
| 619 ExpectHashValue(kExpectedFullHash, base_file_->Finish()); |
| 620 } |
| 621 |
| 622 // Open a large existing file. The contents doesn't match the known hash. |
| 623 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeIncorrectHash) { |
| 624 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 625 std::string big_buffer(1024 * 200, 'a'); |
| 626 ASSERT_TRUE(base::WriteFile(file_path, big_buffer.data(), big_buffer.size())); |
| 627 |
| 628 // Incorrect hash of partial file (1024*200 * 'a') |
| 629 const uint8_t kExpectedPartialHash[] = { |
| 630 0xc2, 0xa9, 0x08, 0xd9, 0x8f, 0x5d, 0xf9, 0x87, 0xad, 0xe4, 0x1b, |
| 631 0x5f, 0xce, 0x21, 0x30, 0x67, 0xef, 0x6c, 0xc2, 0x1e, 0xf2, 0x24, |
| 632 0x02, 0x12, 0xa4, 0x1e, 0x54, 0xb5, 0xe7, 0xc2, 0x8a, 0xe5}; |
| 633 |
| 634 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, |
| 635 base_file_->Initialize(file_path, |
| 636 base::FilePath(), |
| 637 base::File(), |
| 638 big_buffer.size(), |
| 639 std::string(std::begin(kExpectedPartialHash), |
| 640 std::end(kExpectedPartialHash)), |
| 641 scoped_ptr<crypto::SecureHash>())); |
| 642 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); |
| 643 } |
| 644 |
| 645 // Open an existing file. The size of the file is too short. |
| 646 TEST_F(BaseFileTest, ExistingBaseFileTooShort) { |
| 647 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 648 ASSERT_TRUE(base::WriteFile(file_path, kTestData1, kTestDataLength1)); |
| 649 |
| 650 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT, |
| 651 base_file_->Initialize(file_path, |
| 652 base::FilePath(), |
| 653 base::File(), |
| 654 kTestDataLength1 + 1, |
| 655 std::string(), |
| 656 scoped_ptr<crypto::SecureHash>())); |
| 657 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT); |
| 658 } |
| 659 |
| 660 // Open an existing file. The size is larger than expected. |
| 661 TEST_F(BaseFileTest, ExistingBaseFileKnownHashTooLong) { |
| 662 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 663 std::string contents; |
| 664 contents.append(kTestData1); |
| 665 contents.append("Something extra"); |
| 666 ASSERT_TRUE(base::WriteFile(file_path, contents.data(), contents.size())); |
| 667 |
| 668 std::string hash_so_far(std::begin(kHashOfTestData1), |
| 669 std::end(kHashOfTestData1)); |
| 670 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 671 base_file_->Initialize(file_path, |
| 672 base::FilePath(), |
| 673 base::File(), |
| 674 kTestDataLength1, |
| 675 hash_so_far, |
| 676 scoped_ptr<crypto::SecureHash>())); |
| 677 set_expected_data(kTestData1); // Our starting position. |
| 678 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 679 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 680 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 681 } |
| 682 |
| 683 // Open an existing file. The size is large than expected and the hash is |
| 684 // unknown. |
| 685 TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLong) { |
| 686 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
| 687 std::string contents; |
| 688 contents.append(kTestData1); |
| 689 contents.append("Something extra"); |
| 690 ASSERT_TRUE(base::WriteFile(file_path, contents.data(), contents.size())); |
| 691 |
| 692 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
| 693 base_file_->Initialize(file_path, |
| 694 base::FilePath(), |
| 695 base::File(), |
| 696 kTestDataLength1, |
| 697 std::string(), |
| 698 scoped_ptr<crypto::SecureHash>())); |
| 699 set_expected_data(kTestData1); |
| 700 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
| 701 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
| 702 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
| 656 } | 703 } |
| 657 | 704 |
| 658 // Test that a temporary file is created in the default download directory. | 705 // Test that a temporary file is created in the default download directory. |
| 659 TEST_F(BaseFileTest, CreatedInDefaultDirectory) { | 706 TEST_F(BaseFileTest, CreatedInDefaultDirectory) { |
| 660 ASSERT_TRUE(base_file_->full_path().empty()); | 707 ASSERT_TRUE(base_file_->full_path().empty()); |
| 661 ASSERT_TRUE(InitializeFile()); | 708 ASSERT_TRUE(InitializeFile()); |
| 662 EXPECT_FALSE(base_file_->full_path().empty()); | 709 EXPECT_FALSE(base_file_->full_path().empty()); |
| 663 | 710 |
| 664 // On Windows, CreateTemporaryFileInDir() will cause a path with short names | 711 // On Windows, CreateTemporaryFileInDir() will cause a path with short names |
| 665 // to be expanded into a path with long names. Thus temp_dir.path() might not | 712 // to be expanded into a path with long names. Thus temp_dir.path() might not |
| (...skipping 18 matching lines...) Expand all Loading... |
| 684 | 731 |
| 685 const char kData[] = "hello"; | 732 const char kData[] = "hello"; |
| 686 const int kDataLength = static_cast<int>(arraysize(kData) - 1); | 733 const int kDataLength = static_cast<int>(arraysize(kData) - 1); |
| 687 ASSERT_EQ(kDataLength, base::WriteFile(full_path, kData, kDataLength)); | 734 ASSERT_EQ(kDataLength, base::WriteFile(full_path, kData, kDataLength)); |
| 688 // The file that we created here should stick around when the BaseFile is | 735 // The file that we created here should stick around when the BaseFile is |
| 689 // destroyed during TearDown. | 736 // destroyed during TearDown. |
| 690 expect_file_survives_ = true; | 737 expect_file_survives_ = true; |
| 691 } | 738 } |
| 692 | 739 |
| 693 } // namespace content | 740 } // namespace content |
| OLD | NEW |