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.
11 #include "base/file_util.h"
12 #include "base/files/file.h"
13 #include "base/files/file_path.h"
14 #include "base/files/scoped_temp_dir.h"
15 #include "base/stl_util.h"
16 #include "content/browser/fileapi/sandbox_database_test_helper.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/leveldatabase/src/db/filename.h"
19 #include "third_party/leveldatabase/src/include/leveldb/db.h"
20 #include "webkit/browser/fileapi/sandbox_origin_database.h"
21 #include "webkit/common/fileapi/file_system_util.h"
23 using storage::SandboxOriginDatabase
;
28 const base::FilePath::CharType kFileSystemDirName
[] =
29 FILE_PATH_LITERAL("File System");
30 const base::FilePath::CharType kOriginDatabaseName
[] =
31 FILE_PATH_LITERAL("Origins");
34 TEST(SandboxOriginDatabaseTest
, BasicTest
) {
35 base::ScopedTempDir dir
;
36 ASSERT_TRUE(dir
.CreateUniqueTempDir());
37 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
38 EXPECT_FALSE(base::PathExists(kFSDir
));
39 EXPECT_TRUE(base::CreateDirectory(kFSDir
));
41 SandboxOriginDatabase
database(kFSDir
, NULL
);
42 std::string
origin("origin");
44 EXPECT_FALSE(database
.HasOriginPath(origin
));
45 // Double-check to make sure that had no side effects.
46 EXPECT_FALSE(database
.HasOriginPath(origin
));
51 // Empty strings aren't valid origins.
52 EXPECT_FALSE(database
.GetPathForOrigin(std::string(), &path0
));
54 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path0
));
55 EXPECT_TRUE(database
.HasOriginPath(origin
));
56 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path1
));
57 EXPECT_FALSE(path0
.empty());
58 EXPECT_FALSE(path1
.empty());
59 EXPECT_EQ(path0
, path1
);
61 EXPECT_TRUE(base::PathExists(kFSDir
.Append(kOriginDatabaseName
)));
64 TEST(SandboxOriginDatabaseTest
, TwoPathTest
) {
65 base::ScopedTempDir dir
;
66 ASSERT_TRUE(dir
.CreateUniqueTempDir());
67 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
68 EXPECT_FALSE(base::PathExists(kFSDir
));
69 EXPECT_TRUE(base::CreateDirectory(kFSDir
));
71 SandboxOriginDatabase
database(kFSDir
, NULL
);
72 std::string
origin0("origin0");
73 std::string
origin1("origin1");
75 EXPECT_FALSE(database
.HasOriginPath(origin0
));
76 EXPECT_FALSE(database
.HasOriginPath(origin1
));
80 EXPECT_TRUE(database
.GetPathForOrigin(origin0
, &path0
));
81 EXPECT_TRUE(database
.HasOriginPath(origin0
));
82 EXPECT_FALSE(database
.HasOriginPath(origin1
));
83 EXPECT_TRUE(database
.GetPathForOrigin(origin1
, &path1
));
84 EXPECT_TRUE(database
.HasOriginPath(origin1
));
85 EXPECT_FALSE(path0
.empty());
86 EXPECT_FALSE(path1
.empty());
87 EXPECT_NE(path0
, path1
);
89 EXPECT_TRUE(base::PathExists(kFSDir
.Append(kOriginDatabaseName
)));
92 TEST(SandboxOriginDatabaseTest
, DropDatabaseTest
) {
93 base::ScopedTempDir dir
;
94 ASSERT_TRUE(dir
.CreateUniqueTempDir());
95 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
96 EXPECT_FALSE(base::PathExists(kFSDir
));
97 EXPECT_TRUE(base::CreateDirectory(kFSDir
));
99 SandboxOriginDatabase
database(kFSDir
, NULL
);
100 std::string
origin("origin");
102 EXPECT_FALSE(database
.HasOriginPath(origin
));
104 base::FilePath path0
;
105 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path0
));
106 EXPECT_TRUE(database
.HasOriginPath(origin
));
107 EXPECT_FALSE(path0
.empty());
109 EXPECT_TRUE(base::PathExists(kFSDir
.Append(kOriginDatabaseName
)));
111 database
.DropDatabase();
113 base::FilePath path1
;
114 EXPECT_TRUE(database
.HasOriginPath(origin
));
115 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path1
));
116 EXPECT_FALSE(path1
.empty());
117 EXPECT_EQ(path0
, path1
);
120 TEST(SandboxOriginDatabaseTest
, DeleteOriginTest
) {
121 base::ScopedTempDir dir
;
122 ASSERT_TRUE(dir
.CreateUniqueTempDir());
123 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
124 EXPECT_FALSE(base::PathExists(kFSDir
));
125 EXPECT_TRUE(base::CreateDirectory(kFSDir
));
127 SandboxOriginDatabase
database(kFSDir
, NULL
);
128 std::string
origin("origin");
130 EXPECT_FALSE(database
.HasOriginPath(origin
));
131 EXPECT_TRUE(database
.RemovePathForOrigin(origin
));
133 base::FilePath path0
;
134 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path0
));
135 EXPECT_TRUE(database
.HasOriginPath(origin
));
136 EXPECT_FALSE(path0
.empty());
138 EXPECT_TRUE(database
.RemovePathForOrigin(origin
));
139 EXPECT_FALSE(database
.HasOriginPath(origin
));
141 base::FilePath path1
;
142 EXPECT_TRUE(database
.GetPathForOrigin(origin
, &path1
));
143 EXPECT_FALSE(path1
.empty());
144 EXPECT_NE(path0
, path1
);
147 TEST(SandboxOriginDatabaseTest
, ListOriginsTest
) {
148 base::ScopedTempDir dir
;
149 ASSERT_TRUE(dir
.CreateUniqueTempDir());
150 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
151 EXPECT_FALSE(base::PathExists(kFSDir
));
152 EXPECT_TRUE(base::CreateDirectory(kFSDir
));
154 std::vector
<SandboxOriginDatabase::OriginRecord
> origins
;
156 SandboxOriginDatabase
database(kFSDir
, NULL
);
157 EXPECT_TRUE(database
.ListAllOrigins(&origins
));
158 EXPECT_TRUE(origins
.empty());
161 std::string
origin0("origin0");
162 std::string
origin1("origin1");
164 EXPECT_FALSE(database
.HasOriginPath(origin0
));
165 EXPECT_FALSE(database
.HasOriginPath(origin1
));
167 base::FilePath path0
;
168 base::FilePath path1
;
169 EXPECT_TRUE(database
.GetPathForOrigin(origin0
, &path0
));
170 EXPECT_TRUE(database
.ListAllOrigins(&origins
));
171 EXPECT_EQ(origins
.size(), 1UL);
172 EXPECT_EQ(origins
[0].origin
, origin0
);
173 EXPECT_EQ(origins
[0].path
, path0
);
175 EXPECT_TRUE(database
.GetPathForOrigin(origin1
, &path1
));
176 EXPECT_TRUE(database
.ListAllOrigins(&origins
));
177 EXPECT_EQ(origins
.size(), 2UL);
178 if (origins
[0].origin
== origin0
) {
179 EXPECT_EQ(origins
[0].path
, path0
);
180 EXPECT_EQ(origins
[1].origin
, origin1
);
181 EXPECT_EQ(origins
[1].path
, path1
);
183 EXPECT_EQ(origins
[0].origin
, origin1
);
184 EXPECT_EQ(origins
[0].path
, path1
);
185 EXPECT_EQ(origins
[1].origin
, origin0
);
186 EXPECT_EQ(origins
[1].path
, path0
);
190 TEST(SandboxOriginDatabaseTest
, DatabaseRecoveryTest
) {
191 // Checks if SandboxOriginDatabase properly handles database corruption.
192 // In this test, we'll register some origins to the origin database, then
193 // corrupt database and its log file.
194 // After repairing, the origin database should be consistent even when some
197 base::ScopedTempDir dir
;
198 ASSERT_TRUE(dir
.CreateUniqueTempDir());
199 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
200 const base::FilePath kDBDir
= kFSDir
.Append(kOriginDatabaseName
);
201 EXPECT_FALSE(base::PathExists(kFSDir
));
202 EXPECT_TRUE(base::CreateDirectory(kFSDir
));
204 const std::string kOrigins
[] = {
212 scoped_ptr
<SandboxOriginDatabase
> database(
213 new SandboxOriginDatabase(kFSDir
, NULL
));
214 for (size_t i
= 0; i
< arraysize(kOrigins
); ++i
) {
216 EXPECT_FALSE(database
->HasOriginPath(kOrigins
[i
]));
217 EXPECT_TRUE(database
->GetPathForOrigin(kOrigins
[i
], &path
));
218 EXPECT_FALSE(path
.empty());
219 EXPECT_TRUE(database
->GetPathForOrigin(kOrigins
[i
], &path
));
222 EXPECT_TRUE(base::CreateDirectory(kFSDir
.Append(path
)));
226 const base::FilePath kGarbageDir
= kFSDir
.AppendASCII("foo");
227 const base::FilePath kGarbageFile
= kGarbageDir
.AppendASCII("bar");
228 EXPECT_TRUE(base::CreateDirectory(kGarbageDir
));
229 base::File
file(kGarbageFile
,
230 base::File::FLAG_CREATE
| base::File::FLAG_WRITE
);
231 EXPECT_TRUE(file
.IsValid());
234 // Corrupt database itself and last log entry to drop last 1 database
235 // operation. The database should detect the corruption and should recover
236 // its consistency after recovery.
237 CorruptDatabase(kDBDir
, leveldb::kDescriptorFile
,
238 0, std::numeric_limits
<size_t>::max());
239 CorruptDatabase(kDBDir
, leveldb::kLogFile
, -1, 1);
242 database
.reset(new SandboxOriginDatabase(kFSDir
, NULL
));
243 std::vector
<SandboxOriginDatabase::OriginRecord
> origins_in_db
;
244 EXPECT_TRUE(database
->ListAllOrigins(&origins_in_db
));
246 // Expect all but last added origin will be repaired back, and kOrigins[1]
247 // should be dropped due to absence of backing directory.
248 EXPECT_EQ(arraysize(kOrigins
) - 2, origins_in_db
.size());
250 const std::string
kOrigin("piyo.example.org");
251 EXPECT_FALSE(database
->HasOriginPath(kOrigin
));
252 EXPECT_TRUE(database
->GetPathForOrigin(kOrigin
, &path
));
253 EXPECT_FALSE(path
.empty());
254 EXPECT_TRUE(database
->HasOriginPath(kOrigin
));
256 EXPECT_FALSE(base::PathExists(kGarbageFile
));
257 EXPECT_FALSE(base::PathExists(kGarbageDir
));
260 TEST(SandboxOriginDatabaseTest
, DatabaseRecoveryForMissingDBFileTest
) {
261 const leveldb::FileType kLevelDBFileTypes
[] = {
263 leveldb::kDBLockFile
,
265 leveldb::kDescriptorFile
,
266 leveldb::kCurrentFile
,
268 leveldb::kInfoLogFile
,
271 for (size_t i
= 0; i
< arraysize(kLevelDBFileTypes
); ++i
) {
272 base::ScopedTempDir dir
;
273 ASSERT_TRUE(dir
.CreateUniqueTempDir());
274 const base::FilePath kFSDir
= dir
.path().Append(kFileSystemDirName
);
275 const base::FilePath kDBDir
= kFSDir
.Append(kOriginDatabaseName
);
276 EXPECT_FALSE(base::PathExists(kFSDir
));
277 EXPECT_TRUE(base::CreateDirectory(kFSDir
));
279 const std::string kOrigin
= "foo.example.com";
282 scoped_ptr
<SandboxOriginDatabase
> database(
283 new SandboxOriginDatabase(kFSDir
, NULL
));
284 EXPECT_FALSE(database
->HasOriginPath(kOrigin
));
285 EXPECT_TRUE(database
->GetPathForOrigin(kOrigin
, &path
));
286 EXPECT_FALSE(path
.empty());
287 EXPECT_TRUE(database
->GetPathForOrigin(kOrigin
, &path
));
288 EXPECT_TRUE(base::CreateDirectory(kFSDir
.Append(path
)));
291 DeleteDatabaseFile(kDBDir
, kLevelDBFileTypes
[i
]);
293 database
.reset(new SandboxOriginDatabase(kFSDir
, NULL
));
294 std::vector
<SandboxOriginDatabase::OriginRecord
> origins_in_db
;
295 EXPECT_TRUE(database
->ListAllOrigins(&origins_in_db
));
297 const std::string
kOrigin2("piyo.example.org");
298 EXPECT_FALSE(database
->HasOriginPath(kOrigin2
));
299 EXPECT_TRUE(database
->GetPathForOrigin(kOrigin2
, &path
));
300 EXPECT_FALSE(path
.empty());
301 EXPECT_TRUE(database
->HasOriginPath(kOrigin2
));
305 } // namespace content