Chromium Code Reviews| 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 "webkit/fileapi/file_system_directory_database.h" | 5 #include "webkit/fileapi/file_system_directory_database.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 | 8 |
| 9 #include "base/file_util.h" | |
| 10 #include "base/platform_file.h" | |
| 9 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/scoped_temp_dir.h" | 12 #include "base/scoped_temp_dir.h" |
| 11 #include "base/string_number_conversions.h" | 13 #include "base/string_number_conversions.h" |
| 12 #include "base/string_util.h" | 14 #include "base/string_util.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "webkit/fileapi/file_system_util.h" | |
| 17 #include "webkit/fileapi/file_system_database_test_helper.h" | |
| 18 | |
| 19 #define FPL(x) FILE_PATH_LITERAL(x) | |
| 14 | 20 |
| 15 namespace fileapi { | 21 namespace fileapi { |
| 16 | 22 |
| 23 namespace { | |
| 24 const FilePath::CharType kDirectoryDatabaseName[] = FPL("Paths"); | |
| 25 } | |
| 26 | |
| 17 class FileSystemDirectoryDatabaseTest : public testing::Test { | 27 class FileSystemDirectoryDatabaseTest : public testing::Test { |
| 18 public: | 28 public: |
| 19 typedef FileSystemDirectoryDatabase::FileId FileId; | 29 typedef FileSystemDirectoryDatabase::FileId FileId; |
| 20 typedef FileSystemDirectoryDatabase::FileInfo FileInfo; | 30 typedef FileSystemDirectoryDatabase::FileInfo FileInfo; |
| 21 | 31 |
| 22 FileSystemDirectoryDatabaseTest() { | 32 FileSystemDirectoryDatabaseTest() { |
| 23 EXPECT_TRUE(base_.CreateUniqueTempDir()); | 33 EXPECT_TRUE(base_.CreateUniqueTempDir()); |
| 24 InitDatabase(); | 34 InitDatabase(); |
| 25 } | 35 } |
| 26 | 36 |
| 27 FileSystemDirectoryDatabase* db() { | 37 FileSystemDirectoryDatabase* db() { |
| 28 return db_.get(); | 38 return db_.get(); |
| 29 } | 39 } |
| 30 | 40 |
| 31 void InitDatabase() { | 41 void InitDatabase() { |
| 32 // First reset() is to avoid multiple database instance for single | 42 // Call CloseDatabes() to avoid multiple database instance for single |
|
ericu
2012/04/03 01:52:11
Typo: CloseDatabase.
tzik
2012/04/04 06:50:39
Done.
| |
| 33 // directory at once. | 43 // directory at once. |
| 44 CloseDatabase(); | |
| 45 db_.reset(new FileSystemDirectoryDatabase(path())); | |
| 46 } | |
| 47 | |
| 48 void CloseDatabase() { | |
| 34 db_.reset(); | 49 db_.reset(); |
| 35 db_.reset(new FileSystemDirectoryDatabase(base_.path())); | |
| 36 } | 50 } |
| 37 | 51 |
| 38 bool AddFileInfo(FileId parent_id, const FilePath::StringType& name) { | 52 bool AddFileInfo(FileId parent_id, const FilePath::StringType& name) { |
| 39 FileId file_id; | 53 FileId file_id; |
| 40 FileInfo info; | 54 FileInfo info; |
| 41 info.parent_id = parent_id; | 55 info.parent_id = parent_id; |
| 42 info.name = name; | 56 info.name = name; |
| 43 return db_->AddFileInfo(info, &file_id); | 57 return db_->AddFileInfo(info, &file_id); |
| 44 } | 58 } |
| 45 | 59 |
| 60 void CreateDirectory(FileId parent_id, | |
| 61 const FilePath::StringType& name, | |
| 62 FileId* file_id) { | |
| 63 FileId file_id_alt; | |
|
ericu
2012/04/03 01:52:11
[here and below]
Mostly we tend to do this by jus
tzik
2012/04/04 06:50:39
Done.
| |
| 64 if (!file_id) | |
| 65 file_id = &file_id_alt; | |
| 66 | |
| 67 FileInfo info; | |
| 68 info.parent_id = parent_id; | |
| 69 info.name = name; | |
| 70 ASSERT_TRUE(db_->AddFileInfo(info, file_id)); | |
| 71 } | |
| 72 | |
| 73 void CreateFile(FileId parent_id, | |
| 74 const FilePath::StringType& name, | |
| 75 const FilePath::StringType& data_path, | |
| 76 FileId* file_id) { | |
| 77 FileId file_id_alt; | |
| 78 if (!file_id) | |
| 79 file_id = &file_id_alt; | |
| 80 | |
| 81 FileInfo info; | |
| 82 info.parent_id = parent_id; | |
| 83 info.name = name; | |
| 84 info.data_path = FilePath(data_path); | |
| 85 ASSERT_TRUE(db_->AddFileInfo(info, file_id)); | |
| 86 | |
| 87 FilePath local_path = path().Append(data_path); | |
| 88 if (!file_util::DirectoryExists(local_path.DirName())) | |
| 89 ASSERT_TRUE(file_util::CreateDirectory(local_path.DirName())); | |
| 90 | |
| 91 bool created; | |
| 92 base::PlatformFileError error; | |
| 93 base::PlatformFile file = base::CreatePlatformFile( | |
| 94 local_path, | |
| 95 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE, | |
| 96 &created, &error); | |
| 97 ASSERT_EQ(base::PLATFORM_FILE_OK, error); | |
| 98 ASSERT_TRUE(created); | |
| 99 ASSERT_TRUE(base::ClosePlatformFile(file)); | |
| 100 } | |
| 101 | |
| 102 void ClearDatabaseAndDirectory() { | |
| 103 db_.reset(); | |
| 104 ASSERT_TRUE(file_util::Delete(path(), true /* recursive */)); | |
| 105 ASSERT_TRUE(file_util::CreateDirectory(path())); | |
| 106 db_.reset(new FileSystemDirectoryDatabase(path())); | |
| 107 } | |
| 108 | |
| 109 bool RepairDatabase() { | |
| 110 return db()->RepairDatabase( | |
| 111 FilePathToString(path().Append(kDirectoryDatabaseName))); | |
| 112 } | |
| 113 | |
| 114 const FilePath& path() { | |
| 115 return base_.path(); | |
| 116 } | |
| 117 | |
| 46 protected: | 118 protected: |
| 47 // Common temp base for nondestructive uses. | 119 // Common temp base for nondestructive uses. |
| 48 ScopedTempDir base_; | 120 ScopedTempDir base_; |
| 49 scoped_ptr<FileSystemDirectoryDatabase> db_; | 121 scoped_ptr<FileSystemDirectoryDatabase> db_; |
| 50 | 122 |
| 51 DISALLOW_COPY_AND_ASSIGN(FileSystemDirectoryDatabaseTest); | 123 DISALLOW_COPY_AND_ASSIGN(FileSystemDirectoryDatabaseTest); |
| 52 }; | 124 }; |
| 53 | 125 |
| 54 TEST_F(FileSystemDirectoryDatabaseTest, TestMissingFileGetInfo) { | 126 TEST_F(FileSystemDirectoryDatabaseTest, TestMissingFileGetInfo) { |
| 55 FileId file_id = 888; | 127 FileId file_id = 888; |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 InitDatabase(); | 483 InitDatabase(); |
| 412 EXPECT_TRUE(db()->GetNextInteger(&next)); | 484 EXPECT_TRUE(db()->GetNextInteger(&next)); |
| 413 EXPECT_EQ(2, next); | 485 EXPECT_EQ(2, next); |
| 414 EXPECT_TRUE(db()->GetNextInteger(&next)); | 486 EXPECT_TRUE(db()->GetNextInteger(&next)); |
| 415 EXPECT_EQ(3, next); | 487 EXPECT_EQ(3, next); |
| 416 InitDatabase(); | 488 InitDatabase(); |
| 417 EXPECT_TRUE(db()->GetNextInteger(&next)); | 489 EXPECT_TRUE(db()->GetNextInteger(&next)); |
| 418 EXPECT_EQ(4, next); | 490 EXPECT_EQ(4, next); |
| 419 } | 491 } |
| 420 | 492 |
| 493 TEST_F(FileSystemDirectoryDatabaseTest, TestConsistencyCheck_Empty) { | |
| 494 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
| 495 | |
| 496 int64 next; | |
| 497 EXPECT_TRUE(db()->GetNextInteger(&next)); | |
| 498 EXPECT_EQ(0, next); | |
| 499 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
| 500 } | |
| 501 | |
| 502 TEST_F(FileSystemDirectoryDatabaseTest, TestConsistencyCheck_Consistent) { | |
| 503 FileId dir_id; | |
| 504 FileId file_id; | |
|
ericu
2012/04/03 01:52:11
file_id can go away.
tzik
2012/04/04 06:50:39
Done.
| |
| 505 CreateFile(0, FPL("foo"), FPL("hoge"), NULL); | |
| 506 CreateDirectory(0, FPL("bar"), &dir_id); | |
| 507 CreateFile(dir_id, FPL("baz"), FPL("fuga"), &file_id); | |
| 508 CreateFile(dir_id, FPL("fizz"), FPL("buzz"), NULL); | |
| 509 | |
| 510 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
| 511 } | |
| 512 | |
| 513 TEST_F(FileSystemDirectoryDatabaseTest, | |
| 514 TestConsistencyCheck_BackingMultiEntry) { | |
| 515 const FilePath::CharType kBackingFileName[] = FPL("the celeb"); | |
| 516 CreateFile(0, FPL("foo"), kBackingFileName, NULL); | |
| 517 ASSERT_TRUE(file_util::Delete(path().Append(kBackingFileName), false)); | |
| 518 CreateFile(0, FPL("bar"), kBackingFileName, NULL); | |
| 519 | |
| 520 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
| 521 } | |
| 522 | |
| 523 TEST_F(FileSystemDirectoryDatabaseTest, TestConsistencyCheck_FileLost) { | |
| 524 const FilePath::CharType kBackingFileName[] = FPL("hoge"); | |
| 525 CreateFile(0, FPL("foo"), kBackingFileName, NULL); | |
| 526 ASSERT_TRUE(file_util::Delete(path().Append(kBackingFileName), false)); | |
| 527 | |
| 528 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
| 529 } | |
| 530 | |
| 531 TEST_F(FileSystemDirectoryDatabaseTest, TestConsistencyCheck_OrphanFile) { | |
| 532 CreateFile(0, FPL("foo"), FPL("hoge"), NULL); | |
| 533 | |
| 534 bool created; | |
| 535 base::PlatformFileError error; | |
| 536 base::PlatformFile file = base::CreatePlatformFile( | |
| 537 path().Append("Orphan File"), | |
| 538 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE, | |
| 539 &created, &error); | |
| 540 ASSERT_EQ(base::PLATFORM_FILE_OK, error); | |
| 541 ASSERT_TRUE(created); | |
| 542 ASSERT_TRUE(base::ClosePlatformFile(file)); | |
| 543 | |
| 544 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
| 545 } | |
|
ericu
2012/04/03 01:52:11
Please add a test for a directory loop that includ
tzik
2012/04/04 06:50:39
Done.
| |
| 546 | |
| 547 TEST_F(FileSystemDirectoryDatabaseTest, TestRepairDatabase_Success) { | |
| 548 FilePath::StringType kFileName = FPL("bar"); | |
| 549 | |
| 550 FileId file_id_prev; | |
| 551 CreateFile(0, FPL("foo"), FPL("hoge"), NULL); | |
| 552 CreateFile(0, kFileName, FPL("fuga"), &file_id_prev); | |
| 553 | |
| 554 const FilePath kDatabaseDirectory = path().Append(kDirectoryDatabaseName); | |
| 555 CloseDatabase(); | |
| 556 CorruptDatabase(kDatabaseDirectory, leveldb::kDescriptorFile, | |
| 557 0, std::numeric_limits<size_t>::max()); | |
| 558 InitDatabase(); | |
| 559 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
| 560 | |
| 561 FileId file_id; | |
| 562 EXPECT_TRUE(db()->GetChildWithName(0, kFileName, &file_id)); | |
| 563 EXPECT_EQ(file_id_prev, file_id); | |
| 564 | |
| 565 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
| 566 } | |
| 567 | |
| 568 TEST_F(FileSystemDirectoryDatabaseTest, TestRepairDatabase_Failure) { | |
| 569 FilePath::StringType kFileName = FPL("bar"); | |
| 570 | |
| 571 CreateFile(0, FPL("foo"), FPL("hoge"), NULL); | |
| 572 CreateFile(0, kFileName, FPL("fuga"), NULL); | |
| 573 | |
| 574 const FilePath kDatabaseDirectory = path().Append(kDirectoryDatabaseName); | |
| 575 CloseDatabase(); | |
| 576 CorruptDatabase(kDatabaseDirectory, leveldb::kDescriptorFile, | |
| 577 0, std::numeric_limits<size_t>::max()); | |
| 578 CorruptDatabase(kDatabaseDirectory, leveldb::kLogFile, | |
| 579 -1, 1); | |
| 580 InitDatabase(); | |
| 581 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
| 582 | |
| 583 FileId file_id; | |
| 584 EXPECT_FALSE(db()->GetChildWithName(0, kFileName, &file_id)); | |
| 585 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
| 586 } | |
| 587 | |
| 421 } // namespace fileapi | 588 } // namespace fileapi |
| OLD | NEW |