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.
10 #include "base/file_util.h"
11 #include "base/files/file_path.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/platform_file.h"
14 #include "base/stl_util.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/leveldatabase/src/db/filename.h"
17 #include "third_party/leveldatabase/src/include/leveldb/db.h"
18 #include "webkit/fileapi/file_system_database_test_helper.h"
19 #include "webkit/fileapi/file_system_origin_database.h"
20 #include "webkit/fileapi/file_system_util.h"
25 const base::FilePath::CharType kFileSystemDirName
[] =
26 FILE_PATH_LITERAL("File System");
27 const base::FilePath::CharType kOriginDatabaseName
[] = FILE_PATH_LITERAL("Origins");
30 TEST(FileSystemOriginDatabaseTest
, BasicTest
) {
31 base::ScopedTempDir dir
;
32 ASSERT_TRUE(dir
.CreateUniqueTempDir());
33 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
34 EXPECT_FALSE(file_util::PathExists(kFSDir
));
35 EXPECT_TRUE(file_util::CreateDirectory(kFSDir
));
37 FileSystemOriginDatabase
database(kFSDir
);
38 std::string
origin("origin");
40 EXPECT_FALSE(database
.HasOriginPath(origin
));
41 // Double-check to make sure that had no side effects.
42 EXPECT_FALSE(database
.HasOriginPath(origin
));
47 // Empty strings aren't valid origins.
48 EXPECT_FALSE(database
.GetPathForOrigin(std::string(), &path0
));
50 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path0
));
51 EXPECT_TRUE(database
.HasOriginPath(origin
));
52 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path1
));
53 EXPECT_FALSE(path0
.empty());
54 EXPECT_FALSE(path1
.empty());
55 EXPECT_EQ(path0
, path1
);
57 EXPECT_TRUE(file_util::PathExists(kFSDir
.Append(kOriginDatabaseName
)));
60 TEST(FileSystemOriginDatabaseTest
, TwoPathTest
) {
61 base::ScopedTempDir dir
;
62 ASSERT_TRUE(dir
.CreateUniqueTempDir());
63 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
64 EXPECT_FALSE(file_util::PathExists(kFSDir
));
65 EXPECT_TRUE(file_util::CreateDirectory(kFSDir
));
67 FileSystemOriginDatabase
database(kFSDir
);
68 std::string
origin0("origin0");
69 std::string
origin1("origin1");
71 EXPECT_FALSE(database
.HasOriginPath(origin0
));
72 EXPECT_FALSE(database
.HasOriginPath(origin1
));
76 EXPECT_TRUE(database
.GetPathForOrigin(origin0
, &path0
));
77 EXPECT_TRUE(database
.HasOriginPath(origin0
));
78 EXPECT_FALSE(database
.HasOriginPath(origin1
));
79 EXPECT_TRUE(database
.GetPathForOrigin(origin1
, &path1
));
80 EXPECT_TRUE(database
.HasOriginPath(origin1
));
81 EXPECT_FALSE(path0
.empty());
82 EXPECT_FALSE(path1
.empty());
83 EXPECT_NE(path0
, path1
);
85 EXPECT_TRUE(file_util::PathExists(kFSDir
.Append(kOriginDatabaseName
)));
88 TEST(FileSystemOriginDatabaseTest
, DropDatabaseTest
) {
89 base::ScopedTempDir dir
;
90 ASSERT_TRUE(dir
.CreateUniqueTempDir());
91 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
92 EXPECT_FALSE(file_util::PathExists(kFSDir
));
93 EXPECT_TRUE(file_util::CreateDirectory(kFSDir
));
95 FileSystemOriginDatabase
database(kFSDir
);
96 std::string
origin("origin");
98 EXPECT_FALSE(database
.HasOriginPath(origin
));
100 base::FilePath path0
;
101 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path0
));
102 EXPECT_TRUE(database
.HasOriginPath(origin
));
103 EXPECT_FALSE(path0
.empty());
105 EXPECT_TRUE(file_util::PathExists(kFSDir
.Append(kOriginDatabaseName
)));
107 database
.DropDatabase();
109 base::FilePath path1
;
110 EXPECT_TRUE(database
.HasOriginPath(origin
));
111 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path1
));
112 EXPECT_FALSE(path1
.empty());
113 EXPECT_EQ(path0
, path1
);
116 TEST(FileSystemOriginDatabaseTest
, DeleteOriginTest
) {
117 base::ScopedTempDir dir
;
118 ASSERT_TRUE(dir
.CreateUniqueTempDir());
119 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
120 EXPECT_FALSE(file_util::PathExists(kFSDir
));
121 EXPECT_TRUE(file_util::CreateDirectory(kFSDir
));
123 FileSystemOriginDatabase
database(kFSDir
);
124 std::string
origin("origin");
126 EXPECT_FALSE(database
.HasOriginPath(origin
));
127 EXPECT_TRUE(database
.RemovePathForOrigin(origin
));
129 base::FilePath path0
;
130 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path0
));
131 EXPECT_TRUE(database
.HasOriginPath(origin
));
132 EXPECT_FALSE(path0
.empty());
134 EXPECT_TRUE(database
.RemovePathForOrigin(origin
));
135 EXPECT_FALSE(database
.HasOriginPath(origin
));
137 base::FilePath path1
;
138 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path1
));
139 EXPECT_FALSE(path1
.empty());
140 EXPECT_NE(path0
, path1
);
143 TEST(FileSystemOriginDatabaseTest
, ListOriginsTest
) {
144 base::ScopedTempDir dir
;
145 ASSERT_TRUE(dir
.CreateUniqueTempDir());
146 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
147 EXPECT_FALSE(file_util::PathExists(kFSDir
));
148 EXPECT_TRUE(file_util::CreateDirectory(kFSDir
));
150 std::vector
<FileSystemOriginDatabase::OriginRecord
> origins
;
152 FileSystemOriginDatabase
database(kFSDir
);
153 EXPECT_TRUE(database
.ListAllOrigins(&origins
));
154 EXPECT_TRUE(origins
.empty());
157 std::string
origin0("origin0");
158 std::string
origin1("origin1");
160 EXPECT_FALSE(database
.HasOriginPath(origin0
));
161 EXPECT_FALSE(database
.HasOriginPath(origin1
));
163 base::FilePath path0
;
164 base::FilePath path1
;
165 EXPECT_TRUE(database
.GetPathForOrigin(origin0
, &path0
));
166 EXPECT_TRUE(database
.ListAllOrigins(&origins
));
167 EXPECT_EQ(origins
.size(), 1UL);
168 EXPECT_EQ(origins
[0].origin
, origin0
);
169 EXPECT_EQ(origins
[0].path
, path0
);
171 EXPECT_TRUE(database
.GetPathForOrigin(origin1
, &path1
));
172 EXPECT_TRUE(database
.ListAllOrigins(&origins
));
173 EXPECT_EQ(origins
.size(), 2UL);
174 if (origins
[0].origin
== origin0
) {
175 EXPECT_EQ(origins
[0].path
, path0
);
176 EXPECT_EQ(origins
[1].origin
, origin1
);
177 EXPECT_EQ(origins
[1].path
, path1
);
179 EXPECT_EQ(origins
[0].origin
, origin1
);
180 EXPECT_EQ(origins
[0].path
, path1
);
181 EXPECT_EQ(origins
[1].origin
, origin0
);
182 EXPECT_EQ(origins
[1].path
, path0
);
186 TEST(FileSystemOriginDatabaseTest
, DatabaseRecoveryTest
) {
187 // Checks if FileSystemOriginDatabase properly handles database corruption.
188 // In this test, we'll register some origins to the origin database, then
189 // corrupt database and its log file.
190 // After repairing, the origin database should be consistent even when some
193 base::ScopedTempDir dir
;
194 ASSERT_TRUE(dir
.CreateUniqueTempDir());
195 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
196 const base::FilePath kDBDir
= kFSDir
.Append(kOriginDatabaseName
);
197 EXPECT_FALSE(file_util::PathExists(kFSDir
));
198 EXPECT_TRUE(file_util::CreateDirectory(kFSDir
));
200 const std::string kOrigins
[] = {
208 scoped_ptr
<FileSystemOriginDatabase
> database(
209 new FileSystemOriginDatabase(kFSDir
));
210 for (size_t i
= 0; i
< arraysize(kOrigins
); ++i
) {
212 EXPECT_FALSE(database
->HasOriginPath(kOrigins
[i
]));
213 EXPECT_TRUE(database
->GetPathForOrigin(kOrigins
[i
], &path
));
214 EXPECT_FALSE(path
.empty());
215 EXPECT_TRUE(database
->GetPathForOrigin(kOrigins
[i
], &path
));
218 EXPECT_TRUE(file_util::CreateDirectory(kFSDir
.Append(path
)));
222 const base::FilePath kGarbageDir
= kFSDir
.AppendASCII("foo");
223 const base::FilePath kGarbageFile
= kGarbageDir
.AppendASCII("bar");
224 EXPECT_TRUE(file_util::CreateDirectory(kGarbageDir
));
225 bool created
= false;
226 base::PlatformFileError error
;
227 base::PlatformFile file
= base::CreatePlatformFile(
229 base::PLATFORM_FILE_CREATE
| base::PLATFORM_FILE_WRITE
,
231 EXPECT_EQ(base::PLATFORM_FILE_OK
, error
);
232 EXPECT_TRUE(created
);
233 EXPECT_TRUE(base::ClosePlatformFile(file
));
235 // Corrupt database itself and last log entry to drop last 1 database
236 // operation. The database should detect the corruption and should recover
237 // its consistency after recovery.
238 CorruptDatabase(kDBDir
, leveldb::kDescriptorFile
,
239 0, std::numeric_limits
<size_t>::max());
240 CorruptDatabase(kDBDir
, leveldb::kLogFile
, -1, 1);
243 database
.reset(new FileSystemOriginDatabase(kFSDir
));
244 std::vector
<FileSystemOriginDatabase::OriginRecord
> origins_in_db
;
245 EXPECT_TRUE(database
->ListAllOrigins(&origins_in_db
));
247 // Expect all but last added origin will be repaired back, and kOrigins[1]
248 // should be dropped due to absence of backing directory.
249 EXPECT_EQ(arraysize(kOrigins
) - 2, origins_in_db
.size());
251 const std::string
kOrigin("piyo.example.org");
252 EXPECT_FALSE(database
->HasOriginPath(kOrigin
));
253 EXPECT_TRUE(database
->GetPathForOrigin(kOrigin
, &path
));
254 EXPECT_FALSE(path
.empty());
255 EXPECT_TRUE(database
->HasOriginPath(kOrigin
));
257 EXPECT_FALSE(file_util::PathExists(kGarbageFile
));
258 EXPECT_FALSE(file_util::PathExists(kGarbageDir
));
261 TEST(FileSystemOriginDatabaseTest
, DatabaseRecoveryForMissingDBFileTest
) {
262 const leveldb::FileType kLevelDBFileTypes
[] = {
264 leveldb::kDBLockFile
,
266 leveldb::kDescriptorFile
,
267 leveldb::kCurrentFile
,
269 leveldb::kInfoLogFile
,
272 for (size_t i
= 0; i
< arraysize(kLevelDBFileTypes
); ++i
) {
273 base::ScopedTempDir dir
;
274 ASSERT_TRUE(dir
.CreateUniqueTempDir());
275 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
276 const base::FilePath kDBDir
= kFSDir
.Append(kOriginDatabaseName
);
277 EXPECT_FALSE(file_util::PathExists(kFSDir
));
278 EXPECT_TRUE(file_util::CreateDirectory(kFSDir
));
280 const std::string kOrigin
= "foo.example.com";
283 scoped_ptr
<FileSystemOriginDatabase
> database(
284 new FileSystemOriginDatabase(kFSDir
));
285 EXPECT_FALSE(database
->HasOriginPath(kOrigin
));
286 EXPECT_TRUE(database
->GetPathForOrigin(kOrigin
, &path
));
287 EXPECT_FALSE(path
.empty());
288 EXPECT_TRUE(database
->GetPathForOrigin(kOrigin
, &path
));
289 EXPECT_TRUE(file_util::CreateDirectory(kFSDir
.Append(path
)));
292 DeleteDatabaseFile(kDBDir
, kLevelDBFileTypes
[i
]);
294 database
.reset(new FileSystemOriginDatabase(kFSDir
));
295 std::vector
<FileSystemOriginDatabase::OriginRecord
> origins_in_db
;
296 EXPECT_TRUE(database
->ListAllOrigins(&origins_in_db
));
298 const std::string
kOrigin2("piyo.example.org");
299 EXPECT_FALSE(database
->HasOriginPath(kOrigin2
));
300 EXPECT_TRUE(database
->GetPathForOrigin(kOrigin2
, &path
));
301 EXPECT_FALSE(path
.empty());
302 EXPECT_TRUE(database
->HasOriginPath(kOrigin2
));
306 } // namespace fileapi