Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(405)

Side by Side Diff: webkit/fileapi/file_system_directory_database_unittest.cc

Issue 9910005: Add database recovery for FileSystemDirectoryDatabase. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: -TODO Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698