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.
5 #include "webkit/browser/fileapi/sandbox_directory_database.h"
10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/platform_file.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/leveldatabase/src/include/leveldb/db.h"
18 #include "webkit/browser/fileapi/sandbox_database_test_helper.h"
19 #include "webkit/common/fileapi/file_system_util.h"
21 #define FPL(x) FILE_PATH_LITERAL(x)
26 const base::FilePath::CharType kDirectoryDatabaseName
[] = FPL("Paths");
29 class SandboxDirectoryDatabaseTest
: public testing::Test
{
31 typedef SandboxDirectoryDatabase::FileId FileId
;
32 typedef SandboxDirectoryDatabase::FileInfo FileInfo
;
34 SandboxDirectoryDatabaseTest() {
35 EXPECT_TRUE(base_
.CreateUniqueTempDir());
39 SandboxDirectoryDatabase
* db() {
44 // Call CloseDatabase() to avoid having multiple database instances for
45 // single directory at once.
47 db_
.reset(new SandboxDirectoryDatabase(path()));
50 void CloseDatabase() {
54 base::PlatformFileError
AddFileInfo(
55 FileId parent_id
, const base::FilePath::StringType
& name
) {
58 info
.parent_id
= parent_id
;
60 return db_
->AddFileInfo(info
, &file_id
);
63 void CreateDirectory(FileId parent_id
,
64 const base::FilePath::StringType
& name
,
65 FileId
* file_id_out
) {
67 info
.parent_id
= parent_id
;
69 ASSERT_EQ(base::PLATFORM_FILE_OK
, db_
->AddFileInfo(info
, file_id_out
));
72 void CreateFile(FileId parent_id
,
73 const base::FilePath::StringType
& name
,
74 const base::FilePath::StringType
& data_path
,
75 FileId
* file_id_out
) {
79 info
.parent_id
= parent_id
;
81 info
.data_path
= base::FilePath(data_path
).NormalizePathSeparators();
82 ASSERT_EQ(base::PLATFORM_FILE_OK
, db_
->AddFileInfo(info
, &file_id
));
84 base::FilePath local_path
= path().Append(data_path
);
85 if (!base::DirectoryExists(local_path
.DirName()))
86 ASSERT_TRUE(file_util::CreateDirectory(local_path
.DirName()));
89 base::PlatformFileError error
= base::PLATFORM_FILE_ERROR_FAILED
;
90 base::PlatformFile file
= base::CreatePlatformFile(
92 base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
,
94 ASSERT_EQ(base::PLATFORM_FILE_OK
, error
);
96 ASSERT_TRUE(base::ClosePlatformFile(file
));
99 *file_id_out
= file_id
;
102 void ClearDatabaseAndDirectory() {
104 ASSERT_TRUE(base::DeleteFile(path(), true /* recursive */));
105 ASSERT_TRUE(file_util::CreateDirectory(path()));
106 db_
.reset(new SandboxDirectoryDatabase(path()));
109 bool RepairDatabase() {
110 return db()->RepairDatabase(
111 FilePathToString(path().Append(kDirectoryDatabaseName
)));
114 const base::FilePath
& path() {
118 // Makes link from |parent_id| to |child_id| with |name|.
119 void MakeHierarchyLink(FileId parent_id
,
121 const base::FilePath::StringType
& name
) {
122 ASSERT_TRUE(db()->db_
->Put(
123 leveldb::WriteOptions(),
124 "CHILD_OF:" + base::Int64ToString(parent_id
) + ":" +
125 FilePathToString(base::FilePath(name
)),
126 base::Int64ToString(child_id
)).ok());
129 // Deletes link from parent of |file_id| to |file_id|.
130 void DeleteHierarchyLink(FileId file_id
) {
132 ASSERT_TRUE(db()->GetFileInfo(file_id
, &file_info
));
133 ASSERT_TRUE(db()->db_
->Delete(
134 leveldb::WriteOptions(),
135 "CHILD_OF:" + base::Int64ToString(file_info
.parent_id
) + ":" +
136 FilePathToString(base::FilePath(file_info
.name
))).ok());
140 // Common temp base for nondestructive uses.
141 base::ScopedTempDir base_
;
142 scoped_ptr
<SandboxDirectoryDatabase
> db_
;
145 DISALLOW_COPY_AND_ASSIGN(SandboxDirectoryDatabaseTest
);
148 TEST_F(SandboxDirectoryDatabaseTest
, TestMissingFileGetInfo
) {
149 FileId file_id
= 888;
151 EXPECT_FALSE(db()->GetFileInfo(file_id
, &info
));
154 TEST_F(SandboxDirectoryDatabaseTest
, TestGetRootFileInfoBeforeCreate
) {
157 EXPECT_TRUE(db()->GetFileInfo(file_id
, &info
));
158 EXPECT_EQ(0, info
.parent_id
);
159 EXPECT_TRUE(info
.name
.empty());
160 EXPECT_TRUE(info
.data_path
.empty());
163 TEST_F(SandboxDirectoryDatabaseTest
, TestMissingParentAddFileInfo
) {
164 FileId parent_id
= 7;
165 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY
,
166 AddFileInfo(parent_id
, FILE_PATH_LITERAL("foo")));
169 TEST_F(SandboxDirectoryDatabaseTest
, TestAddNameClash
) {
173 info
.name
= FILE_PATH_LITERAL("dir 0");
174 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id
));
176 // Check for name clash in the root directory.
177 base::FilePath::StringType name
= info
.name
;
178 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
, AddFileInfo(0, name
));
179 name
= FILE_PATH_LITERAL("dir 1");
180 EXPECT_EQ(base::PLATFORM_FILE_OK
, AddFileInfo(0, name
));
182 name
= FILE_PATH_LITERAL("subdir 0");
183 EXPECT_EQ(base::PLATFORM_FILE_OK
, AddFileInfo(file_id
, name
));
185 // Check for name clash in a subdirectory.
186 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
, AddFileInfo(file_id
, name
));
187 name
= FILE_PATH_LITERAL("subdir 1");
188 EXPECT_EQ(base::PLATFORM_FILE_OK
, AddFileInfo(file_id
, name
));
191 TEST_F(SandboxDirectoryDatabaseTest
, TestRenameNoMoveNameClash
) {
194 base::FilePath::StringType name0
= FILE_PATH_LITERAL("foo");
195 base::FilePath::StringType name1
= FILE_PATH_LITERAL("bar");
196 base::FilePath::StringType name2
= FILE_PATH_LITERAL("bas");
199 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id0
));
200 EXPECT_EQ(base::PLATFORM_FILE_OK
, AddFileInfo(0, name1
));
202 EXPECT_FALSE(db()->UpdateFileInfo(file_id0
, info
));
204 EXPECT_TRUE(db()->UpdateFileInfo(file_id0
, info
));
207 TEST_F(SandboxDirectoryDatabaseTest
, TestMoveSameNameNameClash
) {
211 base::FilePath::StringType name0
= FILE_PATH_LITERAL("foo");
212 base::FilePath::StringType name1
= FILE_PATH_LITERAL("bar");
215 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id0
));
216 info
.parent_id
= file_id0
;
217 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id1
));
219 EXPECT_FALSE(db()->UpdateFileInfo(file_id1
, info
));
221 EXPECT_TRUE(db()->UpdateFileInfo(file_id1
, info
));
224 TEST_F(SandboxDirectoryDatabaseTest
, TestMoveRenameNameClash
) {
228 base::FilePath::StringType name0
= FILE_PATH_LITERAL("foo");
229 base::FilePath::StringType name1
= FILE_PATH_LITERAL("bar");
230 base::FilePath::StringType name2
= FILE_PATH_LITERAL("bas");
233 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id0
));
234 info
.parent_id
= file_id0
;
236 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id1
));
239 EXPECT_FALSE(db()->UpdateFileInfo(file_id1
, info
));
241 EXPECT_TRUE(db()->UpdateFileInfo(file_id1
, info
));
242 // Also test a successful move+rename.
243 info
.parent_id
= file_id0
;
245 EXPECT_TRUE(db()->UpdateFileInfo(file_id1
, info
));
248 TEST_F(SandboxDirectoryDatabaseTest
, TestRemoveWithChildren
) {
253 info
.name
= FILE_PATH_LITERAL("foo");
254 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id0
));
255 info
.parent_id
= file_id0
;
256 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id1
));
257 EXPECT_FALSE(db()->RemoveFileInfo(file_id0
));
258 EXPECT_TRUE(db()->RemoveFileInfo(file_id1
));
259 EXPECT_TRUE(db()->RemoveFileInfo(file_id0
));
262 TEST_F(SandboxDirectoryDatabaseTest
, TestGetChildWithName
) {
266 base::FilePath::StringType name0
= FILE_PATH_LITERAL("foo");
267 base::FilePath::StringType name1
= FILE_PATH_LITERAL("bar");
270 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id0
));
271 info
.parent_id
= file_id0
;
273 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id1
));
274 EXPECT_NE(file_id0
, file_id1
);
276 FileId check_file_id
;
277 EXPECT_FALSE(db()->GetChildWithName(0, name1
, &check_file_id
));
278 EXPECT_TRUE(db()->GetChildWithName(0, name0
, &check_file_id
));
279 EXPECT_EQ(file_id0
, check_file_id
);
280 EXPECT_FALSE(db()->GetChildWithName(file_id0
, name0
, &check_file_id
));
281 EXPECT_TRUE(db()->GetChildWithName(file_id0
, name1
, &check_file_id
));
282 EXPECT_EQ(file_id1
, check_file_id
);
285 TEST_F(SandboxDirectoryDatabaseTest
, TestGetFileWithPath
) {
290 base::FilePath::StringType name0
= FILE_PATH_LITERAL("foo");
291 base::FilePath::StringType name1
= FILE_PATH_LITERAL("bar");
292 base::FilePath::StringType name2
= FILE_PATH_LITERAL("dog");
296 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id0
));
297 info
.parent_id
= file_id0
;
299 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id1
));
300 EXPECT_NE(file_id0
, file_id1
);
301 info
.parent_id
= file_id1
;
303 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id2
));
304 EXPECT_NE(file_id0
, file_id2
);
305 EXPECT_NE(file_id1
, file_id2
);
307 FileId check_file_id
;
308 base::FilePath path
= base::FilePath(name0
);
309 EXPECT_TRUE(db()->GetFileWithPath(path
, &check_file_id
));
310 EXPECT_EQ(file_id0
, check_file_id
);
312 path
= path
.Append(name1
);
313 EXPECT_TRUE(db()->GetFileWithPath(path
, &check_file_id
));
314 EXPECT_EQ(file_id1
, check_file_id
);
316 path
= path
.Append(name2
);
317 EXPECT_TRUE(db()->GetFileWithPath(path
, &check_file_id
));
318 EXPECT_EQ(file_id2
, check_file_id
);
321 TEST_F(SandboxDirectoryDatabaseTest
, TestListChildren
) {
322 // No children in the root.
323 std::vector
<FileId
> children
;
324 EXPECT_TRUE(db()->ListChildren(0, &children
));
325 EXPECT_TRUE(children
.empty());
327 // One child in the root.
331 info
.name
= FILE_PATH_LITERAL("foo");
332 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id0
));
333 EXPECT_TRUE(db()->ListChildren(0, &children
));
334 EXPECT_EQ(children
.size(), 1UL);
335 EXPECT_EQ(children
[0], file_id0
);
337 // Two children in the root.
339 info
.name
= FILE_PATH_LITERAL("bar");
340 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id1
));
341 EXPECT_TRUE(db()->ListChildren(0, &children
));
342 EXPECT_EQ(2UL, children
.size());
343 if (children
[0] == file_id0
) {
344 EXPECT_EQ(children
[1], file_id1
);
346 EXPECT_EQ(children
[1], file_id0
);
347 EXPECT_EQ(children
[0], file_id1
);
350 // No children in a subdirectory.
351 EXPECT_TRUE(db()->ListChildren(file_id0
, &children
));
352 EXPECT_TRUE(children
.empty());
354 // One child in a subdirectory.
355 info
.parent_id
= file_id0
;
356 info
.name
= FILE_PATH_LITERAL("foo");
359 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id2
));
360 EXPECT_TRUE(db()->ListChildren(file_id0
, &children
));
361 EXPECT_EQ(1UL, children
.size());
362 EXPECT_EQ(children
[0], file_id2
);
364 // Two children in a subdirectory.
365 info
.name
= FILE_PATH_LITERAL("bar");
366 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info
, &file_id3
));
367 EXPECT_TRUE(db()->ListChildren(file_id0
, &children
));
368 EXPECT_EQ(2UL, children
.size());
369 if (children
[0] == file_id2
) {
370 EXPECT_EQ(children
[1], file_id3
);
372 EXPECT_EQ(children
[1], file_id2
);
373 EXPECT_EQ(children
[0], file_id3
);
377 TEST_F(SandboxDirectoryDatabaseTest
, TestUpdateModificationTime
) {
381 info0
.name
= FILE_PATH_LITERAL("name");
382 info0
.data_path
= base::FilePath(FILE_PATH_LITERAL("fake path"));
383 info0
.modification_time
= base::Time::Now();
384 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info0
, &file_id
));
386 EXPECT_TRUE(db()->GetFileInfo(file_id
, &info1
));
387 EXPECT_EQ(info0
.name
, info1
.name
);
388 EXPECT_EQ(info0
.parent_id
, info1
.parent_id
);
389 EXPECT_EQ(info0
.data_path
, info1
.data_path
);
391 floor(info0
.modification_time
.ToDoubleT()),
392 info1
.modification_time
.ToDoubleT());
394 EXPECT_TRUE(db()->UpdateModificationTime(file_id
, base::Time::UnixEpoch()));
395 EXPECT_TRUE(db()->GetFileInfo(file_id
, &info1
));
396 EXPECT_EQ(info0
.name
, info1
.name
);
397 EXPECT_EQ(info0
.parent_id
, info1
.parent_id
);
398 EXPECT_EQ(info0
.data_path
, info1
.data_path
);
399 EXPECT_NE(info0
.modification_time
, info1
.modification_time
);
401 info1
.modification_time
.ToDoubleT(),
402 floor(base::Time::UnixEpoch().ToDoubleT()));
404 EXPECT_FALSE(db()->UpdateModificationTime(999, base::Time::UnixEpoch()));
407 TEST_F(SandboxDirectoryDatabaseTest
, TestSimpleFileOperations
) {
408 FileId file_id
= 888;
410 EXPECT_FALSE(db()->GetFileInfo(file_id
, &info0
));
412 info0
.data_path
= base::FilePath(FILE_PATH_LITERAL("foo"));
413 info0
.name
= FILE_PATH_LITERAL("file name");
414 info0
.modification_time
= base::Time::Now();
415 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info0
, &file_id
));
417 EXPECT_TRUE(db()->GetFileInfo(file_id
, &info1
));
418 EXPECT_EQ(info0
.parent_id
, info1
.parent_id
);
419 EXPECT_EQ(info0
.data_path
, info1
.data_path
);
420 EXPECT_EQ(info0
.name
, info1
.name
);
422 floor(info0
.modification_time
.ToDoubleT()),
423 info1
.modification_time
.ToDoubleT());
426 TEST_F(SandboxDirectoryDatabaseTest
, TestOverwritingMoveFileSrcDirectory
) {
430 info0
.name
= FILE_PATH_LITERAL("directory");
431 info0
.modification_time
= base::Time::Now();
432 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info0
, &directory_id
));
437 info1
.data_path
= base::FilePath(FILE_PATH_LITERAL("bar"));
438 info1
.name
= FILE_PATH_LITERAL("file");
439 info1
.modification_time
= base::Time::UnixEpoch();
440 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info1
, &file_id
));
442 EXPECT_FALSE(db()->OverwritingMoveFile(directory_id
, file_id
));
445 TEST_F(SandboxDirectoryDatabaseTest
, TestOverwritingMoveFileDestDirectory
) {
449 info0
.name
= FILE_PATH_LITERAL("file");
450 info0
.data_path
= base::FilePath(FILE_PATH_LITERAL("bar"));
451 info0
.modification_time
= base::Time::Now();
452 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info0
, &file_id
));
457 info1
.name
= FILE_PATH_LITERAL("directory");
458 info1
.modification_time
= base::Time::UnixEpoch();
459 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info1
, &directory_id
));
461 EXPECT_FALSE(db()->OverwritingMoveFile(file_id
, directory_id
));
464 TEST_F(SandboxDirectoryDatabaseTest
, TestOverwritingMoveFileSuccess
) {
468 info0
.data_path
= base::FilePath(FILE_PATH_LITERAL("foo"));
469 info0
.name
= FILE_PATH_LITERAL("file name 0");
470 info0
.modification_time
= base::Time::Now();
471 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info0
, &file_id0
));
475 dir_info
.parent_id
= 0;
476 dir_info
.name
= FILE_PATH_LITERAL("directory name");
477 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(dir_info
, &dir_id
));
481 info1
.parent_id
= dir_id
;
482 info1
.data_path
= base::FilePath(FILE_PATH_LITERAL("bar"));
483 info1
.name
= FILE_PATH_LITERAL("file name 1");
484 info1
.modification_time
= base::Time::UnixEpoch();
485 EXPECT_EQ(base::PLATFORM_FILE_OK
, db()->AddFileInfo(info1
, &file_id1
));
487 EXPECT_TRUE(db()->OverwritingMoveFile(file_id0
, file_id1
));
492 EXPECT_FALSE(db()->GetFileWithPath(base::FilePath(info0
.name
), &check_id
));
493 EXPECT_TRUE(db()->GetFileWithPath(
494 base::FilePath(dir_info
.name
).Append(info1
.name
), &check_id
));
495 EXPECT_TRUE(db()->GetFileInfo(check_id
, &check_info
));
497 EXPECT_EQ(info0
.data_path
, check_info
.data_path
);
500 TEST_F(SandboxDirectoryDatabaseTest
, TestGetNextInteger
) {
502 EXPECT_TRUE(db()->GetNextInteger(&next
));
504 EXPECT_TRUE(db()->GetNextInteger(&next
));
507 EXPECT_TRUE(db()->GetNextInteger(&next
));
509 EXPECT_TRUE(db()->GetNextInteger(&next
));
512 EXPECT_TRUE(db()->GetNextInteger(&next
));
516 TEST_F(SandboxDirectoryDatabaseTest
, TestConsistencyCheck_Empty
) {
517 EXPECT_TRUE(db()->IsFileSystemConsistent());
520 EXPECT_TRUE(db()->GetNextInteger(&next
));
522 EXPECT_TRUE(db()->IsFileSystemConsistent());
525 TEST_F(SandboxDirectoryDatabaseTest
, TestConsistencyCheck_Consistent
) {
527 CreateFile(0, FPL("foo"), FPL("hoge"), NULL
);
528 CreateDirectory(0, FPL("bar"), &dir_id
);
529 CreateFile(dir_id
, FPL("baz"), FPL("fuga"), NULL
);
530 CreateFile(dir_id
, FPL("fizz"), FPL("buzz"), NULL
);
532 EXPECT_TRUE(db()->IsFileSystemConsistent());
535 TEST_F(SandboxDirectoryDatabaseTest
,
536 TestConsistencyCheck_BackingMultiEntry
) {
537 const base::FilePath::CharType kBackingFileName
[] = FPL("the celeb");
538 CreateFile(0, FPL("foo"), kBackingFileName
, NULL
);
540 EXPECT_TRUE(db()->IsFileSystemConsistent());
541 ASSERT_TRUE(base::DeleteFile(path().Append(kBackingFileName
), false));
542 CreateFile(0, FPL("bar"), kBackingFileName
, NULL
);
543 EXPECT_FALSE(db()->IsFileSystemConsistent());
546 TEST_F(SandboxDirectoryDatabaseTest
, TestConsistencyCheck_FileLost
) {
547 const base::FilePath::CharType kBackingFileName
[] = FPL("hoge");
548 CreateFile(0, FPL("foo"), kBackingFileName
, NULL
);
550 EXPECT_TRUE(db()->IsFileSystemConsistent());
551 ASSERT_TRUE(base::DeleteFile(path().Append(kBackingFileName
), false));
552 EXPECT_TRUE(db()->IsFileSystemConsistent());
555 TEST_F(SandboxDirectoryDatabaseTest
, TestConsistencyCheck_OrphanFile
) {
556 CreateFile(0, FPL("foo"), FPL("hoge"), NULL
);
558 EXPECT_TRUE(db()->IsFileSystemConsistent());
560 bool created
= false;
561 base::PlatformFileError error
= base::PLATFORM_FILE_ERROR_FAILED
;
562 base::PlatformFile file
= base::CreatePlatformFile(
563 path().Append(FPL("Orphan File")),
564 base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
,
566 ASSERT_EQ(base::PLATFORM_FILE_OK
, error
);
567 ASSERT_TRUE(created
);
568 ASSERT_TRUE(base::ClosePlatformFile(file
));
570 EXPECT_TRUE(db()->IsFileSystemConsistent());
573 TEST_F(SandboxDirectoryDatabaseTest
, TestConsistencyCheck_RootLoop
) {
574 EXPECT_TRUE(db()->IsFileSystemConsistent());
575 MakeHierarchyLink(0, 0, base::FilePath::StringType());
576 EXPECT_FALSE(db()->IsFileSystemConsistent());
579 TEST_F(SandboxDirectoryDatabaseTest
, TestConsistencyCheck_DirectoryLoop
) {
582 base::FilePath::StringType dir1_name
= FPL("foo");
583 CreateDirectory(0, dir1_name
, &dir1_id
);
584 CreateDirectory(dir1_id
, FPL("bar"), &dir2_id
);
586 EXPECT_TRUE(db()->IsFileSystemConsistent());
587 MakeHierarchyLink(dir2_id
, dir1_id
, dir1_name
);
588 EXPECT_FALSE(db()->IsFileSystemConsistent());
591 TEST_F(SandboxDirectoryDatabaseTest
, TestConsistencyCheck_NameMismatch
) {
594 CreateDirectory(0, FPL("foo"), &dir_id
);
595 CreateFile(dir_id
, FPL("bar"), FPL("hoge/fuga/piyo"), &file_id
);
597 EXPECT_TRUE(db()->IsFileSystemConsistent());
598 DeleteHierarchyLink(file_id
);
599 MakeHierarchyLink(dir_id
, file_id
, FPL("baz"));
600 EXPECT_FALSE(db()->IsFileSystemConsistent());
603 TEST_F(SandboxDirectoryDatabaseTest
, TestConsistencyCheck_WreckedEntries
) {
606 CreateDirectory(0, FPL("foo"), &dir1_id
);
607 CreateDirectory(dir1_id
, FPL("bar"), &dir2_id
);
608 CreateFile(dir2_id
, FPL("baz"), FPL("fizz/buzz"), NULL
);
610 EXPECT_TRUE(db()->IsFileSystemConsistent());
611 DeleteHierarchyLink(dir2_id
); // Delete link from |dir1_id| to |dir2_id|.
612 EXPECT_FALSE(db()->IsFileSystemConsistent());
615 TEST_F(SandboxDirectoryDatabaseTest
, TestRepairDatabase_Success
) {
616 base::FilePath::StringType kFileName
= FPL("bar");
619 CreateFile(0, FPL("foo"), FPL("hoge"), NULL
);
620 CreateFile(0, kFileName
, FPL("fuga"), &file_id_prev
);
622 const base::FilePath kDatabaseDirectory
=
623 path().Append(kDirectoryDatabaseName
);
625 CorruptDatabase(kDatabaseDirectory
, leveldb::kDescriptorFile
,
626 0, std::numeric_limits
<size_t>::max());
628 EXPECT_FALSE(db()->IsFileSystemConsistent());
631 EXPECT_TRUE(db()->GetChildWithName(0, kFileName
, &file_id
));
632 EXPECT_EQ(file_id_prev
, file_id
);
634 EXPECT_TRUE(db()->IsFileSystemConsistent());
637 TEST_F(SandboxDirectoryDatabaseTest
, TestRepairDatabase_Failure
) {
638 base::FilePath::StringType kFileName
= FPL("bar");
640 CreateFile(0, FPL("foo"), FPL("hoge"), NULL
);
641 CreateFile(0, kFileName
, FPL("fuga"), NULL
);
643 const base::FilePath kDatabaseDirectory
=
644 path().Append(kDirectoryDatabaseName
);
646 CorruptDatabase(kDatabaseDirectory
, leveldb::kDescriptorFile
,
647 0, std::numeric_limits
<size_t>::max());
648 CorruptDatabase(kDatabaseDirectory
, leveldb::kLogFile
,
651 EXPECT_FALSE(db()->IsFileSystemConsistent());
654 EXPECT_FALSE(db()->GetChildWithName(0, kFileName
, &file_id
));
655 EXPECT_TRUE(db()->IsFileSystemConsistent());
658 TEST_F(SandboxDirectoryDatabaseTest
, TestRepairDatabase_MissingManifest
) {
659 base::FilePath::StringType kFileName
= FPL("bar");
662 CreateFile(0, FPL("foo"), FPL("hoge"), NULL
);
663 CreateFile(0, kFileName
, FPL("fuga"), &file_id_prev
);
665 const base::FilePath kDatabaseDirectory
=
666 path().Append(kDirectoryDatabaseName
);
669 DeleteDatabaseFile(kDatabaseDirectory
, leveldb::kDescriptorFile
);
672 EXPECT_FALSE(db()->IsFileSystemConsistent());
675 EXPECT_TRUE(db()->GetChildWithName(0, kFileName
, &file_id
));
676 EXPECT_EQ(file_id_prev
, file_id
);
678 EXPECT_TRUE(db()->IsFileSystemConsistent());
681 } // namespace fileapi