Re-subimission of https://codereview.chromium.org/1041213003/
[chromium-blink-merge.git] / content / browser / fileapi / sandbox_directory_database_unittest.cc
blobdcb74a272c2462805dedb3f5824b4bff11ab746a
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.
5 #include "storage/browser/fileapi/sandbox_directory_database.h"
7 #include <math.h>
8 #include <limits>
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"
21 #define FPL(x) FILE_PATH_LITERAL(x)
23 using storage::FilePathToString;
24 using storage::SandboxDirectoryDatabase;
26 namespace content {
28 namespace {
29 const base::FilePath::CharType kDirectoryDatabaseName[] = FPL("Paths");
32 class SandboxDirectoryDatabaseTest : public testing::Test {
33 public:
34 typedef SandboxDirectoryDatabase::FileId FileId;
35 typedef SandboxDirectoryDatabase::FileInfo FileInfo;
37 SandboxDirectoryDatabaseTest() {
38 EXPECT_TRUE(base_.CreateUniqueTempDir());
39 InitDatabase();
42 SandboxDirectoryDatabase* db() {
43 return db_.get();
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));
53 void CloseDatabase() {
54 db_.reset();
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);
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));
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;
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));
87 base::FilePath local_path = path().Append(data_path);
88 if (!base::DirectoryExists(local_path.DirName()))
89 ASSERT_TRUE(base::CreateDirectory(local_path.DirName()));
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());
96 if (file_id_out)
97 *file_id_out = file_id;
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));
107 bool RepairDatabase() {
108 return db()->RepairDatabase(
109 FilePathToString(path().Append(kDirectoryDatabaseName)));
112 const base::FilePath& path() {
113 return base_.path();
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());
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());
137 protected:
138 // Common temp base for nondestructive uses.
139 base::ScopedTempDir base_;
140 scoped_ptr<SandboxDirectoryDatabase> db_;
142 private:
143 DISALLOW_COPY_AND_ASSIGN(SandboxDirectoryDatabaseTest);
146 TEST_F(SandboxDirectoryDatabaseTest, TestMissingFileGetInfo) {
147 FileId file_id = 888;
148 FileInfo info;
149 EXPECT_FALSE(db()->GetFileInfo(file_id, &info));
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());
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")));
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));
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));
180 name = FILE_PATH_LITERAL("subdir 0");
181 EXPECT_EQ(base::File::FILE_OK, AddFileInfo(file_id, name));
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));
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));
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));
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));
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));
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);
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);
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");
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);
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);
310 path = path.Append(name1);
311 EXPECT_TRUE(db()->GetFileWithPath(path, &check_file_id));
312 EXPECT_EQ(file_id1, check_file_id);
314 path = path.Append(name2);
315 EXPECT_TRUE(db()->GetFileWithPath(path, &check_file_id));
316 EXPECT_EQ(file_id2, check_file_id);
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());
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);
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);
348 // No children in a subdirectory.
349 EXPECT_TRUE(db()->ListChildren(file_id0, &children));
350 EXPECT_TRUE(children.empty());
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);
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);
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());
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()));
402 EXPECT_FALSE(db()->UpdateModificationTime(999, base::Time::UnixEpoch()));
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());
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));
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));
440 EXPECT_FALSE(db()->OverwritingMoveFile(directory_id, file_id));
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));
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));
459 EXPECT_FALSE(db()->OverwritingMoveFile(file_id, directory_id));
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));
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));
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));
485 EXPECT_TRUE(db()->OverwritingMoveFile(file_id0, file_id1));
487 FileInfo check_info;
488 FileId check_id;
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));
495 EXPECT_EQ(info0.data_path, check_info.data_path);
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);
514 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_Empty) {
515 EXPECT_TRUE(db()->IsFileSystemConsistent());
517 int64 next = -1;
518 EXPECT_TRUE(db()->GetNextInteger(&next));
519 EXPECT_EQ(0, next);
520 EXPECT_TRUE(db()->IsFileSystemConsistent());
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);
530 EXPECT_TRUE(db()->IsFileSystemConsistent());
533 TEST_F(SandboxDirectoryDatabaseTest,
534 TestConsistencyCheck_BackingMultiEntry) {
535 const base::FilePath::CharType kBackingFileName[] = FPL("the celeb");
536 CreateFile(0, FPL("foo"), kBackingFileName, NULL);
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());
544 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_FileLost) {
545 const base::FilePath::CharType kBackingFileName[] = FPL("hoge");
546 CreateFile(0, FPL("foo"), kBackingFileName, NULL);
548 EXPECT_TRUE(db()->IsFileSystemConsistent());
549 ASSERT_TRUE(base::DeleteFile(path().Append(kBackingFileName), false));
550 EXPECT_TRUE(db()->IsFileSystemConsistent());
553 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_OrphanFile) {
554 CreateFile(0, FPL("foo"), FPL("hoge"), NULL);
556 EXPECT_TRUE(db()->IsFileSystemConsistent());
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();
564 EXPECT_TRUE(db()->IsFileSystemConsistent());
567 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_RootLoop) {
568 EXPECT_TRUE(db()->IsFileSystemConsistent());
569 MakeHierarchyLink(0, 0, base::FilePath::StringType());
570 EXPECT_FALSE(db()->IsFileSystemConsistent());
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);
580 EXPECT_TRUE(db()->IsFileSystemConsistent());
581 MakeHierarchyLink(dir2_id, dir1_id, dir1_name);
582 EXPECT_FALSE(db()->IsFileSystemConsistent());
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);
591 EXPECT_TRUE(db()->IsFileSystemConsistent());
592 DeleteHierarchyLink(file_id);
593 MakeHierarchyLink(dir_id, file_id, FPL("baz"));
594 EXPECT_FALSE(db()->IsFileSystemConsistent());
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);
604 EXPECT_TRUE(db()->IsFileSystemConsistent());
605 DeleteHierarchyLink(dir2_id); // Delete link from |dir1_id| to |dir2_id|.
606 EXPECT_FALSE(db()->IsFileSystemConsistent());
609 TEST_F(SandboxDirectoryDatabaseTest, TestRepairDatabase_Success) {
610 base::FilePath::StringType kFileName = FPL("bar");
612 FileId file_id_prev;
613 CreateFile(0, FPL("foo"), FPL("hoge"), NULL);
614 CreateFile(0, kFileName, FPL("fuga"), &file_id_prev);
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());
624 FileId file_id;
625 EXPECT_TRUE(db()->GetChildWithName(0, kFileName, &file_id));
626 EXPECT_EQ(file_id_prev, file_id);
628 EXPECT_TRUE(db()->IsFileSystemConsistent());
631 TEST_F(SandboxDirectoryDatabaseTest, TestRepairDatabase_Failure) {
632 base::FilePath::StringType kFileName = FPL("bar");
634 CreateFile(0, FPL("foo"), FPL("hoge"), NULL);
635 CreateFile(0, kFileName, FPL("fuga"), NULL);
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());
647 FileId file_id;
648 EXPECT_FALSE(db()->GetChildWithName(0, kFileName, &file_id));
649 EXPECT_TRUE(db()->IsFileSystemConsistent());
652 TEST_F(SandboxDirectoryDatabaseTest, TestRepairDatabase_MissingManifest) {
653 base::FilePath::StringType kFileName = FPL("bar");
655 FileId file_id_prev;
656 CreateFile(0, FPL("foo"), FPL("hoge"), NULL);
657 CreateFile(0, kFileName, FPL("fuga"), &file_id_prev);
659 const base::FilePath kDatabaseDirectory =
660 path().Append(kDirectoryDatabaseName);
661 CloseDatabase();
663 DeleteDatabaseFile(kDatabaseDirectory, leveldb::kDescriptorFile);
665 InitDatabase();
666 EXPECT_FALSE(db()->IsFileSystemConsistent());
668 FileId file_id;
669 EXPECT_TRUE(db()->GetChildWithName(0, kFileName, &file_id));
670 EXPECT_EQ(file_id_prev, file_id);
672 EXPECT_TRUE(db()->IsFileSystemConsistent());
675 } // namespace content