Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / fileapi / sandbox_origin_database_unittest.cc
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.
4
5 #include <algorithm>
6 #include <functional>
7 #include <limits>
8 #include <string>
9 #include <vector>
10
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"
22
23 using fileapi::SandboxOriginDatabase;
24
25 namespace content {
26
27 namespace {
28 const base::FilePath::CharType kFileSystemDirName[] =
29     FILE_PATH_LITERAL("File System");
30 const base::FilePath::CharType kOriginDatabaseName[] =
31     FILE_PATH_LITERAL("Origins");
32 }  // namespace
33
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));
40
41   SandboxOriginDatabase database(kFSDir, NULL);
42   std::string origin("origin");
43
44   EXPECT_FALSE(database.HasOriginPath(origin));
45   // Double-check to make sure that had no side effects.
46   EXPECT_FALSE(database.HasOriginPath(origin));
47
48   base::FilePath path0;
49   base::FilePath path1;
50
51   // Empty strings aren't valid origins.
52   EXPECT_FALSE(database.GetPathForOrigin(std::string(), &path0));
53
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);
60
61   EXPECT_TRUE(base::PathExists(kFSDir.Append(kOriginDatabaseName)));
62 }
63
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));
70
71   SandboxOriginDatabase database(kFSDir, NULL);
72   std::string origin0("origin0");
73   std::string origin1("origin1");
74
75   EXPECT_FALSE(database.HasOriginPath(origin0));
76   EXPECT_FALSE(database.HasOriginPath(origin1));
77
78   base::FilePath path0;
79   base::FilePath path1;
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);
88
89   EXPECT_TRUE(base::PathExists(kFSDir.Append(kOriginDatabaseName)));
90 }
91
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));
98
99   SandboxOriginDatabase database(kFSDir, NULL);
100   std::string origin("origin");
101
102   EXPECT_FALSE(database.HasOriginPath(origin));
103
104   base::FilePath path0;
105   EXPECT_TRUE(database.GetPathForOrigin(origin, &path0));
106   EXPECT_TRUE(database.HasOriginPath(origin));
107   EXPECT_FALSE(path0.empty());
108
109   EXPECT_TRUE(base::PathExists(kFSDir.Append(kOriginDatabaseName)));
110
111   database.DropDatabase();
112
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);
118 }
119
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));
126
127   SandboxOriginDatabase database(kFSDir, NULL);
128   std::string origin("origin");
129
130   EXPECT_FALSE(database.HasOriginPath(origin));
131   EXPECT_TRUE(database.RemovePathForOrigin(origin));
132
133   base::FilePath path0;
134   EXPECT_TRUE(database.GetPathForOrigin(origin, &path0));
135   EXPECT_TRUE(database.HasOriginPath(origin));
136   EXPECT_FALSE(path0.empty());
137
138   EXPECT_TRUE(database.RemovePathForOrigin(origin));
139   EXPECT_FALSE(database.HasOriginPath(origin));
140
141   base::FilePath path1;
142   EXPECT_TRUE(database.GetPathForOrigin(origin, &path1));
143   EXPECT_FALSE(path1.empty());
144   EXPECT_NE(path0, path1);
145 }
146
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));
153
154   std::vector<SandboxOriginDatabase::OriginRecord> origins;
155
156   SandboxOriginDatabase database(kFSDir, NULL);
157   EXPECT_TRUE(database.ListAllOrigins(&origins));
158   EXPECT_TRUE(origins.empty());
159   origins.clear();
160
161   std::string origin0("origin0");
162   std::string origin1("origin1");
163
164   EXPECT_FALSE(database.HasOriginPath(origin0));
165   EXPECT_FALSE(database.HasOriginPath(origin1));
166
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);
174   origins.clear();
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);
182   } else {
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);
187   }
188 }
189
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
195   // entries lost.
196
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));
203
204   const std::string kOrigins[] = {
205     "foo.example.com",
206     "bar.example.com",
207     "baz.example.com",
208     "hoge.example.com",
209     "fuga.example.com",
210   };
211
212   scoped_ptr<SandboxOriginDatabase> database(
213       new SandboxOriginDatabase(kFSDir, NULL));
214   for (size_t i = 0; i < arraysize(kOrigins); ++i) {
215     base::FilePath path;
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));
220
221     if (i != 1)
222       EXPECT_TRUE(base::CreateDirectory(kFSDir.Append(path)));
223   }
224   database.reset();
225
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());
232   file.Close();
233
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);
240
241   base::FilePath path;
242   database.reset(new SandboxOriginDatabase(kFSDir, NULL));
243   std::vector<SandboxOriginDatabase::OriginRecord> origins_in_db;
244   EXPECT_TRUE(database->ListAllOrigins(&origins_in_db));
245
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());
249
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));
255
256   EXPECT_FALSE(base::PathExists(kGarbageFile));
257   EXPECT_FALSE(base::PathExists(kGarbageDir));
258 }
259
260 TEST(SandboxOriginDatabaseTest, DatabaseRecoveryForMissingDBFileTest) {
261   const leveldb::FileType kLevelDBFileTypes[] = {
262     leveldb::kLogFile,
263     leveldb::kDBLockFile,
264     leveldb::kTableFile,
265     leveldb::kDescriptorFile,
266     leveldb::kCurrentFile,
267     leveldb::kTempFile,
268     leveldb::kInfoLogFile,
269   };
270
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));
278
279     const std::string kOrigin = "foo.example.com";
280     base::FilePath path;
281
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)));
289     database.reset();
290
291     DeleteDatabaseFile(kDBDir, kLevelDBFileTypes[i]);
292
293     database.reset(new SandboxOriginDatabase(kFSDir, NULL));
294     std::vector<SandboxOriginDatabase::OriginRecord> origins_in_db;
295     EXPECT_TRUE(database->ListAllOrigins(&origins_in_db));
296
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));
302   }
303 }
304
305 }  // namespace content