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 3 // found in the LICENSE file. 4 5 #include "content/browser/download/base_file.h" 6 7 #include "base/file_util.h" 8 #include "base/files/scoped_temp_dir.h" 9 #include "base/logging.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/strings/string_number_conversions.h" 12 #include "base/test/test_file_util.h" 13 #include "content/browser/browser_thread_impl.h" 14 #include "content/public/browser/download_interrupt_reasons.h" 15 #include "crypto/secure_hash.h" 16 #include "net/base/file_stream.h" 17 #include "net/base/mock_file_stream.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 namespace content { 21 namespace { 22 23 const char kTestData1[] = "Let's write some data to the file!\n"; 24 const char kTestData2[] = "Writing more data.\n"; 25 const char kTestData3[] = "Final line."; 26 const char kTestData4[] = "supercalifragilisticexpialidocious"; 27 const int kTestDataLength1 = arraysize(kTestData1) - 1; 28 const int kTestDataLength2 = arraysize(kTestData2) - 1; 29 const int kTestDataLength3 = arraysize(kTestData3) - 1; 30 const int kTestDataLength4 = arraysize(kTestData4) - 1; 31 const int kElapsedTimeSeconds = 5; 32 const base::TimeDelta kElapsedTimeDelta = base::TimeDelta::FromSeconds( 33 kElapsedTimeSeconds); 34 35 } // namespace 36 37 class BaseFileTest : public testing::Test { 38 public: 39 static const size_t kSha256HashLen = 32; 40 static const unsigned char kEmptySha256Hash[kSha256HashLen]; 41 42 BaseFileTest() 43 : expect_file_survives_(false), 44 expect_in_progress_(true), 45 expected_error_(DOWNLOAD_INTERRUPT_REASON_NONE), 46 file_thread_(BrowserThread::FILE, &message_loop_) { 47 } 48 49 virtual void SetUp() { 50 ResetHash(); 51 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 52 base_file_.reset(new BaseFile(base::FilePath(), 53 GURL(), 54 GURL(), 55 0, 56 false, 57 std::string(), 58 scoped_ptr<net::FileStream>(), 59 net::BoundNetLog())); 60 } 61 62 virtual void TearDown() { 63 EXPECT_FALSE(base_file_->in_progress()); 64 if (!expected_error_) { 65 EXPECT_EQ(static_cast<int64>(expected_data_.size()), 66 base_file_->bytes_so_far()); 67 } 68 69 base::FilePath full_path = base_file_->full_path(); 70 71 if (!expected_data_.empty() && !expected_error_) { 72 // Make sure the data has been properly written to disk. 73 std::string disk_data; 74 EXPECT_TRUE(base::ReadFileToString(full_path, &disk_data)); 75 EXPECT_EQ(expected_data_, disk_data); 76 } 77 78 // Make sure the mock BrowserThread outlives the BaseFile to satisfy 79 // thread checks inside it. 80 base_file_.reset(); 81 82 EXPECT_EQ(expect_file_survives_, base::PathExists(full_path)); 83 } 84 85 void ResetHash() { 86 secure_hash_.reset(crypto::SecureHash::Create(crypto::SecureHash::SHA256)); 87 memcpy(sha256_hash_, kEmptySha256Hash, kSha256HashLen); 88 } 89 90 void UpdateHash(const char* data, size_t length) { 91 secure_hash_->Update(data, length); 92 } 93 94 std::string GetFinalHash() { 95 std::string hash; 96 secure_hash_->Finish(sha256_hash_, kSha256HashLen); 97 hash.assign(reinterpret_cast<const char*>(sha256_hash_), 98 sizeof(sha256_hash_)); 99 return hash; 100 } 101 102 void MakeFileWithHash() { 103 base_file_.reset(new BaseFile(base::FilePath(), 104 GURL(), 105 GURL(), 106 0, 107 true, 108 std::string(), 109 scoped_ptr<net::FileStream>(), 110 net::BoundNetLog())); 111 } 112 113 bool InitializeFile() { 114 DownloadInterruptReason result = base_file_->Initialize(temp_dir_.path()); 115 EXPECT_EQ(expected_error_, result); 116 return result == DOWNLOAD_INTERRUPT_REASON_NONE; 117 } 118 119 bool AppendDataToFile(const std::string& data) { 120 EXPECT_EQ(expect_in_progress_, base_file_->in_progress()); 121 DownloadInterruptReason result = 122 base_file_->AppendDataToFile(data.data(), data.size()); 123 if (result == DOWNLOAD_INTERRUPT_REASON_NONE) 124 EXPECT_TRUE(expect_in_progress_) << " result = " << result; 125 126 EXPECT_EQ(expected_error_, result); 127 if (base_file_->in_progress()) { 128 expected_data_ += data; 129 if (expected_error_ == DOWNLOAD_INTERRUPT_REASON_NONE) { 130 EXPECT_EQ(static_cast<int64>(expected_data_.size()), 131 base_file_->bytes_so_far()); 132 } 133 } 134 return result == DOWNLOAD_INTERRUPT_REASON_NONE; 135 } 136 137 void set_expected_data(const std::string& data) { expected_data_ = data; } 138 139 // Helper functions. 140 // Create a file. Returns the complete file path. 141 base::FilePath CreateTestFile() { 142 base::FilePath file_name; 143 BaseFile file(base::FilePath(), 144 GURL(), 145 GURL(), 146 0, 147 false, 148 std::string(), 149 scoped_ptr<net::FileStream>(), 150 net::BoundNetLog()); 151 152 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 153 file.Initialize(temp_dir_.path())); 154 file_name = file.full_path(); 155 EXPECT_NE(base::FilePath::StringType(), file_name.value()); 156 157 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 158 file.AppendDataToFile(kTestData4, kTestDataLength4)); 159 160 // Keep the file from getting deleted when existing_file_name is deleted. 161 file.Detach(); 162 163 return file_name; 164 } 165 166 // Create a file with the specified file name. 167 void CreateFileWithName(const base::FilePath& file_name) { 168 EXPECT_NE(base::FilePath::StringType(), file_name.value()); 169 BaseFile duplicate_file(file_name, 170 GURL(), 171 GURL(), 172 0, 173 false, 174 std::string(), 175 scoped_ptr<net::FileStream>(), 176 net::BoundNetLog()); 177 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 178 duplicate_file.Initialize(temp_dir_.path())); 179 // Write something into it. 180 duplicate_file.AppendDataToFile(kTestData4, kTestDataLength4); 181 // Detach the file so it isn't deleted on destruction of |duplicate_file|. 182 duplicate_file.Detach(); 183 } 184 185 int64 CurrentSpeedAtTime(base::TimeTicks current_time) { 186 EXPECT_TRUE(base_file_.get()); 187 return base_file_->CurrentSpeedAtTime(current_time); 188 } 189 190 base::TimeTicks StartTick() { 191 EXPECT_TRUE(base_file_.get()); 192 return base_file_->start_tick_; 193 } 194 195 void set_expected_error(DownloadInterruptReason err) { 196 expected_error_ = err; 197 } 198 199 protected: 200 linked_ptr<net::testing::MockFileStream> mock_file_stream_; 201 202 // BaseClass instance we are testing. 203 scoped_ptr<BaseFile> base_file_; 204 205 // Temporary directory for renamed downloads. 206 base::ScopedTempDir temp_dir_; 207 208 // Expect the file to survive deletion of the BaseFile instance. 209 bool expect_file_survives_; 210 211 // Expect the file to be in progress. 212 bool expect_in_progress_; 213 214 // Hash calculator. 215 scoped_ptr<crypto::SecureHash> secure_hash_; 216 217 unsigned char sha256_hash_[kSha256HashLen]; 218 219 private: 220 // Keep track of what data should be saved to the disk file. 221 std::string expected_data_; 222 DownloadInterruptReason expected_error_; 223 224 // Mock file thread to satisfy debug checks in BaseFile. 225 base::MessageLoop message_loop_; 226 BrowserThreadImpl file_thread_; 227 }; 228 229 // This will initialize the entire array to zero. 230 const unsigned char BaseFileTest::kEmptySha256Hash[] = { 0 }; 231 232 // Test the most basic scenario: just create the object and do a sanity check 233 // on all its accessors. This is actually a case that rarely happens 234 // in production, where we would at least Initialize it. 235 TEST_F(BaseFileTest, CreateDestroy) { 236 EXPECT_EQ(base::FilePath().value(), base_file_->full_path().value()); 237 } 238 239 // Cancel the download explicitly. 240 TEST_F(BaseFileTest, Cancel) { 241 ASSERT_TRUE(InitializeFile()); 242 EXPECT_TRUE(base::PathExists(base_file_->full_path())); 243 base_file_->Cancel(); 244 EXPECT_FALSE(base::PathExists(base_file_->full_path())); 245 EXPECT_NE(base::FilePath().value(), base_file_->full_path().value()); 246 } 247 248 // Write data to the file and detach it, so it doesn't get deleted 249 // automatically when base_file_ is destructed. 250 TEST_F(BaseFileTest, WriteAndDetach) { 251 ASSERT_TRUE(InitializeFile()); 252 ASSERT_TRUE(AppendDataToFile(kTestData1)); 253 base_file_->Finish(); 254 base_file_->Detach(); 255 expect_file_survives_ = true; 256 } 257 258 // Write data to the file and detach it, and calculate its sha256 hash. 259 TEST_F(BaseFileTest, WriteWithHashAndDetach) { 260 // Calculate the final hash. 261 ResetHash(); 262 UpdateHash(kTestData1, kTestDataLength1); 263 std::string expected_hash = GetFinalHash(); 264 std::string expected_hash_hex = 265 base::HexEncode(expected_hash.data(), expected_hash.size()); 266 267 MakeFileWithHash(); 268 ASSERT_TRUE(InitializeFile()); 269 ASSERT_TRUE(AppendDataToFile(kTestData1)); 270 base_file_->Finish(); 271 272 std::string hash; 273 base_file_->GetHash(&hash); 274 EXPECT_EQ("0B2D3F3F7943AD64B860DF94D05CB56A8A97C6EC5768B5B70B930C5AA7FA9ADE", 275 expected_hash_hex); 276 EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size())); 277 278 base_file_->Detach(); 279 expect_file_survives_ = true; 280 } 281 282 // Rename the file after writing to it, then detach. 283 TEST_F(BaseFileTest, WriteThenRenameAndDetach) { 284 ASSERT_TRUE(InitializeFile()); 285 286 base::FilePath initial_path(base_file_->full_path()); 287 EXPECT_TRUE(base::PathExists(initial_path)); 288 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); 289 EXPECT_FALSE(base::PathExists(new_path)); 290 291 ASSERT_TRUE(AppendDataToFile(kTestData1)); 292 293 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); 294 EXPECT_FALSE(base::PathExists(initial_path)); 295 EXPECT_TRUE(base::PathExists(new_path)); 296 297 base_file_->Finish(); 298 base_file_->Detach(); 299 expect_file_survives_ = true; 300 } 301 302 // Write data to the file once. 303 TEST_F(BaseFileTest, SingleWrite) { 304 ASSERT_TRUE(InitializeFile()); 305 ASSERT_TRUE(AppendDataToFile(kTestData1)); 306 base_file_->Finish(); 307 } 308 309 // Write data to the file multiple times. 310 TEST_F(BaseFileTest, MultipleWrites) { 311 ASSERT_TRUE(InitializeFile()); 312 ASSERT_TRUE(AppendDataToFile(kTestData1)); 313 ASSERT_TRUE(AppendDataToFile(kTestData2)); 314 ASSERT_TRUE(AppendDataToFile(kTestData3)); 315 std::string hash; 316 EXPECT_FALSE(base_file_->GetHash(&hash)); 317 base_file_->Finish(); 318 } 319 320 // Write data to the file once and calculate its sha256 hash. 321 TEST_F(BaseFileTest, SingleWriteWithHash) { 322 // Calculate the final hash. 323 ResetHash(); 324 UpdateHash(kTestData1, kTestDataLength1); 325 std::string expected_hash = GetFinalHash(); 326 std::string expected_hash_hex = 327 base::HexEncode(expected_hash.data(), expected_hash.size()); 328 329 MakeFileWithHash(); 330 ASSERT_TRUE(InitializeFile()); 331 // Can get partial hash states before Finish() is called. 332 EXPECT_STRNE(std::string().c_str(), base_file_->GetHashState().c_str()); 333 ASSERT_TRUE(AppendDataToFile(kTestData1)); 334 EXPECT_STRNE(std::string().c_str(), base_file_->GetHashState().c_str()); 335 base_file_->Finish(); 336 337 std::string hash; 338 base_file_->GetHash(&hash); 339 EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size())); 340 } 341 342 // Write data to the file multiple times and calculate its sha256 hash. 343 TEST_F(BaseFileTest, MultipleWritesWithHash) { 344 // Calculate the final hash. 345 ResetHash(); 346 UpdateHash(kTestData1, kTestDataLength1); 347 UpdateHash(kTestData2, kTestDataLength2); 348 UpdateHash(kTestData3, kTestDataLength3); 349 std::string expected_hash = GetFinalHash(); 350 std::string expected_hash_hex = 351 base::HexEncode(expected_hash.data(), expected_hash.size()); 352 353 std::string hash; 354 MakeFileWithHash(); 355 ASSERT_TRUE(InitializeFile()); 356 ASSERT_TRUE(AppendDataToFile(kTestData1)); 357 ASSERT_TRUE(AppendDataToFile(kTestData2)); 358 ASSERT_TRUE(AppendDataToFile(kTestData3)); 359 // No hash before Finish() is called. 360 EXPECT_FALSE(base_file_->GetHash(&hash)); 361 base_file_->Finish(); 362 363 EXPECT_TRUE(base_file_->GetHash(&hash)); 364 EXPECT_EQ("CBF68BF10F8003DB86B31343AFAC8C7175BD03FB5FC905650F8C80AF087443A8", 365 expected_hash_hex); 366 EXPECT_EQ(expected_hash_hex, base::HexEncode(hash.data(), hash.size())); 367 } 368 369 // Write data to the file multiple times, interrupt it, and continue using 370 // another file. Calculate the resulting combined sha256 hash. 371 TEST_F(BaseFileTest, MultipleWritesInterruptedWithHash) { 372 // Calculate the final hash. 373 ResetHash(); 374 UpdateHash(kTestData1, kTestDataLength1); 375 UpdateHash(kTestData2, kTestDataLength2); 376 UpdateHash(kTestData3, kTestDataLength3); 377 std::string expected_hash = GetFinalHash(); 378 std::string expected_hash_hex = 379 base::HexEncode(expected_hash.data(), expected_hash.size()); 380 381 MakeFileWithHash(); 382 ASSERT_TRUE(InitializeFile()); 383 // Write some data 384 ASSERT_TRUE(AppendDataToFile(kTestData1)); 385 ASSERT_TRUE(AppendDataToFile(kTestData2)); 386 // Get the hash state and file name. 387 std::string hash_state; 388 hash_state = base_file_->GetHashState(); 389 // Finish the file. 390 base_file_->Finish(); 391 392 base::FilePath new_file_path(temp_dir_.path().Append( 393 base::FilePath(FILE_PATH_LITERAL("second_file")))); 394 395 ASSERT_TRUE(base::CopyFile(base_file_->full_path(), new_file_path)); 396 397 // Create another file 398 BaseFile second_file(new_file_path, 399 GURL(), 400 GURL(), 401 base_file_->bytes_so_far(), 402 true, 403 hash_state, 404 scoped_ptr<net::FileStream>(), 405 net::BoundNetLog()); 406 ASSERT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 407 second_file.Initialize(base::FilePath())); 408 std::string data(kTestData3); 409 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 410 second_file.AppendDataToFile(data.data(), data.size())); 411 second_file.Finish(); 412 413 std::string hash; 414 EXPECT_TRUE(second_file.GetHash(&hash)); 415 // This will fail until getting the hash state is supported in SecureHash. 416 EXPECT_STREQ(expected_hash_hex.c_str(), 417 base::HexEncode(hash.data(), hash.size()).c_str()); 418 } 419 420 // Rename the file after all writes to it. 421 TEST_F(BaseFileTest, WriteThenRename) { 422 ASSERT_TRUE(InitializeFile()); 423 424 base::FilePath initial_path(base_file_->full_path()); 425 EXPECT_TRUE(base::PathExists(initial_path)); 426 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); 427 EXPECT_FALSE(base::PathExists(new_path)); 428 429 ASSERT_TRUE(AppendDataToFile(kTestData1)); 430 431 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, 432 base_file_->Rename(new_path)); 433 EXPECT_FALSE(base::PathExists(initial_path)); 434 EXPECT_TRUE(base::PathExists(new_path)); 435 436 base_file_->Finish(); 437 } 438 439 // Rename the file while the download is still in progress. 440 TEST_F(BaseFileTest, RenameWhileInProgress) { 441 ASSERT_TRUE(InitializeFile()); 442 443 base::FilePath initial_path(base_file_->full_path()); 444 EXPECT_TRUE(base::PathExists(initial_path)); 445 base::FilePath new_path(temp_dir_.path().AppendASCII("NewFile")); 446 EXPECT_FALSE(base::PathExists(new_path)); 447 448 ASSERT_TRUE(AppendDataToFile(kTestData1)); 449 450 EXPECT_TRUE(base_file_->in_progress()); 451 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_NONE, base_file_->Rename(new_path)); 452 EXPECT_FALSE(base::PathExists(initial_path)); 453 EXPECT_TRUE(base::PathExists(new_path)); 454 455 ASSERT_TRUE(AppendDataToFile(kTestData2)); 456 457 base_file_->Finish(); 458 } 459 460 // Test that a failed rename reports the correct error. 461 TEST_F(BaseFileTest, RenameWithError) { 462 ASSERT_TRUE(InitializeFile()); 463 464 // TestDir is a subdirectory in |temp_dir_| that we will make read-only so 465 // that the rename will fail. 466 base::FilePath test_dir(temp_dir_.path().AppendASCII("TestDir")); 467 ASSERT_TRUE(base::CreateDirectory(test_dir)); 468 469 base::FilePath new_path(test_dir.AppendASCII("TestFile")); 470 EXPECT_FALSE(base::PathExists(new_path)); 471 472 { 473 file_util::PermissionRestorer restore_permissions_for(test_dir); 474 ASSERT_TRUE(file_util::MakeFileUnwritable(test_dir)); 475 EXPECT_EQ(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, 476 base_file_->Rename(new_path)); 477 } 478 479 base_file_->Finish(); 480 } 481 482 // Write data to the file multiple times. 483 TEST_F(BaseFileTest, MultipleWritesWithError) { 484 base::FilePath path; 485 ASSERT_TRUE(base::CreateTemporaryFile(&path)); 486 // Create a new file stream. scoped_ptr takes ownership and passes it to 487 // BaseFile; we use the pointer anyway and rely on the BaseFile not 488 // deleting the MockFileStream until the BaseFile is reset. 489 net::testing::MockFileStream* mock_file_stream( 490 new net::testing::MockFileStream(NULL)); 491 scoped_ptr<net::FileStream> mock_file_stream_scoped_ptr(mock_file_stream); 492 493 ASSERT_EQ(0, 494 mock_file_stream->OpenSync( 495 path, 496 base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE)); 497 498 // Copy of mock_file_stream; we pass ownership and rely on the BaseFile 499 // not deleting it until it is reset. 500 501 base_file_.reset(new BaseFile(mock_file_stream->get_path(), 502 GURL(), 503 GURL(), 504 0, 505 false, 506 std::string(), 507 mock_file_stream_scoped_ptr.Pass(), 508 net::BoundNetLog())); 509 ASSERT_TRUE(InitializeFile()); 510 ASSERT_TRUE(AppendDataToFile(kTestData1)); 511 ASSERT_TRUE(AppendDataToFile(kTestData2)); 512 mock_file_stream->set_forced_error(net::ERR_ACCESS_DENIED); 513 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); 514 ASSERT_FALSE(AppendDataToFile(kTestData3)); 515 std::string hash; 516 EXPECT_FALSE(base_file_->GetHash(&hash)); 517 base_file_->Finish(); 518 } 519 520 // Try to write to uninitialized file. 521 TEST_F(BaseFileTest, UninitializedFile) { 522 expect_in_progress_ = false; 523 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 524 EXPECT_FALSE(AppendDataToFile(kTestData1)); 525 } 526 527 // Create two |BaseFile|s with the same file, and attempt to write to both. 528 // Overwrite base_file_ with another file with the same name and 529 // non-zero contents, and make sure the last file to close 'wins'. 530 TEST_F(BaseFileTest, DuplicateBaseFile) { 531 ASSERT_TRUE(InitializeFile()); 532 533 // Create another |BaseFile| referring to the file that |base_file_| owns. 534 CreateFileWithName(base_file_->full_path()); 535 536 ASSERT_TRUE(AppendDataToFile(kTestData1)); 537 base_file_->Finish(); 538 } 539 540 // Create a file and append to it. 541 TEST_F(BaseFileTest, AppendToBaseFile) { 542 // Create a new file. 543 base::FilePath existing_file_name = CreateTestFile(); 544 545 set_expected_data(kTestData4); 546 547 // Use the file we've just created. 548 base_file_.reset(new BaseFile(existing_file_name, 549 GURL(), 550 GURL(), 551 kTestDataLength4, 552 false, 553 std::string(), 554 scoped_ptr<net::FileStream>(), 555 net::BoundNetLog())); 556 557 ASSERT_TRUE(InitializeFile()); 558 559 const base::FilePath file_name = base_file_->full_path(); 560 EXPECT_NE(base::FilePath::StringType(), file_name.value()); 561 562 // Write into the file. 563 EXPECT_TRUE(AppendDataToFile(kTestData1)); 564 565 base_file_->Finish(); 566 base_file_->Detach(); 567 expect_file_survives_ = true; 568 } 569 570 // Create a read-only file and attempt to write to it. 571 TEST_F(BaseFileTest, ReadonlyBaseFile) { 572 // Create a new file. 573 base::FilePath readonly_file_name = CreateTestFile(); 574 575 // Restore permissions to the file when we are done with this test. 576 file_util::PermissionRestorer restore_permissions(readonly_file_name); 577 578 // Make it read-only. 579 EXPECT_TRUE(file_util::MakeFileUnwritable(readonly_file_name)); 580 581 // Try to overwrite it. 582 base_file_.reset(new BaseFile(readonly_file_name, 583 GURL(), 584 GURL(), 585 0, 586 false, 587 std::string(), 588 scoped_ptr<net::FileStream>(), 589 net::BoundNetLog())); 590 591 expect_in_progress_ = false; 592 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED); 593 EXPECT_FALSE(InitializeFile()); 594 595 const base::FilePath file_name = base_file_->full_path(); 596 EXPECT_NE(base::FilePath::StringType(), file_name.value()); 597 598 // Write into the file. 599 set_expected_error(DOWNLOAD_INTERRUPT_REASON_FILE_FAILED); 600 EXPECT_FALSE(AppendDataToFile(kTestData1)); 601 602 base_file_->Finish(); 603 base_file_->Detach(); 604 expect_file_survives_ = true; 605 } 606 607 TEST_F(BaseFileTest, IsEmptyHash) { 608 std::string empty(BaseFile::kSha256HashLen, '\x00'); 609 EXPECT_TRUE(BaseFile::IsEmptyHash(empty)); 610 std::string not_empty(BaseFile::kSha256HashLen, '\x01'); 611 EXPECT_FALSE(BaseFile::IsEmptyHash(not_empty)); 612 EXPECT_FALSE(BaseFile::IsEmptyHash(std::string())); 613 } 614 615 // Test that a temporary file is created in the default download directory. 616 TEST_F(BaseFileTest, CreatedInDefaultDirectory) { 617 ASSERT_TRUE(base_file_->full_path().empty()); 618 ASSERT_TRUE(InitializeFile()); 619 EXPECT_FALSE(base_file_->full_path().empty()); 620 621 // On Windows, CreateTemporaryFileInDir() will cause a path with short names 622 // to be expanded into a path with long names. Thus temp_dir.path() might not 623 // be a string-wise match to base_file_->full_path().DirName() even though 624 // they are in the same directory. 625 base::FilePath temp_file; 626 ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &temp_file)); 627 ASSERT_FALSE(temp_file.empty()); 628 EXPECT_STREQ(temp_file.DirName().value().c_str(), 629 base_file_->full_path().DirName().value().c_str()); 630 base_file_->Finish(); 631 } 632 633 } // namespace content 634