OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "webkit/browser/fileapi/sandbox_directory_database.h" | |
6 | |
7 #include <math.h> | |
8 #include <limits> | |
9 | |
10 #include "base/file_util.h" | |
11 #include "base/files/file.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 "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" | |
20 | |
21 #define FPL(x) FILE_PATH_LITERAL(x) | |
22 | |
23 namespace fileapi { | |
24 | |
25 namespace { | |
26 const base::FilePath::CharType kDirectoryDatabaseName[] = FPL("Paths"); | |
27 } | |
28 | |
29 class SandboxDirectoryDatabaseTest : public testing::Test { | |
30 public: | |
31 typedef SandboxDirectoryDatabase::FileId FileId; | |
32 typedef SandboxDirectoryDatabase::FileInfo FileInfo; | |
33 | |
34 SandboxDirectoryDatabaseTest() { | |
35 EXPECT_TRUE(base_.CreateUniqueTempDir()); | |
36 InitDatabase(); | |
37 } | |
38 | |
39 SandboxDirectoryDatabase* db() { | |
40 return db_.get(); | |
41 } | |
42 | |
43 void InitDatabase() { | |
44 // Call CloseDatabase() to avoid having multiple database instances for | |
45 // single directory at once. | |
46 CloseDatabase(); | |
47 db_.reset(new SandboxDirectoryDatabase(path(), NULL)); | |
48 } | |
49 | |
50 void CloseDatabase() { | |
51 db_.reset(); | |
52 } | |
53 | |
54 base::File::Error AddFileInfo( | |
55 FileId parent_id, const base::FilePath::StringType& name) { | |
56 FileId file_id; | |
57 FileInfo info; | |
58 info.parent_id = parent_id; | |
59 info.name = name; | |
60 return db_->AddFileInfo(info, &file_id); | |
61 } | |
62 | |
63 void CreateDirectory(FileId parent_id, | |
64 const base::FilePath::StringType& name, | |
65 FileId* file_id_out) { | |
66 FileInfo info; | |
67 info.parent_id = parent_id; | |
68 info.name = name; | |
69 ASSERT_EQ(base::File::FILE_OK, db_->AddFileInfo(info, file_id_out)); | |
70 } | |
71 | |
72 void CreateFile(FileId parent_id, | |
73 const base::FilePath::StringType& name, | |
74 const base::FilePath::StringType& data_path, | |
75 FileId* file_id_out) { | |
76 FileId file_id; | |
77 | |
78 FileInfo info; | |
79 info.parent_id = parent_id; | |
80 info.name = name; | |
81 info.data_path = base::FilePath(data_path).NormalizePathSeparators(); | |
82 ASSERT_EQ(base::File::FILE_OK, db_->AddFileInfo(info, &file_id)); | |
83 | |
84 base::FilePath local_path = path().Append(data_path); | |
85 if (!base::DirectoryExists(local_path.DirName())) | |
86 ASSERT_TRUE(base::CreateDirectory(local_path.DirName())); | |
87 | |
88 base::File file(local_path, | |
89 base::File::FLAG_CREATE | base::File::FLAG_WRITE); | |
90 ASSERT_TRUE(file.IsValid()); | |
91 ASSERT_TRUE(file.created()); | |
92 | |
93 if (file_id_out) | |
94 *file_id_out = file_id; | |
95 } | |
96 | |
97 void ClearDatabaseAndDirectory() { | |
98 db_.reset(); | |
99 ASSERT_TRUE(base::DeleteFile(path(), true /* recursive */)); | |
100 ASSERT_TRUE(base::CreateDirectory(path())); | |
101 db_.reset(new SandboxDirectoryDatabase(path(), NULL)); | |
102 } | |
103 | |
104 bool RepairDatabase() { | |
105 return db()->RepairDatabase( | |
106 FilePathToString(path().Append(kDirectoryDatabaseName))); | |
107 } | |
108 | |
109 const base::FilePath& path() { | |
110 return base_.path(); | |
111 } | |
112 | |
113 // Makes link from |parent_id| to |child_id| with |name|. | |
114 void MakeHierarchyLink(FileId parent_id, | |
115 FileId child_id, | |
116 const base::FilePath::StringType& name) { | |
117 ASSERT_TRUE(db()->db_->Put( | |
118 leveldb::WriteOptions(), | |
119 "CHILD_OF:" + base::Int64ToString(parent_id) + ":" + | |
120 FilePathToString(base::FilePath(name)), | |
121 base::Int64ToString(child_id)).ok()); | |
122 } | |
123 | |
124 // Deletes link from parent of |file_id| to |file_id|. | |
125 void DeleteHierarchyLink(FileId file_id) { | |
126 FileInfo file_info; | |
127 ASSERT_TRUE(db()->GetFileInfo(file_id, &file_info)); | |
128 ASSERT_TRUE(db()->db_->Delete( | |
129 leveldb::WriteOptions(), | |
130 "CHILD_OF:" + base::Int64ToString(file_info.parent_id) + ":" + | |
131 FilePathToString(base::FilePath(file_info.name))).ok()); | |
132 } | |
133 | |
134 protected: | |
135 // Common temp base for nondestructive uses. | |
136 base::ScopedTempDir base_; | |
137 scoped_ptr<SandboxDirectoryDatabase> db_; | |
138 | |
139 private: | |
140 DISALLOW_COPY_AND_ASSIGN(SandboxDirectoryDatabaseTest); | |
141 }; | |
142 | |
143 TEST_F(SandboxDirectoryDatabaseTest, TestMissingFileGetInfo) { | |
144 FileId file_id = 888; | |
145 FileInfo info; | |
146 EXPECT_FALSE(db()->GetFileInfo(file_id, &info)); | |
147 } | |
148 | |
149 TEST_F(SandboxDirectoryDatabaseTest, TestGetRootFileInfoBeforeCreate) { | |
150 FileId file_id = 0; | |
151 FileInfo info; | |
152 EXPECT_TRUE(db()->GetFileInfo(file_id, &info)); | |
153 EXPECT_EQ(0, info.parent_id); | |
154 EXPECT_TRUE(info.name.empty()); | |
155 EXPECT_TRUE(info.data_path.empty()); | |
156 } | |
157 | |
158 TEST_F(SandboxDirectoryDatabaseTest, TestMissingParentAddFileInfo) { | |
159 FileId parent_id = 7; | |
160 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY, | |
161 AddFileInfo(parent_id, FILE_PATH_LITERAL("foo"))); | |
162 } | |
163 | |
164 TEST_F(SandboxDirectoryDatabaseTest, TestAddNameClash) { | |
165 FileInfo info; | |
166 FileId file_id; | |
167 info.parent_id = 0; | |
168 info.name = FILE_PATH_LITERAL("dir 0"); | |
169 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id)); | |
170 | |
171 // Check for name clash in the root directory. | |
172 base::FilePath::StringType name = info.name; | |
173 EXPECT_EQ(base::File::FILE_ERROR_EXISTS, AddFileInfo(0, name)); | |
174 name = FILE_PATH_LITERAL("dir 1"); | |
175 EXPECT_EQ(base::File::FILE_OK, AddFileInfo(0, name)); | |
176 | |
177 name = FILE_PATH_LITERAL("subdir 0"); | |
178 EXPECT_EQ(base::File::FILE_OK, AddFileInfo(file_id, name)); | |
179 | |
180 // Check for name clash in a subdirectory. | |
181 EXPECT_EQ(base::File::FILE_ERROR_EXISTS, AddFileInfo(file_id, name)); | |
182 name = FILE_PATH_LITERAL("subdir 1"); | |
183 EXPECT_EQ(base::File::FILE_OK, AddFileInfo(file_id, name)); | |
184 } | |
185 | |
186 TEST_F(SandboxDirectoryDatabaseTest, TestRenameNoMoveNameClash) { | |
187 FileInfo info; | |
188 FileId file_id0; | |
189 base::FilePath::StringType name0 = FILE_PATH_LITERAL("foo"); | |
190 base::FilePath::StringType name1 = FILE_PATH_LITERAL("bar"); | |
191 base::FilePath::StringType name2 = FILE_PATH_LITERAL("bas"); | |
192 info.parent_id = 0; | |
193 info.name = name0; | |
194 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0)); | |
195 EXPECT_EQ(base::File::FILE_OK, AddFileInfo(0, name1)); | |
196 info.name = name1; | |
197 EXPECT_FALSE(db()->UpdateFileInfo(file_id0, info)); | |
198 info.name = name2; | |
199 EXPECT_TRUE(db()->UpdateFileInfo(file_id0, info)); | |
200 } | |
201 | |
202 TEST_F(SandboxDirectoryDatabaseTest, TestMoveSameNameNameClash) { | |
203 FileInfo info; | |
204 FileId file_id0; | |
205 FileId file_id1; | |
206 base::FilePath::StringType name0 = FILE_PATH_LITERAL("foo"); | |
207 base::FilePath::StringType name1 = FILE_PATH_LITERAL("bar"); | |
208 info.parent_id = 0; | |
209 info.name = name0; | |
210 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0)); | |
211 info.parent_id = file_id0; | |
212 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1)); | |
213 info.parent_id = 0; | |
214 EXPECT_FALSE(db()->UpdateFileInfo(file_id1, info)); | |
215 info.name = name1; | |
216 EXPECT_TRUE(db()->UpdateFileInfo(file_id1, info)); | |
217 } | |
218 | |
219 TEST_F(SandboxDirectoryDatabaseTest, TestMoveRenameNameClash) { | |
220 FileInfo info; | |
221 FileId file_id0; | |
222 FileId file_id1; | |
223 base::FilePath::StringType name0 = FILE_PATH_LITERAL("foo"); | |
224 base::FilePath::StringType name1 = FILE_PATH_LITERAL("bar"); | |
225 base::FilePath::StringType name2 = FILE_PATH_LITERAL("bas"); | |
226 info.parent_id = 0; | |
227 info.name = name0; | |
228 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0)); | |
229 info.parent_id = file_id0; | |
230 info.name = name1; | |
231 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1)); | |
232 info.parent_id = 0; | |
233 info.name = name0; | |
234 EXPECT_FALSE(db()->UpdateFileInfo(file_id1, info)); | |
235 info.name = name1; | |
236 EXPECT_TRUE(db()->UpdateFileInfo(file_id1, info)); | |
237 // Also test a successful move+rename. | |
238 info.parent_id = file_id0; | |
239 info.name = name2; | |
240 EXPECT_TRUE(db()->UpdateFileInfo(file_id1, info)); | |
241 } | |
242 | |
243 TEST_F(SandboxDirectoryDatabaseTest, TestRemoveWithChildren) { | |
244 FileInfo info; | |
245 FileId file_id0; | |
246 FileId file_id1; | |
247 info.parent_id = 0; | |
248 info.name = FILE_PATH_LITERAL("foo"); | |
249 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0)); | |
250 info.parent_id = file_id0; | |
251 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1)); | |
252 EXPECT_FALSE(db()->RemoveFileInfo(file_id0)); | |
253 EXPECT_TRUE(db()->RemoveFileInfo(file_id1)); | |
254 EXPECT_TRUE(db()->RemoveFileInfo(file_id0)); | |
255 } | |
256 | |
257 TEST_F(SandboxDirectoryDatabaseTest, TestGetChildWithName) { | |
258 FileInfo info; | |
259 FileId file_id0; | |
260 FileId file_id1; | |
261 base::FilePath::StringType name0 = FILE_PATH_LITERAL("foo"); | |
262 base::FilePath::StringType name1 = FILE_PATH_LITERAL("bar"); | |
263 info.parent_id = 0; | |
264 info.name = name0; | |
265 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0)); | |
266 info.parent_id = file_id0; | |
267 info.name = name1; | |
268 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1)); | |
269 EXPECT_NE(file_id0, file_id1); | |
270 | |
271 FileId check_file_id; | |
272 EXPECT_FALSE(db()->GetChildWithName(0, name1, &check_file_id)); | |
273 EXPECT_TRUE(db()->GetChildWithName(0, name0, &check_file_id)); | |
274 EXPECT_EQ(file_id0, check_file_id); | |
275 EXPECT_FALSE(db()->GetChildWithName(file_id0, name0, &check_file_id)); | |
276 EXPECT_TRUE(db()->GetChildWithName(file_id0, name1, &check_file_id)); | |
277 EXPECT_EQ(file_id1, check_file_id); | |
278 } | |
279 | |
280 TEST_F(SandboxDirectoryDatabaseTest, TestGetFileWithPath) { | |
281 FileInfo info; | |
282 FileId file_id0; | |
283 FileId file_id1; | |
284 FileId file_id2; | |
285 base::FilePath::StringType name0 = FILE_PATH_LITERAL("foo"); | |
286 base::FilePath::StringType name1 = FILE_PATH_LITERAL("bar"); | |
287 base::FilePath::StringType name2 = FILE_PATH_LITERAL("dog"); | |
288 | |
289 info.parent_id = 0; | |
290 info.name = name0; | |
291 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0)); | |
292 info.parent_id = file_id0; | |
293 info.name = name1; | |
294 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1)); | |
295 EXPECT_NE(file_id0, file_id1); | |
296 info.parent_id = file_id1; | |
297 info.name = name2; | |
298 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id2)); | |
299 EXPECT_NE(file_id0, file_id2); | |
300 EXPECT_NE(file_id1, file_id2); | |
301 | |
302 FileId check_file_id; | |
303 base::FilePath path = base::FilePath(name0); | |
304 EXPECT_TRUE(db()->GetFileWithPath(path, &check_file_id)); | |
305 EXPECT_EQ(file_id0, check_file_id); | |
306 | |
307 path = path.Append(name1); | |
308 EXPECT_TRUE(db()->GetFileWithPath(path, &check_file_id)); | |
309 EXPECT_EQ(file_id1, check_file_id); | |
310 | |
311 path = path.Append(name2); | |
312 EXPECT_TRUE(db()->GetFileWithPath(path, &check_file_id)); | |
313 EXPECT_EQ(file_id2, check_file_id); | |
314 } | |
315 | |
316 TEST_F(SandboxDirectoryDatabaseTest, TestListChildren) { | |
317 // No children in the root. | |
318 std::vector<FileId> children; | |
319 EXPECT_TRUE(db()->ListChildren(0, &children)); | |
320 EXPECT_TRUE(children.empty()); | |
321 | |
322 // One child in the root. | |
323 FileId file_id0; | |
324 FileInfo info; | |
325 info.parent_id = 0; | |
326 info.name = FILE_PATH_LITERAL("foo"); | |
327 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id0)); | |
328 EXPECT_TRUE(db()->ListChildren(0, &children)); | |
329 EXPECT_EQ(children.size(), 1UL); | |
330 EXPECT_EQ(children[0], file_id0); | |
331 | |
332 // Two children in the root. | |
333 FileId file_id1; | |
334 info.name = FILE_PATH_LITERAL("bar"); | |
335 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id1)); | |
336 EXPECT_TRUE(db()->ListChildren(0, &children)); | |
337 EXPECT_EQ(2UL, children.size()); | |
338 if (children[0] == file_id0) { | |
339 EXPECT_EQ(children[1], file_id1); | |
340 } else { | |
341 EXPECT_EQ(children[1], file_id0); | |
342 EXPECT_EQ(children[0], file_id1); | |
343 } | |
344 | |
345 // No children in a subdirectory. | |
346 EXPECT_TRUE(db()->ListChildren(file_id0, &children)); | |
347 EXPECT_TRUE(children.empty()); | |
348 | |
349 // One child in a subdirectory. | |
350 info.parent_id = file_id0; | |
351 info.name = FILE_PATH_LITERAL("foo"); | |
352 FileId file_id2; | |
353 FileId file_id3; | |
354 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id2)); | |
355 EXPECT_TRUE(db()->ListChildren(file_id0, &children)); | |
356 EXPECT_EQ(1UL, children.size()); | |
357 EXPECT_EQ(children[0], file_id2); | |
358 | |
359 // Two children in a subdirectory. | |
360 info.name = FILE_PATH_LITERAL("bar"); | |
361 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info, &file_id3)); | |
362 EXPECT_TRUE(db()->ListChildren(file_id0, &children)); | |
363 EXPECT_EQ(2UL, children.size()); | |
364 if (children[0] == file_id2) { | |
365 EXPECT_EQ(children[1], file_id3); | |
366 } else { | |
367 EXPECT_EQ(children[1], file_id2); | |
368 EXPECT_EQ(children[0], file_id3); | |
369 } | |
370 } | |
371 | |
372 TEST_F(SandboxDirectoryDatabaseTest, TestUpdateModificationTime) { | |
373 FileInfo info0; | |
374 FileId file_id; | |
375 info0.parent_id = 0; | |
376 info0.name = FILE_PATH_LITERAL("name"); | |
377 info0.data_path = base::FilePath(FILE_PATH_LITERAL("fake path")); | |
378 info0.modification_time = base::Time::Now(); | |
379 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info0, &file_id)); | |
380 FileInfo info1; | |
381 EXPECT_TRUE(db()->GetFileInfo(file_id, &info1)); | |
382 EXPECT_EQ(info0.name, info1.name); | |
383 EXPECT_EQ(info0.parent_id, info1.parent_id); | |
384 EXPECT_EQ(info0.data_path, info1.data_path); | |
385 EXPECT_EQ( | |
386 floor(info0.modification_time.ToDoubleT()), | |
387 info1.modification_time.ToDoubleT()); | |
388 | |
389 EXPECT_TRUE(db()->UpdateModificationTime(file_id, base::Time::UnixEpoch())); | |
390 EXPECT_TRUE(db()->GetFileInfo(file_id, &info1)); | |
391 EXPECT_EQ(info0.name, info1.name); | |
392 EXPECT_EQ(info0.parent_id, info1.parent_id); | |
393 EXPECT_EQ(info0.data_path, info1.data_path); | |
394 EXPECT_NE(info0.modification_time, info1.modification_time); | |
395 EXPECT_EQ( | |
396 info1.modification_time.ToDoubleT(), | |
397 floor(base::Time::UnixEpoch().ToDoubleT())); | |
398 | |
399 EXPECT_FALSE(db()->UpdateModificationTime(999, base::Time::UnixEpoch())); | |
400 } | |
401 | |
402 TEST_F(SandboxDirectoryDatabaseTest, TestSimpleFileOperations) { | |
403 FileId file_id = 888; | |
404 FileInfo info0; | |
405 EXPECT_FALSE(db()->GetFileInfo(file_id, &info0)); | |
406 info0.parent_id = 0; | |
407 info0.data_path = base::FilePath(FILE_PATH_LITERAL("foo")); | |
408 info0.name = FILE_PATH_LITERAL("file name"); | |
409 info0.modification_time = base::Time::Now(); | |
410 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info0, &file_id)); | |
411 FileInfo info1; | |
412 EXPECT_TRUE(db()->GetFileInfo(file_id, &info1)); | |
413 EXPECT_EQ(info0.parent_id, info1.parent_id); | |
414 EXPECT_EQ(info0.data_path, info1.data_path); | |
415 EXPECT_EQ(info0.name, info1.name); | |
416 EXPECT_EQ( | |
417 floor(info0.modification_time.ToDoubleT()), | |
418 info1.modification_time.ToDoubleT()); | |
419 } | |
420 | |
421 TEST_F(SandboxDirectoryDatabaseTest, TestOverwritingMoveFileSrcDirectory) { | |
422 FileId directory_id; | |
423 FileInfo info0; | |
424 info0.parent_id = 0; | |
425 info0.name = FILE_PATH_LITERAL("directory"); | |
426 info0.modification_time = base::Time::Now(); | |
427 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info0, &directory_id)); | |
428 | |
429 FileId file_id; | |
430 FileInfo info1; | |
431 info1.parent_id = 0; | |
432 info1.data_path = base::FilePath(FILE_PATH_LITERAL("bar")); | |
433 info1.name = FILE_PATH_LITERAL("file"); | |
434 info1.modification_time = base::Time::UnixEpoch(); | |
435 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info1, &file_id)); | |
436 | |
437 EXPECT_FALSE(db()->OverwritingMoveFile(directory_id, file_id)); | |
438 } | |
439 | |
440 TEST_F(SandboxDirectoryDatabaseTest, TestOverwritingMoveFileDestDirectory) { | |
441 FileId file_id; | |
442 FileInfo info0; | |
443 info0.parent_id = 0; | |
444 info0.name = FILE_PATH_LITERAL("file"); | |
445 info0.data_path = base::FilePath(FILE_PATH_LITERAL("bar")); | |
446 info0.modification_time = base::Time::Now(); | |
447 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info0, &file_id)); | |
448 | |
449 FileId directory_id; | |
450 FileInfo info1; | |
451 info1.parent_id = 0; | |
452 info1.name = FILE_PATH_LITERAL("directory"); | |
453 info1.modification_time = base::Time::UnixEpoch(); | |
454 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info1, &directory_id)); | |
455 | |
456 EXPECT_FALSE(db()->OverwritingMoveFile(file_id, directory_id)); | |
457 } | |
458 | |
459 TEST_F(SandboxDirectoryDatabaseTest, TestOverwritingMoveFileSuccess) { | |
460 FileId file_id0; | |
461 FileInfo info0; | |
462 info0.parent_id = 0; | |
463 info0.data_path = base::FilePath(FILE_PATH_LITERAL("foo")); | |
464 info0.name = FILE_PATH_LITERAL("file name 0"); | |
465 info0.modification_time = base::Time::Now(); | |
466 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info0, &file_id0)); | |
467 | |
468 FileInfo dir_info; | |
469 FileId dir_id; | |
470 dir_info.parent_id = 0; | |
471 dir_info.name = FILE_PATH_LITERAL("directory name"); | |
472 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(dir_info, &dir_id)); | |
473 | |
474 FileId file_id1; | |
475 FileInfo info1; | |
476 info1.parent_id = dir_id; | |
477 info1.data_path = base::FilePath(FILE_PATH_LITERAL("bar")); | |
478 info1.name = FILE_PATH_LITERAL("file name 1"); | |
479 info1.modification_time = base::Time::UnixEpoch(); | |
480 EXPECT_EQ(base::File::FILE_OK, db()->AddFileInfo(info1, &file_id1)); | |
481 | |
482 EXPECT_TRUE(db()->OverwritingMoveFile(file_id0, file_id1)); | |
483 | |
484 FileInfo check_info; | |
485 FileId check_id; | |
486 | |
487 EXPECT_FALSE(db()->GetFileWithPath(base::FilePath(info0.name), &check_id)); | |
488 EXPECT_TRUE(db()->GetFileWithPath( | |
489 base::FilePath(dir_info.name).Append(info1.name), &check_id)); | |
490 EXPECT_TRUE(db()->GetFileInfo(check_id, &check_info)); | |
491 | |
492 EXPECT_EQ(info0.data_path, check_info.data_path); | |
493 } | |
494 | |
495 TEST_F(SandboxDirectoryDatabaseTest, TestGetNextInteger) { | |
496 int64 next = -1; | |
497 EXPECT_TRUE(db()->GetNextInteger(&next)); | |
498 EXPECT_EQ(0, next); | |
499 EXPECT_TRUE(db()->GetNextInteger(&next)); | |
500 EXPECT_EQ(1, next); | |
501 InitDatabase(); | |
502 EXPECT_TRUE(db()->GetNextInteger(&next)); | |
503 EXPECT_EQ(2, next); | |
504 EXPECT_TRUE(db()->GetNextInteger(&next)); | |
505 EXPECT_EQ(3, next); | |
506 InitDatabase(); | |
507 EXPECT_TRUE(db()->GetNextInteger(&next)); | |
508 EXPECT_EQ(4, next); | |
509 } | |
510 | |
511 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_Empty) { | |
512 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
513 | |
514 int64 next = -1; | |
515 EXPECT_TRUE(db()->GetNextInteger(&next)); | |
516 EXPECT_EQ(0, next); | |
517 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
518 } | |
519 | |
520 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_Consistent) { | |
521 FileId dir_id; | |
522 CreateFile(0, FPL("foo"), FPL("hoge"), NULL); | |
523 CreateDirectory(0, FPL("bar"), &dir_id); | |
524 CreateFile(dir_id, FPL("baz"), FPL("fuga"), NULL); | |
525 CreateFile(dir_id, FPL("fizz"), FPL("buzz"), NULL); | |
526 | |
527 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
528 } | |
529 | |
530 TEST_F(SandboxDirectoryDatabaseTest, | |
531 TestConsistencyCheck_BackingMultiEntry) { | |
532 const base::FilePath::CharType kBackingFileName[] = FPL("the celeb"); | |
533 CreateFile(0, FPL("foo"), kBackingFileName, NULL); | |
534 | |
535 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
536 ASSERT_TRUE(base::DeleteFile(path().Append(kBackingFileName), false)); | |
537 CreateFile(0, FPL("bar"), kBackingFileName, NULL); | |
538 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
539 } | |
540 | |
541 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_FileLost) { | |
542 const base::FilePath::CharType kBackingFileName[] = FPL("hoge"); | |
543 CreateFile(0, FPL("foo"), kBackingFileName, NULL); | |
544 | |
545 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
546 ASSERT_TRUE(base::DeleteFile(path().Append(kBackingFileName), false)); | |
547 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
548 } | |
549 | |
550 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_OrphanFile) { | |
551 CreateFile(0, FPL("foo"), FPL("hoge"), NULL); | |
552 | |
553 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
554 | |
555 base::File file(path().Append(FPL("Orphan File")), | |
556 base::File::FLAG_CREATE | base::File::FLAG_WRITE); | |
557 ASSERT_TRUE(file.IsValid()); | |
558 ASSERT_TRUE(file.created()); | |
559 file.Close(); | |
560 | |
561 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
562 } | |
563 | |
564 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_RootLoop) { | |
565 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
566 MakeHierarchyLink(0, 0, base::FilePath::StringType()); | |
567 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
568 } | |
569 | |
570 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_DirectoryLoop) { | |
571 FileId dir1_id; | |
572 FileId dir2_id; | |
573 base::FilePath::StringType dir1_name = FPL("foo"); | |
574 CreateDirectory(0, dir1_name, &dir1_id); | |
575 CreateDirectory(dir1_id, FPL("bar"), &dir2_id); | |
576 | |
577 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
578 MakeHierarchyLink(dir2_id, dir1_id, dir1_name); | |
579 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
580 } | |
581 | |
582 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_NameMismatch) { | |
583 FileId dir_id; | |
584 FileId file_id; | |
585 CreateDirectory(0, FPL("foo"), &dir_id); | |
586 CreateFile(dir_id, FPL("bar"), FPL("hoge/fuga/piyo"), &file_id); | |
587 | |
588 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
589 DeleteHierarchyLink(file_id); | |
590 MakeHierarchyLink(dir_id, file_id, FPL("baz")); | |
591 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
592 } | |
593 | |
594 TEST_F(SandboxDirectoryDatabaseTest, TestConsistencyCheck_WreckedEntries) { | |
595 FileId dir1_id; | |
596 FileId dir2_id; | |
597 CreateDirectory(0, FPL("foo"), &dir1_id); | |
598 CreateDirectory(dir1_id, FPL("bar"), &dir2_id); | |
599 CreateFile(dir2_id, FPL("baz"), FPL("fizz/buzz"), NULL); | |
600 | |
601 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
602 DeleteHierarchyLink(dir2_id); // Delete link from |dir1_id| to |dir2_id|. | |
603 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
604 } | |
605 | |
606 TEST_F(SandboxDirectoryDatabaseTest, TestRepairDatabase_Success) { | |
607 base::FilePath::StringType kFileName = FPL("bar"); | |
608 | |
609 FileId file_id_prev; | |
610 CreateFile(0, FPL("foo"), FPL("hoge"), NULL); | |
611 CreateFile(0, kFileName, FPL("fuga"), &file_id_prev); | |
612 | |
613 const base::FilePath kDatabaseDirectory = | |
614 path().Append(kDirectoryDatabaseName); | |
615 CloseDatabase(); | |
616 CorruptDatabase(kDatabaseDirectory, leveldb::kDescriptorFile, | |
617 0, std::numeric_limits<size_t>::max()); | |
618 InitDatabase(); | |
619 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
620 | |
621 FileId file_id; | |
622 EXPECT_TRUE(db()->GetChildWithName(0, kFileName, &file_id)); | |
623 EXPECT_EQ(file_id_prev, file_id); | |
624 | |
625 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
626 } | |
627 | |
628 TEST_F(SandboxDirectoryDatabaseTest, TestRepairDatabase_Failure) { | |
629 base::FilePath::StringType kFileName = FPL("bar"); | |
630 | |
631 CreateFile(0, FPL("foo"), FPL("hoge"), NULL); | |
632 CreateFile(0, kFileName, FPL("fuga"), NULL); | |
633 | |
634 const base::FilePath kDatabaseDirectory = | |
635 path().Append(kDirectoryDatabaseName); | |
636 CloseDatabase(); | |
637 CorruptDatabase(kDatabaseDirectory, leveldb::kDescriptorFile, | |
638 0, std::numeric_limits<size_t>::max()); | |
639 CorruptDatabase(kDatabaseDirectory, leveldb::kLogFile, | |
640 -1, 1); | |
641 InitDatabase(); | |
642 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
643 | |
644 FileId file_id; | |
645 EXPECT_FALSE(db()->GetChildWithName(0, kFileName, &file_id)); | |
646 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
647 } | |
648 | |
649 TEST_F(SandboxDirectoryDatabaseTest, TestRepairDatabase_MissingManifest) { | |
650 base::FilePath::StringType kFileName = FPL("bar"); | |
651 | |
652 FileId file_id_prev; | |
653 CreateFile(0, FPL("foo"), FPL("hoge"), NULL); | |
654 CreateFile(0, kFileName, FPL("fuga"), &file_id_prev); | |
655 | |
656 const base::FilePath kDatabaseDirectory = | |
657 path().Append(kDirectoryDatabaseName); | |
658 CloseDatabase(); | |
659 | |
660 DeleteDatabaseFile(kDatabaseDirectory, leveldb::kDescriptorFile); | |
661 | |
662 InitDatabase(); | |
663 EXPECT_FALSE(db()->IsFileSystemConsistent()); | |
664 | |
665 FileId file_id; | |
666 EXPECT_TRUE(db()->GetChildWithName(0, kFileName, &file_id)); | |
667 EXPECT_EQ(file_id_prev, file_id); | |
668 | |
669 EXPECT_TRUE(db()->IsFileSystemConsistent()); | |
670 } | |
671 | |
672 } // namespace fileapi | |
OLD | NEW |