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 = base_file_->Initialize( |
96 base::FilePath(), temp_dir_.path(), base::File(), 0, std::string(), | |
97 scoped_ptr<crypto::SecureHash>()); | |
120 EXPECT_EQ(expected_error_, result); | 98 EXPECT_EQ(expected_error_, result); |
121 return result == DOWNLOAD_INTERRUPT_REASON_NONE; | 99 return result == DOWNLOAD_INTERRUPT_REASON_NONE; |
122 } | 100 } |
123 | 101 |
124 bool AppendDataToFile(const std::string& data) { | 102 bool AppendDataToFile(const std::string& data) { |
125 EXPECT_EQ(expect_in_progress_, base_file_->in_progress()); | 103 EXPECT_EQ(expect_in_progress_, base_file_->in_progress()); |
126 DownloadInterruptReason result = | 104 DownloadInterruptReason result = |
127 base_file_->AppendDataToFile(data.data(), data.size()); | 105 base_file_->AppendDataToFile(data.data(), data.size()); |
128 if (result == DOWNLOAD_INTERRUPT_REASON_NONE) | 106 if (result == DOWNLOAD_INTERRUPT_REASON_NONE) |
129 EXPECT_TRUE(expect_in_progress_) << " result = " << result; | 107 EXPECT_TRUE(expect_in_progress_) << " result = " << result; |
130 | 108 |
131 EXPECT_EQ(expected_error_, result); | 109 EXPECT_EQ(expected_error_, result); |
132 if (base_file_->in_progress()) { | 110 if (base_file_->in_progress()) { |
133 expected_data_ += data; | 111 expected_data_ += data; |
134 if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) { | 112 if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) { |
135 EXPECT_EQ(static_cast<int64_t>(expected_data_.size()), | 113 EXPECT_EQ(static_cast<int64_t>(expected_data_.size()), |
136 base_file_->bytes_so_far()); | 114 base_file_->bytes_so_far()); |
137 } | 115 } |
138 } | 116 } |
139 return result == DOWNLOAD_INTERRUPT_REASON_NONE; | 117 return result == DOWNLOAD_INTERRUPT_REASON_NONE; |
140 } | 118 } |
141 | 119 |
142 void set_expected_data(const std::string& data) { expected_data_ = data; } | 120 void set_expected_data(const std::string& data) { expected_data_ = data; } |
143 | 121 |
144 // Helper functions. | 122 // Helper functions. |
145 // Create a file. Returns the complete file path. | 123 // Create a file. Returns the complete file path. |
146 base::FilePath CreateTestFile() { | 124 base::FilePath CreateTestFile() { |
147 base::FilePath file_name; | 125 base::FilePath file_name; |
148 BaseFile file(base::FilePath(), | 126 BaseFile file((net::BoundNetLog())); |
svaldez
2016/03/10 17:45:33
file(net::...)?
Does this actually need the casti
asanka
2016/03/11 16:25:09
Sadly, yes. Without them, 'BaseFile file(net::Boun
| |
149 GURL(), | |
150 GURL(), | |
151 0, | |
152 false, | |
153 std::string(), | |
154 base::File(), | |
155 net::BoundNetLog()); | |
156 | 127 |
157 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 128 EXPECT_EQ( |
158 file.Initialize(temp_dir_.path())); | 129 DOWNLOAD_INTERRUPT_REASON_NONE, |
130 file.Initialize(base::FilePath(), temp_dir_.path(), base::File(), 0, | |
131 std::string(), scoped_ptr<crypto::SecureHash>())); | |
159 file_name = file.full_path(); | 132 file_name = file.full_path(); |
160 EXPECT_NE(base::FilePath::StringType(), file_name.value()); | 133 EXPECT_NE(base::FilePath::StringType(), file_name.value()); |
161 | 134 |
162 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 135 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
163 file.AppendDataToFile(kTestData4, kTestDataLength4)); | 136 file.AppendDataToFile(kTestData4, kTestDataLength4)); |
164 | 137 |
165 // Keep the file from getting deleted when existing_file_name is deleted. | 138 // Keep the file from getting deleted when existing_file_name is deleted. |
166 file.Detach(); | 139 file.Detach(); |
167 | 140 |
168 return file_name; | 141 return file_name; |
169 } | 142 } |
170 | 143 |
171 // Create a file with the specified file name. | 144 // Create a file with the specified file name. |
172 void CreateFileWithName(const base::FilePath& file_name) { | 145 void CreateFileWithName(const base::FilePath& file_name) { |
173 EXPECT_NE(base::FilePath::StringType(), file_name.value()); | 146 EXPECT_NE(base::FilePath::StringType(), file_name.value()); |
174 BaseFile duplicate_file(file_name, | 147 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, | 148 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
183 duplicate_file.Initialize(temp_dir_.path())); | 149 duplicate_file.Initialize(file_name, temp_dir_.path(), |
150 base::File(), 0, std::string(), | |
151 scoped_ptr<crypto::SecureHash>())); | |
184 // Write something into it. | 152 // Write something into it. |
185 duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4); | 153 duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4); |
186 // Detach the file so it isn't deleted on destruction of |duplicate_file|. | 154 // Detach the file so it isn't deleted on destruction of |duplicate_file|. |
187 duplicate_file.Detach(); | 155 duplicate_file.Detach(); |
188 } | 156 } |
189 | 157 |
190 int64_t CurrentSpeedAtTime(base::TimeTicks current_time) { | 158 int64_t CurrentSpeedAtTime(base::TimeTicks current_time) { |
191 EXPECT_TRUE(base_file_.get()); | 159 EXPECT_TRUE(base_file_.get()); |
192 return base_file_->CurrentSpeedAtTime(current_time); | 160 return base_file_->CurrentSpeedAtTime(current_time); |
193 } | 161 } |
194 | 162 |
195 base::TimeTicks StartTick() { | 163 base::TimeTicks StartTick() { |
196 EXPECT_TRUE(base_file_.get()); | 164 EXPECT_TRUE(base_file_.get()); |
197 return base_file_->start_tick_; | 165 return base_file_->start_tick_; |
198 } | 166 } |
199 | 167 |
200 void set_expected_error(DownloadInterruptReason err) { | 168 void set_expected_error(DownloadInterruptReason err) { |
201 expected_error_ = err; | 169 expected_error_ = err; |
202 } | 170 } |
203 | 171 |
204 void ExpectPermissionError(DownloadInterruptReason err) { | 172 void ExpectPermissionError(DownloadInterruptReason err) { |
205 EXPECT_TRUE(err == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR || | 173 EXPECT_TRUE(err == DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR || |
206 err == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED) | 174 err == DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED) |
207 << "Interrupt reason = " << err; | 175 << "Interrupt reason = " << err; |
208 } | 176 } |
209 | 177 |
178 template <size_t SZ> | |
179 static void ExpectHashValue(const uint8_t (&expected_hash)[SZ], | |
180 scoped_ptr<crypto::SecureHash> hash_state) { | |
181 std::vector<char> hash_value(hash_state->GetHashLength()); | |
svaldez
2016/03/10 17:45:33
Should this be vector<uint8_t>?
asanka
2016/03/11 16:25:09
Done.
| |
182 hash_state->Finish(&hash_value.front(), hash_value.size()); | |
183 ASSERT_EQ(hash_state->GetHashLength(), hash_value.size()); | |
svaldez
2016/03/10 17:45:33
Seems extraneous, since hash_value.size won't chan
asanka
2016/03/11 16:25:09
Indeed.
| |
184 ASSERT_EQ(SZ, hash_value.size()); | |
185 EXPECT_EQ(0, memcmp(expected_hash, &hash_value.front(), SZ)); | |
svaldez
2016/03/10 17:45:33
Use hash_value.size()?
asanka
2016/03/11 16:25:09
Done.
| |
186 } | |
187 | |
210 protected: | 188 protected: |
211 // BaseClass instance we are testing. | 189 // BaseClass instance we are testing. |
212 scoped_ptr<BaseFile> base_file_; | 190 scoped_ptr<BaseFile> base_file_; |
213 | 191 |
214 // Temporary directory for renamed downloads. | 192 // Temporary directory for renamed downloads. |
215 base::ScopedTempDir temp_dir_; | 193 base::ScopedTempDir temp_dir_; |
216 | 194 |
217 // Expect the file to survive deletion of the BaseFile instance. | 195 // Expect the file to survive deletion of the BaseFile instance. |
218 bool expect_file_survives_; | 196 bool expect_file_survives_; |
219 | 197 |
220 // Expect the file to be in progress. | 198 // Expect the file to be in progress. |
221 bool expect_in_progress_; | 199 bool expect_in_progress_; |
222 | 200 |
223 // Hash calculator. | |
224 scoped_ptr<crypto::SecureHash> secure_hash_; | |
225 | |
226 unsigned char sha256_hash_[crypto::kSHA256Length]; | |
227 | |
228 private: | 201 private: |
229 // Keep track of what data should be saved to the disk file. | 202 // Keep track of what data should be saved to the disk file. |
230 std::string expected_data_; | 203 std::string expected_data_; |
231 DownloadInterruptReason expected_error_; | 204 DownloadInterruptReason expected_error_; |
232 | 205 |
233 // Mock file thread to satisfy debug checks in BaseFile. | 206 // Mock file thread to satisfy debug checks in BaseFile. |
234 base::MessageLoop message_loop_; | 207 base::MessageLoop message_loop_; |
235 BrowserThreadImpl file_thread_; | 208 BrowserThreadImpl file_thread_; |
236 }; | 209 }; |
237 | 210 |
(...skipping 21 matching lines...) Expand all Loading... | |
259 TEST_F(BaseFileTest, WriteAndDetach) { | 232 TEST_F(BaseFileTest, WriteAndDetach) { |
260 ASSERT_TRUE(InitializeFile()); | 233 ASSERT_TRUE(InitializeFile()); |
261 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 234 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
262 base_file_->Finish(); | 235 base_file_->Finish(); |
263 base_file_->Detach(); | 236 base_file_->Detach(); |
264 expect_file_survives_ = true; | 237 expect_file_survives_ = true; |
265 } | 238 } |
266 | 239 |
267 // Write data to the file and detach it, and calculate its sha256 hash. | 240 // Write data to the file and detach it, and calculate its sha256 hash. |
268 TEST_F(BaseFileTest, WriteWithHashAndDetach) { | 241 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()); | 242 ASSERT_TRUE(InitializeFile()); |
278 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 243 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
279 base_file_->Finish(); | 244 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(); | 245 base_file_->Detach(); |
288 expect_file_survives_ = true; | 246 expect_file_survives_ = true; |
289 } | 247 } |
290 | 248 |
291 // Rename the file after writing to it, then detach. | 249 // Rename the file after writing to it, then detach. |
292 TEST_F(BaseFileTest, WriteThenRenameAndDetach) { | 250 TEST_F(BaseFileTest, WriteThenRenameAndDetach) { |
293 ASSERT_TRUE(InitializeFile()); | 251 ASSERT_TRUE(InitializeFile()); |
294 | 252 |
295 base::FilePath initial_path(base_file_->full_path()); | 253 base::FilePath initial_path(base_file_->full_path()); |
296 EXPECT_TRUE(base::PathExists(initial_path)); | 254 EXPECT_TRUE(base::PathExists(initial_path)); |
297 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); | 255 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); |
298 EXPECT_FALSE(base::PathExists(new_path)); | 256 EXPECT_FALSE(base::PathExists(new_path)); |
299 | 257 |
300 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 258 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
301 | 259 |
302 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); | 260 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); |
303 EXPECT_FALSE(base::PathExists(initial_path)); | 261 EXPECT_FALSE(base::PathExists(initial_path)); |
304 EXPECT_TRUE(base::PathExists(new_path)); | 262 EXPECT_TRUE(base::PathExists(new_path)); |
305 | 263 |
306 base_file_->Finish(); | 264 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); |
307 base_file_->Detach(); | 265 base_file_->Detach(); |
308 expect_file_survives_ = true; | 266 expect_file_survives_ = true; |
309 } | 267 } |
310 | 268 |
311 // Write data to the file once. | 269 // Write data to the file once. |
312 TEST_F(BaseFileTest, SingleWrite) { | 270 TEST_F(BaseFileTest, SingleWrite) { |
313 ASSERT_TRUE(InitializeFile()); | 271 ASSERT_TRUE(InitializeFile()); |
314 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 272 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
315 base_file_->Finish(); | 273 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); |
316 } | 274 } |
317 | 275 |
318 // Write data to the file multiple times. | 276 // Write data to the file multiple times. |
319 TEST_F(BaseFileTest, MultipleWrites) { | 277 TEST_F(BaseFileTest, MultipleWrites) { |
320 ASSERT_TRUE(InitializeFile()); | 278 ASSERT_TRUE(InitializeFile()); |
321 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 279 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
322 ASSERT_TRUE(AppendDataToFile(kTestData2)); | 280 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
323 ASSERT_TRUE(AppendDataToFile(kTestData3)); | 281 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
324 std::string hash; | 282 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 } | 283 } |
377 | 284 |
378 // Write data to the file multiple times, interrupt it, and continue using | 285 // Write data to the file multiple times, interrupt it, and continue using |
379 // another file. Calculate the resulting combined sha256 hash. | 286 // another file. Calculate the resulting combined sha256 hash. |
380 TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) { | 287 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()); | 288 ASSERT_TRUE(InitializeFile()); |
392 // Write some data | 289 // Write some data |
393 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 290 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
394 ASSERT_TRUE(AppendDataToFile(kTestData2)); | 291 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
395 // Get the hash state and file name. | 292 // Get the hash state and file name. |
396 std::string hash_state; | 293 scoped_ptr<crypto::SecureHash> hash_state = base_file_->Finish(); |
397 hash_state = base_file_->GetHashState(); | |
398 // Finish the file. | |
399 base_file_->Finish(); | |
400 | 294 |
401 base::FilePath new_file_path(temp_dir_.path().Append( | 295 base::FilePath new_file_path(temp_dir_.path().Append( |
402 base::FilePath(FILE_PATH_LITERAL("second_file")))); | 296 base::FilePath(FILE_PATH_LITERAL("second_file")))); |
403 | 297 |
404 ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path)); | 298 ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path)); |
405 | 299 |
406 // Create another file | 300 // Create another file |
407 BaseFile second_file(new_file_path, | 301 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, | 302 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
416 second_file.Initialize(base::FilePath())); | 303 second_file.Initialize(new_file_path, base::FilePath(), |
304 base::File(), base_file_->bytes_so_far(), | |
305 std::string(), std::move(hash_state))); | |
417 std::string data(kTestData3); | 306 std::string data(kTestData3); |
418 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 307 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
419 second_file.AppendDataToFile(data.data(), data.size())); | 308 second_file.AppendDataToFile(data.data(), data.size())); |
420 second_file.Finish(); | 309 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 } | 310 } |
428 | 311 |
429 // Rename the file after all writes to it. | 312 // Rename the file after all writes to it. |
430 TEST_F(BaseFileTest, WriteThenRename) { | 313 TEST_F(BaseFileTest, WriteThenRename) { |
431 ASSERT_TRUE(InitializeFile()); | 314 ASSERT_TRUE(InitializeFile()); |
432 | 315 |
433 base::FilePath initial_path(base_file_->full_path()); | 316 base::FilePath initial_path(base_file_->full_path()); |
434 EXPECT_TRUE(base::PathExists(initial_path)); | 317 EXPECT_TRUE(base::PathExists(initial_path)); |
435 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); | 318 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); |
436 EXPECT_FALSE(base::PathExists(new_path)); | 319 EXPECT_FALSE(base::PathExists(new_path)); |
437 | 320 |
438 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 321 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
439 | 322 |
440 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | 323 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
441 base_file_->Rename(new_path)); | 324 base_file_->Rename(new_path)); |
442 EXPECT_FALSE(base::PathExists(initial_path)); | 325 EXPECT_FALSE(base::PathExists(initial_path)); |
443 EXPECT_TRUE(base::PathExists(new_path)); | 326 EXPECT_TRUE(base::PathExists(new_path)); |
444 | 327 |
445 base_file_->Finish(); | 328 ExpectHashValue(kHashOfTestData1, base_file_->Finish()); |
446 } | 329 } |
447 | 330 |
448 // Rename the file while the download is still in progress. | 331 // Rename the file while the download is still in progress. |
449 TEST_F(BaseFileTest, RenameWhileInProgress) { | 332 TEST_F(BaseFileTest, RenameWhileInProgress) { |
450 ASSERT_TRUE(InitializeFile()); | 333 ASSERT_TRUE(InitializeFile()); |
451 | 334 |
452 base::FilePath initial_path(base_file_->full_path()); | 335 base::FilePath initial_path(base_file_->full_path()); |
453 EXPECT_TRUE(base::PathExists(initial_path)); | 336 EXPECT_TRUE(base::PathExists(initial_path)); |
454 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); | 337 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); |
455 EXPECT_FALSE(base::PathExists(new_path)); | 338 EXPECT_FALSE(base::PathExists(new_path)); |
456 | 339 |
457 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 340 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
458 | 341 |
459 EXPECT_TRUE(base_file_->in_progress()); | 342 EXPECT_TRUE(base_file_->in_progress()); |
460 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); | 343 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); |
461 EXPECT_FALSE(base::PathExists(initial_path)); | 344 EXPECT_FALSE(base::PathExists(initial_path)); |
462 EXPECT_TRUE(base::PathExists(new_path)); | 345 EXPECT_TRUE(base::PathExists(new_path)); |
463 | 346 |
464 ASSERT_TRUE(AppendDataToFile(kTestData2)); | 347 ASSERT_TRUE(AppendDataToFile(kTestData2)); |
348 ASSERT_TRUE(AppendDataToFile(kTestData3)); | |
465 | 349 |
466 base_file_->Finish(); | 350 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); |
467 } | 351 } |
468 | 352 |
469 // Test that a failed rename reports the correct error. | 353 // Test that a failed rename reports the correct error. |
470 TEST_F(BaseFileTest, RenameWithError) { | 354 TEST_F(BaseFileTest, RenameWithError) { |
471 ASSERT_TRUE(InitializeFile()); | 355 ASSERT_TRUE(InitializeFile()); |
472 | 356 |
473 // TestDir is a subdirectory in |temp_dir_| that we will make read-only so | 357 // TestDir is a subdirectory in |temp_dir_| that we will make read-only so |
474 // that the rename will fail. | 358 // that the rename will fail. |
475 base::FilePath test_dir(temp_dir_.path().AppendASCII("TestDir")); | 359 base::FilePath test_dir(temp_dir_.path().AppendASCII("TestDir")); |
476 ASSERT_TRUE(base::CreateDirectory(test_dir)); | 360 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. | 402 // Try to rename again, just for kicks. It should still fail. |
519 ExpectPermissionError(base_file_->Rename(new_path)); | 403 ExpectPermissionError(base_file_->Rename(new_path)); |
520 } | 404 } |
521 | 405 |
522 // Now that TestDir is writeable again, we should be able to successfully | 406 // Now that TestDir is writeable again, we should be able to successfully |
523 // rename the file. | 407 // rename the file. |
524 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); | 408 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); |
525 ASSERT_EQ(new_path.value(), base_file_->full_path().value()); | 409 ASSERT_EQ(new_path.value(), base_file_->full_path().value()); |
526 ASSERT_TRUE(AppendDataToFile(kTestData3)); | 410 ASSERT_TRUE(AppendDataToFile(kTestData3)); |
527 | 411 |
528 base_file_->Finish(); | 412 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 } | 413 } |
538 | 414 |
539 // Test that a failed write reports an error. | 415 // Test that a failed write reports an error. |
540 TEST_F(BaseFileTest, WriteWithError) { | 416 TEST_F(BaseFileTest, WriteWithError) { |
541 base::FilePath path; | 417 base::FilePath path; |
542 ASSERT_TRUE(base::CreateTemporaryFile(&path)); | 418 ASSERT_TRUE(base::CreateTemporaryFile(&path)); |
543 | 419 |
544 // Pass a file handle which was opened without the WRITE flag. | 420 // Pass a file handle which was opened without the WRITE flag. |
545 // This should result in an error when writing. | 421 // This should result in an error when writing. |
546 base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ); | 422 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(), | 423 base_file_.reset(new BaseFile(net::BoundNetLog())); |
548 std::move(file), net::BoundNetLog())); | 424 EXPECT_EQ( |
549 ASSERT_TRUE(InitializeFile()); | 425 DOWNLOAD_INTERRUPT_REASON_NONE, |
426 base_file_->Initialize(path, base::FilePath(), std::move(file), 0, | |
427 std::string(), scoped_ptr<crypto::SecureHash>())); | |
550 #if defined(OS_WIN) | 428 #if defined(OS_WIN) |
551 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); | 429 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); |
552 #elif defined (OS_POSIX) | 430 #elif defined (OS_POSIX) |
553 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 431 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
554 #endif | 432 #endif |
555 ASSERT_FALSE(AppendDataToFile(kTestData1)); | 433 ASSERT_FALSE(AppendDataToFile(kTestData1)); |
556 base_file_->Finish(); | 434 base_file_->Finish(); |
557 } | 435 } |
558 | 436 |
559 // Try to write to uninitialized file. | 437 // Try to write to uninitialized file. |
(...skipping 13 matching lines...) Expand all Loading... | |
573 CreateFileWithName(base_file_->full_path()); | 451 CreateFileWithName(base_file_->full_path()); |
574 | 452 |
575 ASSERT_TRUE(AppendDataToFile(kTestData1)); | 453 ASSERT_TRUE(AppendDataToFile(kTestData1)); |
576 base_file_->Finish(); | 454 base_file_->Finish(); |
577 } | 455 } |
578 | 456 |
579 // Create a file and append to it. | 457 // Create a file and append to it. |
580 TEST_F(BaseFileTest, AppendToBaseFile) { | 458 TEST_F(BaseFileTest, AppendToBaseFile) { |
581 // Create a new file. | 459 // Create a new file. |
582 base::FilePath existing_file_name = CreateTestFile(); | 460 base::FilePath existing_file_name = CreateTestFile(); |
583 | |
584 set_expected_data(kTestData4); | 461 set_expected_data(kTestData4); |
585 | 462 |
586 // Use the file we've just created. | 463 // Use the file we've just created. |
587 base_file_.reset(new BaseFile(existing_file_name, | 464 base_file_.reset(new BaseFile(net::BoundNetLog())); |
588 GURL(), | 465 ASSERT_EQ( |
589 GURL(), | 466 DOWNLOAD_INTERRUPT_REASON_NONE, |
590 kTestDataLength4, | 467 base_file_->Initialize(existing_file_name, base::FilePath(), base::File(), |
591 false, | 468 kTestDataLength4, std::string(), |
592 std::string(), | 469 scoped_ptr<crypto::SecureHash>())); |
593 base::File(), | |
594 net::BoundNetLog())); | |
595 | |
596 ASSERT_TRUE(InitializeFile()); | |
597 | 470 |
598 const base::FilePath file_name = base_file_->full_path(); | 471 const base::FilePath file_name = base_file_->full_path(); |
599 EXPECT_NE(base::FilePath::StringType(), file_name.value()); | 472 EXPECT_NE(base::FilePath::StringType(), file_name.value()); |
600 | 473 |
601 // Write into the file. | 474 // Write into the file. |
602 EXPECT_TRUE(AppendDataToFile(kTestData1)); | 475 EXPECT_TRUE(AppendDataToFile(kTestData1)); |
603 | 476 |
604 base_file_->Finish(); | 477 base_file_->Finish(); |
605 base_file_->Detach(); | 478 base_file_->Detach(); |
606 expect_file_survives_ = true; | 479 expect_file_survives_ = true; |
607 } | 480 } |
608 | 481 |
609 // Create a read-only file and attempt to write to it. | 482 // Create a read-only file and attempt to write to it. |
610 TEST_F(BaseFileTest, ReadonlyBaseFile) { | 483 TEST_F(BaseFileTest, ReadonlyBaseFile) { |
611 // Create a new file. | 484 // Create a new file. |
612 base::FilePath readonly_file_name = CreateTestFile(); | 485 base::FilePath readonly_file_name = CreateTestFile(); |
613 | 486 |
614 // Restore permissions to the file when we are done with this test. | 487 // Restore permissions to the file when we are done with this test. |
615 base::FilePermissionRestorer restore_permissions(readonly_file_name); | 488 base::FilePermissionRestorer restore_permissions(readonly_file_name); |
616 | 489 |
617 // Make it read-only. | 490 // Make it read-only. |
618 EXPECT_TRUE(base::MakeFileUnwritable(readonly_file_name)); | 491 EXPECT_TRUE(base::MakeFileUnwritable(readonly_file_name)); |
619 | 492 |
620 // Try to overwrite it. | 493 // Try to overwrite it. |
621 base_file_.reset(new BaseFile(readonly_file_name, | 494 base_file_.reset(new BaseFile(net::BoundNetLog())); |
622 GURL(), | 495 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, |
623 GURL(), | 496 base_file_->Initialize(readonly_file_name, base::FilePath(), |
624 0, | 497 base::File(), 0, std::string(), |
625 false, | 498 scoped_ptr<crypto::SecureHash>())); |
626 std::string(), | |
627 base::File(), | |
628 net::BoundNetLog())); | |
629 | 499 |
630 expect_in_progress_ = false; | 500 expect_in_progress_ = false; |
631 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); | |
632 EXPECT_FALSE(InitializeFile()); | |
633 | 501 |
634 const base::FilePath file_name = base_file_->full_path(); | 502 const base::FilePath file_name = base_file_->full_path(); |
635 EXPECT_NE(base::FilePath::StringType(), file_name.value()); | 503 EXPECT_NE(base::FilePath::StringType(), file_name.value()); |
636 | 504 |
637 // Write into the file. | 505 // Write into the file. |
638 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); | 506 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); |
639 EXPECT_FALSE(AppendDataToFile(kTestData1)); | 507 EXPECT_FALSE(AppendDataToFile(kTestData1)); |
640 | 508 |
641 base_file_->Finish(); | 509 base_file_->Finish(); |
642 base_file_->Detach(); | 510 base_file_->Detach(); |
643 expect_file_survives_ = true; | 511 expect_file_survives_ = true; |
644 } | 512 } |
645 | 513 |
646 TEST_F(BaseFileTest, IsEmptyHash) { | 514 // Open an existing file and continue writing to it. The hash of the partial |
647 std::string empty(crypto::kSHA256Length, '\x00'); | 515 // file is known and matches the existing contents. |
648 EXPECT_TRUE(BaseFile::IsEmptyHash(empty)); | 516 TEST_F(BaseFileTest, ExistingBaseFileKnownHash) { |
649 std::string not_empty(crypto::kSHA256Length, '\x01'); | 517 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); |
650 EXPECT_FALSE(BaseFile::IsEmptyHash(not_empty)); | 518 ASSERT_TRUE(base::WriteFile(file_path, kTestData1, kTestDataLength1)); |
651 EXPECT_FALSE(BaseFile::IsEmptyHash(std::string())); | |
652 | 519 |
653 std::string also_not_empty = empty; | 520 std::string hash_so_far(std::begin(kHashOfTestData1), |
654 also_not_empty[crypto::kSHA256Length - 1] = '\x01'; | 521 std::end(kHashOfTestData1)); |
655 EXPECT_FALSE(BaseFile::IsEmptyHash(also_not_empty)); | 522 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, |
523 base_file_->Initialize(file_path, base::FilePath(), base::File(), | |
524 kTestDataLength1, hash_so_far, | |
525 scoped_ptr<crypto::SecureHash>())); | |
526 set_expected_data(kTestData1); | |
527 ASSERT_TRUE(AppendDataToFile(kTestData2)); | |
528 ASSERT_TRUE(AppendDataToFile(kTestData3)); | |
529 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); | |
530 } | |
531 | |
532 // Open an existing file and continue writing to it. The hash of the partial | |
533 // file is unknown. | |
534 TEST_F(BaseFileTest, ExistingBaseFileUnknownHash) { | |
535 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | |
536 ASSERT_TRUE(base::WriteFile(file_path, kTestData1, kTestDataLength1)); | |
537 | |
538 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | |
539 base_file_->Initialize(file_path, base::FilePath(), base::File(), | |
540 kTestDataLength1, std::string(), | |
541 scoped_ptr<crypto::SecureHash>())); | |
542 set_expected_data(kTestData1); | |
543 ASSERT_TRUE(AppendDataToFile(kTestData2)); | |
544 ASSERT_TRUE(AppendDataToFile(kTestData3)); | |
545 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); | |
546 } | |
547 | |
548 // Open an existing file. The contentsof the file doesn't match the known hash. | |
549 TEST_F(BaseFileTest, ExistingBaseFileIncorrectHash) { | |
550 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | |
551 ASSERT_TRUE(base::WriteFile(file_path, kTestData2, kTestDataLength2)); | |
552 | |
553 std::string hash_so_far(std::begin(kHashOfTestData1), | |
554 std::end(kHashOfTestData1)); | |
555 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, | |
556 base_file_->Initialize(file_path, base::FilePath(), base::File(), | |
557 kTestDataLength2, hash_so_far, | |
558 scoped_ptr<crypto::SecureHash>())); | |
559 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); | |
560 } | |
561 | |
562 // Open a large existing file with a known hash and continue writing to it. | |
563 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeKnownHash) { | |
564 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | |
565 std::string big_buffer(1024 * 200, 'a'); | |
566 ASSERT_TRUE(base::WriteFile(file_path, big_buffer.data(), big_buffer.size())); | |
567 | |
568 // Hash of partial file (1024*200 * 'a') | |
569 const uint8_t kExpectedPartialHash[] = { | |
570 0x4b, 0x4f, 0x0f, 0x46, 0xac, 0x02, 0xd1, 0x77, 0xde, 0xa0, 0xab, | |
571 0x36, 0xa6, 0x6a, 0x65, 0x78, 0x40, 0xe2, 0xfb, 0x98, 0xb2, 0x0b, | |
572 0xb2, 0x7a, 0x68, 0x8d, 0xb4, 0xd8, 0xea, 0x9c, 0xd2, 0x2c}; | |
573 | |
574 // Hash of entire file (1024*400 * 'a') | |
575 const uint8_t kExpectedFullHash[] = { | |
576 0x0c, 0xe9, 0xf6, 0x78, 0x6b, 0x0f, 0x58, 0x49, 0x36, 0xe8, 0x83, | |
577 0xc5, 0x09, 0x16, 0xbc, 0x5e, 0x2d, 0x07, 0x95, 0xb9, 0x42, 0x20, | |
578 0x41, 0x7c, 0xb3, 0x38, 0xd3, 0xf4, 0xe0, 0x78, 0x89, 0x46}; | |
579 | |
580 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | |
581 base_file_->Initialize(file_path, base::FilePath(), base::File(), | |
582 big_buffer.size(), | |
583 std::string(std::begin(kExpectedPartialHash), | |
584 std::end(kExpectedPartialHash)), | |
585 scoped_ptr<crypto::SecureHash>())); | |
586 set_expected_data(big_buffer); // Contents of the file on Open. | |
587 ASSERT_TRUE(AppendDataToFile(big_buffer)); | |
588 ExpectHashValue(kExpectedFullHash, base_file_->Finish()); | |
589 } | |
590 | |
591 // Open a large existing file. The contents doesn't match the known hash. | |
592 TEST_F(BaseFileTest, ExistingBaseFileLargeSizeIncorrectHash) { | |
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 // Incorrect hash of partial file (1024*200 * 'a') | |
598 const uint8_t kExpectedPartialHash[] = { | |
599 0xc2, 0xa9, 0x08, 0xd9, 0x8f, 0x5d, 0xf9, 0x87, 0xad, 0xe4, 0x1b, | |
600 0x5f, 0xce, 0x21, 0x30, 0x67, 0xef, 0x6c, 0xc2, 0x1e, 0xf2, 0x24, | |
601 0x02, 0x12, 0xa4, 0x1e, 0x54, 0xb5, 0xe7, 0xc2, 0x8a, 0xe5}; | |
602 | |
603 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, | |
604 base_file_->Initialize(file_path, base::FilePath(), base::File(), | |
605 big_buffer.size(), | |
606 std::string(std::begin(kExpectedPartialHash), | |
607 std::end(kExpectedPartialHash)), | |
608 scoped_ptr<crypto::SecureHash>())); | |
609 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH); | |
610 } | |
611 | |
612 // Open an existing file. The size of the file is too short. | |
613 TEST_F(BaseFileTest, ExistingBaseFileTooShort) { | |
614 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | |
615 ASSERT_TRUE(base::WriteFile(file_path, kTestData1, kTestDataLength1)); | |
616 | |
617 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT, | |
618 base_file_->Initialize(file_path, base::FilePath(), base::File(), | |
619 kTestDataLength1 + 1, std::string(), | |
620 scoped_ptr<crypto::SecureHash>())); | |
621 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT); | |
622 } | |
623 | |
624 // Open an existing file. The size is larger than expected. | |
625 TEST_F(BaseFileTest, ExistingBaseFileKnownHashTooLong) { | |
626 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | |
627 std::string contents; | |
628 contents.append(kTestData1); | |
629 contents.append("Something extra"); | |
630 ASSERT_TRUE(base::WriteFile(file_path, contents.data(), contents.size())); | |
631 | |
632 std::string hash_so_far(std::begin(kHashOfTestData1), | |
633 std::end(kHashOfTestData1)); | |
634 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | |
635 base_file_->Initialize(file_path, base::FilePath(), base::File(), | |
636 kTestDataLength1, hash_so_far, | |
637 scoped_ptr<crypto::SecureHash>())); | |
638 set_expected_data(kTestData1); // Our starting position. | |
639 ASSERT_TRUE(AppendDataToFile(kTestData2)); | |
640 ASSERT_TRUE(AppendDataToFile(kTestData3)); | |
641 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); | |
642 } | |
643 | |
644 // Open an existing file. The size is large than expected and the hash is | |
645 // unknown. | |
646 TEST_F(BaseFileTest, ExistingBaseFileUnknownHashTooLong) { | |
647 base::FilePath file_path = temp_dir_.path().AppendASCII("existing"); | |
648 std::string contents; | |
649 contents.append(kTestData1); | |
650 contents.append("Something extra"); | |
651 ASSERT_TRUE(base::WriteFile(file_path, contents.data(), contents.size())); | |
652 | |
653 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, | |
654 base_file_->Initialize(file_path, base::FilePath(), base::File(), | |
655 kTestDataLength1, std::string(), | |
656 scoped_ptr<crypto::SecureHash>())); | |
657 set_expected_data(kTestData1); | |
658 ASSERT_TRUE(AppendDataToFile(kTestData2)); | |
659 ASSERT_TRUE(AppendDataToFile(kTestData3)); | |
660 ExpectHashValue(kHashOfTestData1To3, base_file_->Finish()); | |
656 } | 661 } |
657 | 662 |
658 // Test that a temporary file is created in the default download directory. | 663 // Test that a temporary file is created in the default download directory. |
659 TEST_F(BaseFileTest, CreatedInDefaultDirectory) { | 664 TEST_F(BaseFileTest, CreatedInDefaultDirectory) { |
660 ASSERT_TRUE(base_file_->full_path().empty()); | 665 ASSERT_TRUE(base_file_->full_path().empty()); |
661 ASSERT_TRUE(InitializeFile()); | 666 ASSERT_TRUE(InitializeFile()); |
662 EXPECT_FALSE(base_file_->full_path().empty()); | 667 EXPECT_FALSE(base_file_->full_path().empty()); |
663 | 668 |
664 // On Windows, CreateTemporaryFileInDir() will cause a path with short names | 669 // 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 | 670 // to be expanded into a path with long names. Thus temp_dir.path() might not |
(...skipping 18 matching lines...) Expand all Loading... | |
684 | 689 |
685 const char kData[] = "hello"; | 690 const char kData[] = "hello"; |
686 const int kDataLength = static_cast<int>(arraysize(kData) - 1); | 691 const int kDataLength = static_cast<int>(arraysize(kData) - 1); |
687 ASSERT_EQ(kDataLength, base::WriteFile(full_path, kData, kDataLength)); | 692 ASSERT_EQ(kDataLength, base::WriteFile(full_path, kData, kDataLength)); |
688 // The file that we created here should stick around when the BaseFile is | 693 // The file that we created here should stick around when the BaseFile is |
689 // destroyed during TearDown. | 694 // destroyed during TearDown. |
690 expect_file_survives_ = true; | 695 expect_file_survives_ = true; |
691 } | 696 } |
692 | 697 |
693 } // namespace content | 698 } // namespace content |
OLD | NEW |