Home | History | Annotate | Download | only in fileapi
      1 // Copyright 2014 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 "storage/browser/fileapi/sandbox_directory_database.h"
      6 
      7 #include <math.h>
      8 #include <limits>
      9 
     10 #include "base/files/file.h"
     11 #include "base/files/file_util.h"
     12 #include "base/files/scoped_temp_dir.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/strings/string_number_conversions.h"
     15 #include "base/strings/string_util.h"
     16 #include "content/browser/fileapi/sandbox_database_test_helper.h"
     17 #include "storage/common/fileapi/file_system_util.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 #include "third_party/leveldatabase/src/include/leveldb/db.h"
     20 
     21 #define FPL(x) FILE_PATH_LITERAL(x)
     22 
     23 using storage::FilePathToString;
     24 using storage::SandboxDirectoryDatabase;
     25 
     26 namespace content {
     27 
     28 namespace {
     29 const base::FilePath::CharType kDirectoryDatabaseName[] = FPL("Paths");
     30 }
     31 
     32 class SandboxDirectoryDatabaseTest : public testing::Test {
     33  public:
     34   typedef SandboxDirectoryDatabase::FileId FileId;
     35   typedef SandboxDirectoryDatabase::FileInfo FileInfo;
     36 
     37   SandboxDirectoryDatabaseTest() {
     38     EXPECT_TRUE(base_.CreateUniqueTempDir());
     39     InitDatabase();
     40   }
     41 
     42   SandboxDirectoryDatabase* db() {
     43     return db_.get();
     44   }
     45 
     46   void InitDatabase() {
     47     // Call CloseDatabase() to avoid having multiple database instances for
     48     // single directory at once.
     49     CloseDatabase();
     50     db_.reset(new SandboxDirectoryDatabase(path(), NULL));
     51   }
     52 
     53   void CloseDatabase() {
     54     db_.reset();
     55   }
     56 
     57   base::File::Error AddFileInfo(
     58       FileId parent_id, const base::FilePath::StringType& name) {
     59     FileId file_id;
     60     FileInfo info;
     61     info.parent_id = parent_id;
     62     info.name = name;
     63     return db_->AddFileInfo(info, &file_id);
     64   }
     65 
     66   void CreateDirectory(FileId parent_id,
     67                        const base::FilePath::StringType& name,
     68                        FileId* file_id_out) {
     69     FileInfo info;
     70     info.parent_id = parent_id;
     71     info.name = name;
     72     ASSERT_EQ(base::File::FILE_OK, db_->AddFileInfo(info, file_id_out));
     73   }
     74 
     75   void CreateFile(FileId parent_id,
     76                   const base::FilePath::StringType& name,
     77                   const base::FilePath::StringType& data_path,
     78                   FileId* file_id_out) {
     79     FileId file_id;
     80 
     81     FileInfo info;
     82     info.parent_id = parent_id;
     83     info.name = name;
     84     info.data_path = base::FilePath(data_path).NormalizePathSeparators();
     85     ASSERT_EQ(base::File::FILE_OK, db_->AddFileInfo(info, &file_id));
     86 
     87     base::FilePath local_path = path().Append(data_path);
     88     if (!base::DirectoryExists(local_path.DirName()))
     89       ASSERT_TRUE(base::CreateDirectory(local_path.DirName()));
     90 
     91     base::File file(local_path,
     92                     base::File::FLAG_CREATE | base::File::FLAG_WRITE);
     93     ASSERT_TRUE(file.IsValid());
     94     ASSERT_TRUE(file.created());
     95 
     96     if (file_id_out)
     97       *file_id_out = file_id;
     98   }
     99 
    100   void ClearDatabaseAndDirectory() {
    101     db_.reset();
    102     ASSERT_TRUE(base::DeleteFile(path(), true /* recursive */));
    103     ASSERT_TRUE(base::CreateDirectory(path()));
    104     db_.reset(new SandboxDirectoryDatabase(path(), NULL));
    105   }
    106 
    107   bool RepairDatabase() {
    108     return db()->RepairDatabase(
    109         FilePathToString(path().Append(kDirectoryDatabaseName)));
    110   }
    111 
    112   const base::FilePath& path() {
    113     return base_.path();
    114   }
    115 
    116   // Makes link from |parent_id| to |child_id| with |name|.
    117   void MakeHierarchyLink(FileId parent_id,
    118                          FileId child_id,
    119                          const base::FilePath::StringType& name) {
    120     ASSERT_TRUE(db()->db_->Put(
    121         leveldb::WriteOptions(),
    122         "CHILD_OF:" + base::Int64ToString(parent_id) + ":" +
    123         FilePathToString(base::FilePath(name)),
    124         base::Int64ToString(child_id)).ok());
    125   }
    126 
    127   // Deletes link from parent of |file_id| to |file_id|.
    128   void DeleteHierarchyLink(FileId file_id) {
    129     FileInfo file_info;
    130     ASSERT_TRUE(db()->GetFileInfo(file_id, &file_info));
    131     ASSERT_TRUE(db()->db_->Delete(
    132         leveldb::WriteOptions(),
    133         "CHILD_OF:" + base::Int64ToString(file_info.parent_id) + ":" +
    134         FilePathToString(base::FilePath(file_info.name))).ok());
    135   }
    136 
    137  protected:
    138   // Common temp base for nondestructive uses.
    139   base::ScopedTempDir base_;
    140   scoped_ptr<SandboxDirectoryDatabase> db_;
    141 
    142  private:
    143   DISALLOW_COPY_AND_ASSIGN(SandboxDirectoryDatabaseTest);
    144 };
    145 
    146 TEST_F(SandboxDirectoryDatabaseTest, TestMissingFileGetInfo) {
    147   FileId file_id = 888;
    148   FileInfo info;
    149   EXPECT_FALSE(db()->GetFileInfo(file_id, &info));
    150 }
    151 
    152 TEST_F(SandboxDirectoryDatabaseTest, TestGetRootFileInfoBeforeCreate) {
    153   FileId file_id = 0;
    154   FileInfo info;
    155   EXPECT_TRUE(db()->GetFileInfo(file_id, &info));
    156   EXPECT_EQ(0, info.parent_id);
    157   EXPECT_TRUE(info.name.empty());
    158   EXPECT_TRUE(info.data_path.empty());
    159 }
    160 
    161 TEST_F(SandboxDirectoryDatabaseTest, TestMissingParentAddFileInfo) {
    162   FileId parent_id = 7;
    163   EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY,
    164             AddFileInfo(parent_id, FILE_PATH_LITERAL("foo")));
    165 }
    166 
    167 TEST_F(SandboxDirectoryDatabaseTest, TestAddNameClash) {
    168   FileInfo info;
    169   FileId file_id;
    170   info.parent_id = 0;
    171   info.name = FILE_PATH_LITERAL("dir 0");
    172   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id));
    173 
    174   // Check for name clash in the root directory.
    175   base::FilePath::StringType name = info.name;
    176   EXPECT_EQ(base::File::FILE_ERROR_EXISTS, AddFileInfo(0, name));
    177   name = FILE_PATH_LITERAL("dir 1");
    178   EXPECT_EQ(base::File::FILE_OK, AddFileInfo(0, name));
    179 
    180   name = FILE_PATH_LITERAL("subdir 0");
    181   EXPECT_EQ(base::File::FILE_OK, AddFileInfo(file_id, name));
    182 
    183   // Check for name clash in a subdirectory.
    184   EXPECT_EQ(base::File::FILE_ERROR_EXISTS, AddFileInfo(file_id, name));
    185   name = FILE_PATH_LITERAL("subdir 1");
    186   EXPECT_EQ(base::File::FILE_OK, AddFileInfo(file_id, name));
    187 }
    188 
    189 TEST_F(SandboxDirectoryDatabaseTest, TestRenameNoMoveNameClash) {
    190   FileInfo info;
    191   FileId file_id0;
    192   base::FilePath::StringType name0 = FILE_PATH_LITERAL("foo");
    193   base::FilePath::StringType name1 = FILE_PATH_LITERAL("bar");
    194   base::FilePath::StringType name2 = FILE_PATH_LITERAL("bas");
    195   info.parent_id = 0;
    196   info.name = name0;
    197   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0));
    198   EXPECT_EQ(base::File::FILE_OK, AddFileInfo(0, name1));
    199   info.name = name1;
    200   EXPECT_FALSE(db()->UpdateFileInfo(file_id0, info));
    201   info.name = name2;
    202   EXPECT_TRUE(db()->UpdateFileInfo(file_id0, info));
    203 }
    204 
    205 TEST_F(SandboxDirectoryDatabaseTest, TestMoveSameNameNameClash) {
    206   FileInfo info;
    207   FileId file_id0;
    208   FileId file_id1;
    209   base::FilePath::StringType name0 = FILE_PATH_LITERAL("foo");
    210   base::FilePath::StringType name1 = FILE_PATH_LITERAL("bar");
    211   info.parent_id = 0;
    212   info.name = name0;
    213   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0));
    214   info.parent_id = file_id0;
    215   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1));
    216   info.parent_id = 0;
    217   EXPECT_FALSE(db()->UpdateFileInfo(file_id1, info));
    218   info.name = name1;
    219   EXPECT_TRUE(db()->UpdateFileInfo(file_id1, info));
    220 }
    221 
    222 TEST_F(SandboxDirectoryDatabaseTest, TestMoveRenameNameClash) {
    223   FileInfo info;
    224   FileId file_id0;
    225   FileId file_id1;
    226   base::FilePath::StringType name0 = FILE_PATH_LITERAL("foo");
    227   base::FilePath::StringType name1 = FILE_PATH_LITERAL("bar");
    228   base::FilePath::StringType name2 = FILE_PATH_LITERAL("bas");
    229   info.parent_id = 0;
    230   info.name = name0;
    231   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0));
    232   info.parent_id = file_id0;
    233   info.name = name1;
    234   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1));
    235   info.parent_id = 0;
    236   info.name = name0;
    237   EXPECT_FALSE(db()->UpdateFileInfo(file_id1, info));
    238   info.name = name1;
    239   EXPECT_TRUE(db()->UpdateFileInfo(file_id1, info));
    240   // Also test a successful move+rename.
    241   info.parent_id = file_id0;
    242   info.name = name2;
    243   EXPECT_TRUE(db()->UpdateFileInfo(file_id1, info));
    244 }
    245 
    246 TEST_F(SandboxDirectoryDatabaseTest, TestRemoveWithChildren) {
    247   FileInfo info;
    248   FileId file_id0;
    249   FileId file_id1;
    250   info.parent_id = 0;
    251   info.name = FILE_PATH_LITERAL("foo");
    252   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0));
    253   info.parent_id = file_id0;
    254   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1));
    255   EXPECT_FALSE(db()->RemoveFileInfo(file_id0));
    256   EXPECT_TRUE(db()->RemoveFileInfo(file_id1));
    257   EXPECT_TRUE(db()->RemoveFileInfo(file_id0));
    258 }
    259 
    260 TEST_F(SandboxDirectoryDatabaseTest, TestGetChildWithName) {
    261   FileInfo info;
    262   FileId file_id0;
    263   FileId file_id1;
    264   base::FilePath::StringType name0 = FILE_PATH_LITERAL("foo");
    265   base::FilePath::StringType name1 = FILE_PATH_LITERAL("bar");
    266   info.parent_id = 0;
    267   info.name = name0;
    268   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0));
    269   info.parent_id = file_id0;
    270   info.name = name1;
    271   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1));
    272   EXPECT_NE(file_id0, file_id1);
    273 
    274   FileId check_file_id;
    275   EXPECT_FALSE(db()->GetChildWithName(0, name1, &check_file_id));
    276   EXPECT_TRUE(db()->GetChildWithName(0, name0, &check_file_id));
    277   EXPECT_EQ(file_id0, check_file_id);
    278   EXPECT_FALSE(db()->GetChildWithName(file_id0, name0, &check_file_id));
    279   EXPECT_TRUE(db()->GetChildWithName(file_id0, name1, &check_file_id));
    280   EXPECT_EQ(file_id1, check_file_id);
    281 }
    282 
    283 TEST_F(SandboxDirectoryDatabaseTest, TestGetFileWithPath) {
    284   FileInfo info;
    285   FileId file_id0;
    286   FileId file_id1;
    287   FileId file_id2;
    288   base::FilePath::StringType name0 = FILE_PATH_LITERAL("foo");
    289   base::FilePath::StringType name1 = FILE_PATH_LITERAL("bar");
    290   base::FilePath::StringType name2 = FILE_PATH_LITERAL("dog");
    291 
    292   info.parent_id = 0;
    293   info.name = name0;
    294   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0));
    295   info.parent_id = file_id0;
    296   info.name = name1;
    297   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1));
    298   EXPECT_NE(file_id0, file_id1);
    299   info.parent_id = file_id1;
    300   info.name = name2;
    301   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id2));
    302   EXPECT_NE(file_id0, file_id2);
    303   EXPECT_NE(file_id1, file_id2);
    304 
    305   FileId check_file_id;
    306   base::FilePath path = base::FilePath(name0);
    307   EXPECT_TRUE(db()->GetFileWithPath(path, &check_file_id));
    308   EXPECT_EQ(file_id0, check_file_id);
    309 
    310   path = path.Append(name1);
    311   EXPECT_TRUE(db()->GetFileWithPath(path, &check_file_id));
    312   EXPECT_EQ(file_id1, check_file_id);
    313 
    314   path = path.Append(name2);
    315   EXPECT_TRUE(db()->GetFileWithPath(path, &check_file_id));
    316   EXPECT_EQ(file_id2, check_file_id);
    317 }
    318 
    319 TEST_F(SandboxDirectoryDatabaseTest, TestListChildren) {
    320   // No children in the root.
    321   std::vector<FileId> children;
    322   EXPECT_TRUE(db()->ListChildren(0, &children));
    323   EXPECT_TRUE(children.empty());
    324 
    325   // One child in the root.
    326   FileId file_id0;
    327   FileInfo info;
    328   info.parent_id = 0;
    329   info.name = FILE_PATH_LITERAL("foo");
    330   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0));
    331   EXPECT_TRUE(db()->ListChildren(0, &children));
    332   EXPECT_EQ(children.size(), 1UL);
    333   EXPECT_EQ(children[0], file_id0);
    334 
    335   // Two children in the root.
    336   FileId file_id1;
    337   info.name = FILE_PATH_LITERAL("bar");
    338   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1));
    339   EXPECT_TRUE(db()->ListChildren(0, &children));
    340   EXPECT_EQ(2UL, children.size());
    341   if (children[0] == file_id0) {
    342     EXPECT_EQ(children[1], file_id1);
    343   } else {
    344     EXPECT_EQ(children[1], file_id0);
    345     EXPECT_EQ(children[0], file_id1);
    346   }
    347 
    348   // No children in a subdirectory.
    349   EXPECT_TRUE(db()->ListChildren(file_id0, &children));
    350   EXPECT_TRUE(children.empty());
    351 
    352   // One child in a subdirectory.
    353   info.parent_id = file_id0;
    354   info.name = FILE_PATH_LITERAL("foo");
    355   FileId file_id2;
    356   FileId file_id3;
    357   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id2));
    358   EXPECT_TRUE(db()->ListChildren(file_id0, &children));
    359   EXPECT_EQ(1UL, children.size());
    360   EXPECT_EQ(children[0], file_id2);
    361 
    362   // Two children in a subdirectory.
    363   info.name = FILE_PATH_LITERAL("bar");
    364   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id3));
    365   EXPECT_TRUE(db()->ListChildren(file_id0, &children));
    366   EXPECT_EQ(2UL, children.size());
    367   if (children[0] == file_id2) {
    368     EXPECT_EQ(children[1], file_id3);
    369   } else {
    370     EXPECT_EQ(children[1], file_id2);
    371     EXPECT_EQ(children[0], file_id3);
    372   }
    373 }
    374 
    375 TEST_F(SandboxDirectoryDatabaseTest, TestUpdateModificationTime) {
    376   FileInfo info0;
    377   FileId file_id;
    378   info0.parent_id = 0;
    379   info0.name = FILE_PATH_LITERAL("name");
    380   info0.data_path = base::FilePath(FILE_PATH_LITERAL("fake path"));
    381   info0.modification_time = base::Time::Now();
    382   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info0, &file_id));
    383   FileInfo info1;
    384   EXPECT_TRUE(db()->GetFileInfo(file_id, &info1));
    385   EXPECT_EQ(info0.name, info1.name);
    386   EXPECT_EQ(info0.parent_id, info1.parent_id);
    387   EXPECT_EQ(info0.data_path, info1.data_path);
    388   EXPECT_EQ(
    389       floor(info0.modification_time.ToDoubleT()),
    390       info1.modification_time.ToDoubleT());
    391 
    392   EXPECT_TRUE(db()->UpdateModificationTime(file_id, base::Time::UnixEpoch()));
    393   EXPECT_TRUE(db()->GetFileInfo(file_id, &info1));
    394   EXPECT_EQ(info0.name, info1.name);
    395   EXPECT_EQ(info0.parent_id, info1.parent_id);
    396   EXPECT_EQ(info0.data_path, info1.data_path);
    397   EXPECT_NE(info0.modification_time, info1.modification_time);
    398   EXPECT_EQ(
    399       info1.modification_time.ToDoubleT(),
    400       floor(base::Time::UnixEpoch().ToDoubleT()));
    401 
    402   EXPECT_FALSE(db()->UpdateModificationTime(999, base::Time::UnixEpoch()));
    403 }
    404 
    405 TEST_F(SandboxDirectoryDatabaseTest, TestSimpleFileOperations) {
    406   FileId file_id = 888;
    407   FileInfo info0;
    408   EXPECT_FALSE(db()->GetFileInfo(file_id, &info0));
    409   info0.parent_id = 0;
    410   info0.data_path = base::FilePath(FILE_PATH_LITERAL("foo"));
    411   info0.name = FILE_PATH_LITERAL("file name");
    412   info0.modification_time = base::Time::Now();
    413   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info0, &file_id));
    414   FileInfo info1;
    415   EXPECT_TRUE(db()->GetFileInfo(file_id, &info1));
    416   EXPECT_EQ(info0.parent_id, info1.parent_id);
    417   EXPECT_EQ(info0.data_path, info1.data_path);
    418   EXPECT_EQ(info0.name, info1.name);
    419   EXPECT_EQ(
    420       floor(info0.modification_time.ToDoubleT()),
    421       info1.modification_time.ToDoubleT());
    422 }
    423 
    424 TEST_F(SandboxDirectoryDatabaseTest, TestOverwritingMoveFileSrcDirectory) {
    425   FileId directory_id;
    426   FileInfo info0;
    427   info0.parent_id = 0;
    428   info0.name = FILE_PATH_LITERAL("directory");
    429   info0.modification_time = base::Time::Now();
    430   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info0, &directory_id));
    431 
    432   FileId file_id;
    433   FileInfo info1;
    434   info1.parent_id = 0;
    435   info1.data_path = base::FilePath(FILE_PATH_LITERAL("bar"));
    436   info1.name = FILE_PATH_LITERAL("file");
    437   info1.modification_time = base::Time::UnixEpoch();
    438   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info1, &file_id));
    439 
    440   EXPECT_FALSE(db()->OverwritingMoveFile(directory_id, file_id));
    441 }
    442 
    443 TEST_F(SandboxDirectoryDatabaseTest, TestOverwritingMoveFileDestDirectory) {
    444   FileId file_id;
    445   FileInfo info0;
    446   info0.parent_id = 0;
    447   info0.name = FILE_PATH_LITERAL("file");
    448   info0.data_path = base::FilePath(FILE_PATH_LITERAL("bar"));
    449   info0.modification_time = base::Time::Now();
    450   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info0, &file_id));
    451 
    452   FileId directory_id;
    453   FileInfo info1;
    454   info1.parent_id = 0;
    455   info1.name = FILE_PATH_LITERAL("directory");
    456   info1.modification_time = base::Time::UnixEpoch();
    457   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info1, &directory_id));
    458 
    459   EXPECT_FALSE(db()->OverwritingMoveFile(file_id, directory_id));
    460 }
    461 
    462 TEST_F(SandboxDirectoryDatabaseTest, TestOverwritingMoveFileSuccess) {
    463   FileId file_id0;
    464   FileInfo info0;
    465   info0.parent_id = 0;
    466   info0.data_path = base::FilePath(FILE_PATH_LITERAL("foo"));
    467   info0.name = FILE_PATH_LITERAL("file name 0");
    468   info0.modification_time = base::Time::Now();
    469   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info0, &file_id0));
    470 
    471   FileInfo dir_info;
    472   FileId dir_id;
    473   dir_info.parent_id = 0;
    474   dir_info.name = FILE_PATH_LITERAL("directory name");
    475   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(dir_info, &dir_id));
    476 
    477   FileId file_id1;
    478   FileInfo info1;
    479   info1.parent_id = dir_id;
    480   info1.data_path = base::FilePath(FILE_PATH_LITERAL("bar"));
    481   info1.name = FILE_PATH_LITERAL("file name 1");
    482   info1.modification_time = base::Time::UnixEpoch();
    483   EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info1, &file_id1));
    484 
    485   EXPECT_TRUE(db()->OverwritingMoveFile(file_id0, file_id1));
    486 
    487   FileInfo check_info;
    488   FileId check_id;
    489 
    490   EXPECT_FALSE(db()->GetFileWithPath(base::FilePath(info0.name), &check_id));
    491   EXPECT_TRUE(db()->GetFileWithPath(
    492       base::FilePath(dir_info.name).Append(info1.name), &check_id));
    493   EXPECT_TRUE(db()->GetFileInfo(check_id, &check_info));
    494 
    495   EXPECT_EQ(info0.data_path, check_info.data_path);
    496 }
    497 
    498 TEST_F(SandboxDirectoryDatabaseTest, TestGetNextInteger) {
    499   int64 next = -1;
    500   EXPECT_TRUE(db()->GetNextInteger(&next));
    501   EXPECT_EQ(0, next);
    502   EXPECT_TRUE(db()->GetNextInteger(&next));
    503   EXPECT_EQ(1, next);
    504   InitDatabase();
    505   EXPECT_TRUE(db()->GetNextInteger(&next));
    506   EXPECT_EQ(2, next);
    507   EXPECT_TRUE(db()->GetNextInteger(&next));
    508   EXPECT_EQ(3, next);
    509   InitDatabase();
    510   EXPECT_TRUE(db()->GetNextInteger(&next));
    511   EXPECT_EQ(4, next);
    512 }
    513 
    514 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_Empty) {
    515   EXPECT_TRUE(db()->IsFileSystemConsistent());
    516 
    517   int64 next = -1;
    518   EXPECT_TRUE(db()->GetNextInteger(&next));
    519   EXPECT_EQ(0, next);
    520   EXPECT_TRUE(db()->IsFileSystemConsistent());
    521 }
    522 
    523 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_Consistent) {
    524   FileId dir_id;
    525   CreateFile(0, FPL("foo"), FPL("hoge"), NULL);
    526   CreateDirectory(0, FPL("bar"), &dir_id);
    527   CreateFile(dir_id, FPL("baz"), FPL("fuga"), NULL);
    528   CreateFile(dir_id, FPL("fizz"), FPL("buzz"), NULL);
    529 
    530   EXPECT_TRUE(db()->IsFileSystemConsistent());
    531 }
    532 
    533 TEST_F(SandboxDirectoryDatabaseTest,
    534        TestConsistencyCheck_BackingMultiEntry) {
    535   const base::FilePath::CharType kBackingFileName[] = FPL("the celeb");
    536   CreateFile(0, FPL("foo"), kBackingFileName, NULL);
    537 
    538   EXPECT_TRUE(db()->IsFileSystemConsistent());
    539   ASSERT_TRUE(base::DeleteFile(path().Append(kBackingFileName), false));
    540   CreateFile(0, FPL("bar"), kBackingFileName, NULL);
    541   EXPECT_FALSE(db()->IsFileSystemConsistent());
    542 }
    543 
    544 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_FileLost) {
    545   const base::FilePath::CharType kBackingFileName[] = FPL("hoge");
    546   CreateFile(0, FPL("foo"), kBackingFileName, NULL);
    547 
    548   EXPECT_TRUE(db()->IsFileSystemConsistent());
    549   ASSERT_TRUE(base::DeleteFile(path().Append(kBackingFileName), false));
    550   EXPECT_TRUE(db()->IsFileSystemConsistent());
    551 }
    552 
    553 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_OrphanFile) {
    554   CreateFile(0, FPL("foo"), FPL("hoge"), NULL);
    555 
    556   EXPECT_TRUE(db()->IsFileSystemConsistent());
    557 
    558   base::File file(path().Append(FPL("Orphan File")),
    559                   base::File::FLAG_CREATE | base::File::FLAG_WRITE);
    560   ASSERT_TRUE(file.IsValid());
    561   ASSERT_TRUE(file.created());
    562   file.Close();
    563 
    564   EXPECT_TRUE(db()->IsFileSystemConsistent());
    565 }
    566 
    567 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_RootLoop) {
    568   EXPECT_TRUE(db()->IsFileSystemConsistent());
    569   MakeHierarchyLink(0, 0, base::FilePath::StringType());
    570   EXPECT_FALSE(db()->IsFileSystemConsistent());
    571 }
    572 
    573 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_DirectoryLoop) {
    574   FileId dir1_id;
    575   FileId dir2_id;
    576   base::FilePath::StringType dir1_name = FPL("foo");
    577   CreateDirectory(0, dir1_name, &dir1_id);
    578   CreateDirectory(dir1_id, FPL("bar"), &dir2_id);
    579 
    580   EXPECT_TRUE(db()->IsFileSystemConsistent());
    581   MakeHierarchyLink(dir2_id, dir1_id, dir1_name);
    582   EXPECT_FALSE(db()->IsFileSystemConsistent());
    583 }
    584 
    585 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_NameMismatch) {
    586   FileId dir_id;
    587   FileId file_id;
    588   CreateDirectory(0, FPL("foo"), &dir_id);
    589   CreateFile(dir_id, FPL("bar"), FPL("hoge/fuga/piyo"), &file_id);
    590 
    591   EXPECT_TRUE(db()->IsFileSystemConsistent());
    592   DeleteHierarchyLink(file_id);
    593   MakeHierarchyLink(dir_id, file_id, FPL("baz"));
    594   EXPECT_FALSE(db()->IsFileSystemConsistent());
    595 }
    596 
    597 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_WreckedEntries) {
    598   FileId dir1_id;
    599   FileId dir2_id;
    600   CreateDirectory(0, FPL("foo"), &dir1_id);
    601   CreateDirectory(dir1_id, FPL("bar"), &dir2_id);
    602   CreateFile(dir2_id, FPL("baz"), FPL("fizz/buzz"), NULL);
    603 
    604   EXPECT_TRUE(db()->IsFileSystemConsistent());
    605   DeleteHierarchyLink(dir2_id);  // Delete link from |dir1_id| to |dir2_id|.
    606   EXPECT_FALSE(db()->IsFileSystemConsistent());
    607 }
    608 
    609 TEST_F(SandboxDirectoryDatabaseTest, TestRepairDatabase_Success) {
    610   base::FilePath::StringType kFileName = FPL("bar");
    611 
    612   FileId file_id_prev;
    613   CreateFile(0, FPL("foo"), FPL("hoge"), NULL);
    614   CreateFile(0, kFileName, FPL("fuga"), &file_id_prev);
    615 
    616   const base::FilePath kDatabaseDirectory =
    617       path().Append(kDirectoryDatabaseName);
    618   CloseDatabase();
    619   CorruptDatabase(kDatabaseDirectory, leveldb::kDescriptorFile,
    620                   0, std::numeric_limits<size_t>::max());
    621   InitDatabase();
    622   EXPECT_FALSE(db()->IsFileSystemConsistent());
    623 
    624   FileId file_id;
    625   EXPECT_TRUE(db()->GetChildWithName(0, kFileName, &file_id));
    626   EXPECT_EQ(file_id_prev, file_id);
    627 
    628   EXPECT_TRUE(db()->IsFileSystemConsistent());
    629 }
    630 
    631 TEST_F(SandboxDirectoryDatabaseTest, TestRepairDatabase_Failure) {
    632   base::FilePath::StringType kFileName = FPL("bar");
    633 
    634   CreateFile(0, FPL("foo"), FPL("hoge"), NULL);
    635   CreateFile(0, kFileName, FPL("fuga"), NULL);
    636 
    637   const base::FilePath kDatabaseDirectory =
    638       path().Append(kDirectoryDatabaseName);
    639   CloseDatabase();
    640   CorruptDatabase(kDatabaseDirectory, leveldb::kDescriptorFile,
    641                   0, std::numeric_limits<size_t>::max());
    642   CorruptDatabase(kDatabaseDirectory, leveldb::kLogFile,
    643                   -1, 1);
    644   InitDatabase();
    645   EXPECT_FALSE(db()->IsFileSystemConsistent());
    646 
    647   FileId file_id;
    648   EXPECT_FALSE(db()->GetChildWithName(0, kFileName, &file_id));
    649   EXPECT_TRUE(db()->IsFileSystemConsistent());
    650 }
    651 
    652 TEST_F(SandboxDirectoryDatabaseTest, TestRepairDatabase_MissingManifest) {
    653   base::FilePath::StringType kFileName = FPL("bar");
    654 
    655   FileId file_id_prev;
    656   CreateFile(0, FPL("foo"), FPL("hoge"), NULL);
    657   CreateFile(0, kFileName, FPL("fuga"), &file_id_prev);
    658 
    659   const base::FilePath kDatabaseDirectory =
    660       path().Append(kDirectoryDatabaseName);
    661   CloseDatabase();
    662 
    663   DeleteDatabaseFile(kDatabaseDirectory, leveldb::kDescriptorFile);
    664 
    665   InitDatabase();
    666   EXPECT_FALSE(db()->IsFileSystemConsistent());
    667 
    668   FileId file_id;
    669   EXPECT_TRUE(db()->GetChildWithName(0, kFileName, &file_id));
    670   EXPECT_EQ(file_id_prev, file_id);
    671 
    672   EXPECT_TRUE(db()->IsFileSystemConsistent());
    673 }
    674 
    675 }  // namespace content
    676