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

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

Issue 9663021: Add database recovery for FileSystemOriginDatabase (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: '' Created 8 years, 9 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "testing/gtest/include/gtest/gtest.h" 5 #include "testing/gtest/include/gtest/gtest.h"
6 6
7 #include <algorithm>
7 #include <string> 8 #include <string>
8 9
10 #include "base/file_path.h"
9 #include "base/file_util.h" 11 #include "base/file_util.h"
12 #include "base/platform_file.h"
10 #include "base/scoped_temp_dir.h" 13 #include "base/scoped_temp_dir.h"
14 #include "base/stl_util.h"
15 #include "base/utf_string_conversions.h"
16 #include "third_party/leveldatabase/src/db/filename.h"
17 #include "third_party/leveldatabase/src/include/leveldb/db.h"
11 #include "webkit/fileapi/file_system_origin_database.h" 18 #include "webkit/fileapi/file_system_origin_database.h"
12 19
13 namespace fileapi { 20 namespace fileapi {
14 21
22 namespace {
23 const FilePath::CharType kFileSystemDirName[] =
24 FILE_PATH_LITERAL("File System");
25 const FilePath::CharType kOriginDatabaseName[] = FILE_PATH_LITERAL("Origins");
26
27 std::string FilePathToString(const FilePath& path) {
28 #if defined(OS_POSIX)
29 return path.value();
30 #elif defined(OS_WIN)
31 return UTF16ToUTF8(path.value());
32 #endif
33 }
34
35 FilePath UTF8ToFilePath(const std::string& path_string) {
36 return FilePath::FromUTF8Unsafe(path_string);
37 }
38
39 void CorruptDatabase(const FilePath& db_path,
40 leveldb::FileType type,
41 ptrdiff_t offset,
42 size_t size) {
43 file_util::FileEnumerator file_enum(
44 db_path, false /* recursive */,
45 static_cast<file_util::FileEnumerator::FileType>(
46 file_util::FileEnumerator::DIRECTORIES |
47 file_util::FileEnumerator::FILES));
48 FilePath file_path;
49 FilePath picked_file_path;
50 uint64 picked_file_number = kuint64max;
51
52 while (!(file_path = file_enum.Next()).empty()) {
53 uint64 number = -1;
54 leveldb::FileType file_type;
55 EXPECT_TRUE(leveldb::ParseFileName(FilePathToString(file_path.BaseName()),
56 &number, &file_type));
57 if (file_type == type &&
58 (picked_file_number == kuint64max || picked_file_number < number)) {
59 picked_file_path = file_path;
60 picked_file_number = number;
61 }
62 }
63
64 EXPECT_FALSE(picked_file_path.empty());
65 EXPECT_NE(kuint64max, picked_file_number);
66
67 bool created = true;
68 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
69 base::PlatformFile file =
70 CreatePlatformFile(picked_file_path,
71 base::PLATFORM_FILE_OPEN |
72 base::PLATFORM_FILE_READ |
73 base::PLATFORM_FILE_WRITE,
74 &created, &error);
75 EXPECT_EQ(base::PLATFORM_FILE_OK, error);
76 EXPECT_FALSE(created);
77
78 std::vector<char> buf(size);
79
80 int read_size = base::ReadPlatformFile(file, offset,
81 vector_as_array(&buf), buf.size());
82 EXPECT_LT(0, read_size);
83 EXPECT_GE(buf.size(), static_cast<size_t>(read_size));
84 buf.resize(read_size);
85
86 std::transform(buf.begin(), buf.end(), buf.begin(),
87 std::logical_not<char>());
88
89 int wrote_size = base::WritePlatformFile(file, offset,
kinuko 2012/03/26 05:25:09 nit: written_size ?
tzik 2012/03/26 08:04:56 Done.
90 vector_as_array(&buf), buf.size());
91 EXPECT_LE(0, wrote_size);
92 EXPECT_EQ(buf.size(), static_cast<size_t>(wrote_size));
93
94 base::ClosePlatformFile(file);
95 }
96
97 }
98
15 TEST(FileSystemOriginDatabaseTest, BasicTest) { 99 TEST(FileSystemOriginDatabaseTest, BasicTest) {
16 ScopedTempDir dir; 100 ScopedTempDir dir;
17 ASSERT_TRUE(dir.CreateUniqueTempDir()); 101 ASSERT_TRUE(dir.CreateUniqueTempDir());
18 const FilePath kDBFile = dir.path().AppendASCII("fsod.db"); 102 const FilePath kFSDir = dir.path().Append(kFileSystemDirName);
19 EXPECT_FALSE(file_util::PathExists(kDBFile)); 103 EXPECT_FALSE(file_util::PathExists(kFSDir));
104 EXPECT_TRUE(file_util::CreateDirectory(kFSDir));
20 105
21 FileSystemOriginDatabase database(kDBFile); 106 FileSystemOriginDatabase database(kFSDir);
22 std::string origin("origin"); 107 std::string origin("origin");
23 108
24 EXPECT_FALSE(database.HasOriginPath(origin)); 109 EXPECT_FALSE(database.HasOriginPath(origin));
25 // Double-check to make sure that had no side effects. 110 // Double-check to make sure that had no side effects.
26 EXPECT_FALSE(database.HasOriginPath(origin)); 111 EXPECT_FALSE(database.HasOriginPath(origin));
27 112
28 FilePath path0; 113 FilePath path0;
29 FilePath path1; 114 FilePath path1;
30 115
31 // Empty strings aren't valid origins. 116 // Empty strings aren't valid origins.
32 EXPECT_FALSE(database.GetPathForOrigin(std::string(), &path0)); 117 EXPECT_FALSE(database.GetPathForOrigin(std::string(), &path0));
33 118
34 EXPECT_TRUE(database.GetPathForOrigin(origin, &path0)); 119 EXPECT_TRUE(database.GetPathForOrigin(origin, &path0));
35 EXPECT_TRUE(database.HasOriginPath(origin)); 120 EXPECT_TRUE(database.HasOriginPath(origin));
36 EXPECT_TRUE(database.GetPathForOrigin(origin, &path1)); 121 EXPECT_TRUE(database.GetPathForOrigin(origin, &path1));
37 EXPECT_FALSE(path0.empty()); 122 EXPECT_FALSE(path0.empty());
38 EXPECT_FALSE(path1.empty()); 123 EXPECT_FALSE(path1.empty());
39 EXPECT_EQ(path0, path1); 124 EXPECT_EQ(path0, path1);
40 125
41 EXPECT_TRUE(file_util::PathExists(kDBFile)); 126 EXPECT_TRUE(file_util::PathExists(kFSDir.Append(kOriginDatabaseName)));
42 } 127 }
43 128
44 TEST(FileSystemOriginDatabaseTest, TwoPathTest) { 129 TEST(FileSystemOriginDatabaseTest, TwoPathTest) {
45 ScopedTempDir dir; 130 ScopedTempDir dir;
46 ASSERT_TRUE(dir.CreateUniqueTempDir()); 131 ASSERT_TRUE(dir.CreateUniqueTempDir());
47 const FilePath kDBFile = dir.path().AppendASCII("fsod.db"); 132 const FilePath kFSDir = dir.path().Append(kFileSystemDirName);
48 EXPECT_FALSE(file_util::PathExists(kDBFile)); 133 EXPECT_FALSE(file_util::PathExists(kFSDir));
134 EXPECT_TRUE(file_util::CreateDirectory(kFSDir));
49 135
50 FileSystemOriginDatabase database(kDBFile); 136 FileSystemOriginDatabase database(kFSDir);
51 std::string origin0("origin0"); 137 std::string origin0("origin0");
52 std::string origin1("origin1"); 138 std::string origin1("origin1");
53 139
54 EXPECT_FALSE(database.HasOriginPath(origin0)); 140 EXPECT_FALSE(database.HasOriginPath(origin0));
55 EXPECT_FALSE(database.HasOriginPath(origin1)); 141 EXPECT_FALSE(database.HasOriginPath(origin1));
56 142
57 FilePath path0; 143 FilePath path0;
58 FilePath path1; 144 FilePath path1;
59 EXPECT_TRUE(database.GetPathForOrigin(origin0, &path0)); 145 EXPECT_TRUE(database.GetPathForOrigin(origin0, &path0));
60 EXPECT_TRUE(database.HasOriginPath(origin0)); 146 EXPECT_TRUE(database.HasOriginPath(origin0));
61 EXPECT_FALSE(database.HasOriginPath(origin1)); 147 EXPECT_FALSE(database.HasOriginPath(origin1));
62 EXPECT_TRUE(database.GetPathForOrigin(origin1, &path1)); 148 EXPECT_TRUE(database.GetPathForOrigin(origin1, &path1));
63 EXPECT_TRUE(database.HasOriginPath(origin1)); 149 EXPECT_TRUE(database.HasOriginPath(origin1));
64 EXPECT_FALSE(path0.empty()); 150 EXPECT_FALSE(path0.empty());
65 EXPECT_FALSE(path1.empty()); 151 EXPECT_FALSE(path1.empty());
66 EXPECT_NE(path0, path1); 152 EXPECT_NE(path0, path1);
67 153
68 EXPECT_TRUE(file_util::PathExists(kDBFile)); 154 EXPECT_TRUE(file_util::PathExists(kFSDir.Append(kOriginDatabaseName)));
69 } 155 }
70 156
71 TEST(FileSystemOriginDatabaseTest, DropDatabaseTest) { 157 TEST(FileSystemOriginDatabaseTest, DropDatabaseTest) {
72 ScopedTempDir dir; 158 ScopedTempDir dir;
73 ASSERT_TRUE(dir.CreateUniqueTempDir()); 159 ASSERT_TRUE(dir.CreateUniqueTempDir());
74 const FilePath kDBFile = dir.path().AppendASCII("fsod.db"); 160 const FilePath kFSDir = dir.path().Append(kFileSystemDirName);
75 EXPECT_FALSE(file_util::PathExists(kDBFile)); 161 EXPECT_FALSE(file_util::PathExists(kFSDir));
162 EXPECT_TRUE(file_util::CreateDirectory(kFSDir));
76 163
77 FileSystemOriginDatabase database(kDBFile); 164 FileSystemOriginDatabase database(kFSDir);
78 std::string origin("origin"); 165 std::string origin("origin");
79 166
80 EXPECT_FALSE(database.HasOriginPath(origin)); 167 EXPECT_FALSE(database.HasOriginPath(origin));
81 168
82 FilePath path0; 169 FilePath path0;
83 EXPECT_TRUE(database.GetPathForOrigin(origin, &path0)); 170 EXPECT_TRUE(database.GetPathForOrigin(origin, &path0));
84 EXPECT_TRUE(database.HasOriginPath(origin)); 171 EXPECT_TRUE(database.HasOriginPath(origin));
85 EXPECT_FALSE(path0.empty()); 172 EXPECT_FALSE(path0.empty());
86 173
87 EXPECT_TRUE(file_util::PathExists(kDBFile)); 174 EXPECT_TRUE(file_util::PathExists(kFSDir.Append(kOriginDatabaseName)));
88 175
89 database.DropDatabase(); 176 database.DropDatabase();
90 177
91 FilePath path1; 178 FilePath path1;
92 EXPECT_TRUE(database.HasOriginPath(origin)); 179 EXPECT_TRUE(database.HasOriginPath(origin));
93 EXPECT_TRUE(database.GetPathForOrigin(origin, &path1)); 180 EXPECT_TRUE(database.GetPathForOrigin(origin, &path1));
94 EXPECT_FALSE(path1.empty()); 181 EXPECT_FALSE(path1.empty());
95 EXPECT_EQ(path0, path1); 182 EXPECT_EQ(path0, path1);
96 } 183 }
97 184
98 TEST(FileSystemOriginDatabaseTest, DeleteOriginTest) { 185 TEST(FileSystemOriginDatabaseTest, DeleteOriginTest) {
99 ScopedTempDir dir; 186 ScopedTempDir dir;
100 ASSERT_TRUE(dir.CreateUniqueTempDir()); 187 ASSERT_TRUE(dir.CreateUniqueTempDir());
101 const FilePath kDBFile = dir.path().AppendASCII("fsod.db"); 188 const FilePath kFSDir = dir.path().Append(kFileSystemDirName);
102 EXPECT_FALSE(file_util::PathExists(kDBFile)); 189 EXPECT_FALSE(file_util::PathExists(kFSDir));
190 EXPECT_TRUE(file_util::CreateDirectory(kFSDir));
103 191
104 FileSystemOriginDatabase database(kDBFile); 192 FileSystemOriginDatabase database(kFSDir);
105 std::string origin("origin"); 193 std::string origin("origin");
106 194
107 EXPECT_FALSE(database.HasOriginPath(origin)); 195 EXPECT_FALSE(database.HasOriginPath(origin));
108 EXPECT_TRUE(database.RemovePathForOrigin(origin)); 196 EXPECT_TRUE(database.RemovePathForOrigin(origin));
109 197
110 FilePath path0; 198 FilePath path0;
111 EXPECT_TRUE(database.GetPathForOrigin(origin, &path0)); 199 EXPECT_TRUE(database.GetPathForOrigin(origin, &path0));
112 EXPECT_TRUE(database.HasOriginPath(origin)); 200 EXPECT_TRUE(database.HasOriginPath(origin));
113 EXPECT_FALSE(path0.empty()); 201 EXPECT_FALSE(path0.empty());
114 202
115 EXPECT_TRUE(database.RemovePathForOrigin(origin)); 203 EXPECT_TRUE(database.RemovePathForOrigin(origin));
116 EXPECT_FALSE(database.HasOriginPath(origin)); 204 EXPECT_FALSE(database.HasOriginPath(origin));
117 205
118 FilePath path1; 206 FilePath path1;
119 EXPECT_TRUE(database.GetPathForOrigin(origin, &path1)); 207 EXPECT_TRUE(database.GetPathForOrigin(origin, &path1));
120 EXPECT_FALSE(path1.empty()); 208 EXPECT_FALSE(path1.empty());
121 EXPECT_NE(path0, path1); 209 EXPECT_NE(path0, path1);
122 } 210 }
123 211
124 TEST(FileSystemOriginDatabaseTest, ListOriginsTest) { 212 TEST(FileSystemOriginDatabaseTest, ListOriginsTest) {
125 ScopedTempDir dir; 213 ScopedTempDir dir;
126 ASSERT_TRUE(dir.CreateUniqueTempDir()); 214 ASSERT_TRUE(dir.CreateUniqueTempDir());
127 const FilePath kDBFile = dir.path().AppendASCII("fsod.db"); 215 const FilePath kFSDir = dir.path().Append(kFileSystemDirName);
128 EXPECT_FALSE(file_util::PathExists(kDBFile)); 216 EXPECT_FALSE(file_util::PathExists(kFSDir));
217 EXPECT_TRUE(file_util::CreateDirectory(kFSDir));
129 218
130 std::vector<FileSystemOriginDatabase::OriginRecord> origins; 219 std::vector<FileSystemOriginDatabase::OriginRecord> origins;
131 220
132 FileSystemOriginDatabase database(kDBFile); 221 FileSystemOriginDatabase database(kFSDir);
133 EXPECT_TRUE(database.ListAllOrigins(&origins)); 222 EXPECT_TRUE(database.ListAllOrigins(&origins));
134 EXPECT_TRUE(origins.empty()); 223 EXPECT_TRUE(origins.empty());
135 origins.clear(); 224 origins.clear();
136 225
137 std::string origin0("origin0"); 226 std::string origin0("origin0");
138 std::string origin1("origin1"); 227 std::string origin1("origin1");
139 228
140 EXPECT_FALSE(database.HasOriginPath(origin0)); 229 EXPECT_FALSE(database.HasOriginPath(origin0));
141 EXPECT_FALSE(database.HasOriginPath(origin1)); 230 EXPECT_FALSE(database.HasOriginPath(origin1));
142 231
(...skipping 13 matching lines...) Expand all
156 EXPECT_EQ(origins[1].origin, origin1); 245 EXPECT_EQ(origins[1].origin, origin1);
157 EXPECT_EQ(origins[1].path, path1); 246 EXPECT_EQ(origins[1].path, path1);
158 } else { 247 } else {
159 EXPECT_EQ(origins[0].origin, origin1); 248 EXPECT_EQ(origins[0].origin, origin1);
160 EXPECT_EQ(origins[0].path, path1); 249 EXPECT_EQ(origins[0].path, path1);
161 EXPECT_EQ(origins[1].origin, origin0); 250 EXPECT_EQ(origins[1].origin, origin0);
162 EXPECT_EQ(origins[1].path, path0); 251 EXPECT_EQ(origins[1].path, path0);
163 } 252 }
164 } 253 }
165 254
255 TEST(FileSystemOriginDatabaseTest, DatabaseRecoveryTest) {
kinuko 2012/03/26 05:25:09 Would be worth adding some toplevel comments about
tzik 2012/03/26 08:04:56 Done.
256 ScopedTempDir dir;
257 ASSERT_TRUE(dir.CreateUniqueTempDir());
258 const FilePath kFSDir = dir.path().Append(kFileSystemDirName);
259 const FilePath kDBDir = kFSDir.Append(kOriginDatabaseName);
260 EXPECT_FALSE(file_util::PathExists(kFSDir));
261 EXPECT_TRUE(file_util::CreateDirectory(kFSDir));
262
263 const std::string kOrigins[] = {
264 "foo.example.com",
265 "bar.example.com",
266 "baz.example.com",
267 "hoge.example.com",
268 "fuga.example.com",
269 };
270
271 scoped_ptr<FileSystemOriginDatabase> database(
272 new FileSystemOriginDatabase(kFSDir));
273 for (size_t i = 0; i < arraysize(kOrigins); ++i) {
274 FilePath path;
275 EXPECT_FALSE(database->HasOriginPath(kOrigins[i]));
276 EXPECT_TRUE(database->GetPathForOrigin(kOrigins[i], &path));
277 EXPECT_FALSE(path.empty());
278 EXPECT_TRUE(database->GetPathForOrigin(kOrigins[i], &path));
279
280 if (i != 1)
281 EXPECT_TRUE(file_util::CreateDirectory(kFSDir.Append(path)));
282 }
283 database->RemovePathForOrigin(kOrigins[0]);
284 database.reset();
285
286 const FilePath kGarbageDir = kFSDir.AppendASCII("foo");
287 const FilePath kGarbageFile = kGarbageDir.AppendASCII("bar");
288 EXPECT_TRUE(file_util::CreateDirectory(kGarbageDir));
289 bool created = false;
290 base::PlatformFileError error;
291 base::PlatformFile file = base::CreatePlatformFile(
292 kGarbageFile,
293 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE,
294 &created, &error);
295 EXPECT_EQ(base::PLATFORM_FILE_OK, error);
296 EXPECT_TRUE(created);
297 EXPECT_TRUE(base::ClosePlatformFile(file));
298
299 CorruptDatabase(kDBDir, leveldb::kDescriptorFile, 0, 100);
kinuko 2012/03/26 05:25:09 Could you add some comment about why we specify '0
tzik 2012/03/26 08:04:56 Done. Modified area to corrupt and added comment.
300
301 const std::string kOrigin("piyo.example.org");
kinuko 2012/03/26 05:25:09 Should we move this before line 308?
tzik 2012/03/26 08:04:56 Done.
302 FilePath path;
303 database.reset(new FileSystemOriginDatabase(kFSDir));
304 std::vector<FileSystemOriginDatabase::OriginRecord> origins_in_db;
305 EXPECT_TRUE(database->ListAllOrigins(&origins_in_db));
306 EXPECT_EQ(arraysize(kOrigins) - 2, origins_in_db.size());
kinuko 2012/03/26 05:25:09 Could you add some comment about what this '-2' me
tzik 2012/03/26 08:04:56 Done.
307
308 EXPECT_FALSE(database->HasOriginPath(kOrigin));
309 EXPECT_TRUE(database->GetPathForOrigin(kOrigin, &path));
310 EXPECT_FALSE(path.empty());
311 EXPECT_TRUE(database->HasOriginPath(kOrigin));
312
313 EXPECT_FALSE(file_util::PathExists(kGarbageFile));
314 EXPECT_FALSE(file_util::PathExists(kGarbageDir));
315 }
316
166 } // namespace fileapi 317 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698