Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / fileapi / file_system_context_unittest.cc
1 // Copyright 2013 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/file_system_context.h"
6
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/strings/stringprintf.h"
10 #include "content/browser/quota/mock_quota_manager.h"
11 #include "content/public/test/mock_special_storage_policy.h"
12 #include "content/public/test/test_file_system_options.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webkit/browser/fileapi/external_mount_points.h"
15 #include "webkit/browser/fileapi/file_system_backend.h"
16 #include "webkit/browser/fileapi/isolated_context.h"
17
18 #define FPL(x) FILE_PATH_LITERAL(x)
19
20 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
21 #define DRIVE FPL("C:")
22 #else
23 #define DRIVE
24 #endif
25
26 using fileapi::ExternalMountPoints;
27 using fileapi::FileSystemBackend;
28 using fileapi::FileSystemContext;
29 using fileapi::FileSystemMountOption;
30 using fileapi::FileSystemType;
31 using fileapi::FileSystemURL;
32 using fileapi::IsolatedContext;
33
34 namespace content {
35
36 namespace {
37
38 const char kTestOrigin[] = "http://chromium.org/";
39
40 GURL CreateRawFileSystemURL(const std::string& type_str,
41                             const std::string& fs_id) {
42   std::string url_str = base::StringPrintf(
43       "filesystem:http://chromium.org/%s/%s/root/file",
44       type_str.c_str(),
45       fs_id.c_str());
46   return GURL(url_str);
47 }
48
49 class FileSystemContextTest : public testing::Test {
50  public:
51   FileSystemContextTest() {}
52
53   virtual void SetUp() {
54     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
55
56     storage_policy_ = new MockSpecialStoragePolicy();
57
58     mock_quota_manager_ =
59         new MockQuotaManager(false /* is_incognito */,
60                                     data_dir_.path(),
61                                     base::MessageLoopProxy::current().get(),
62                                     base::MessageLoopProxy::current().get(),
63                                     storage_policy_.get());
64   }
65
66  protected:
67   FileSystemContext* CreateFileSystemContextForTest(
68       fileapi::ExternalMountPoints* external_mount_points) {
69     return new FileSystemContext(
70         base::MessageLoopProxy::current().get(),
71         base::MessageLoopProxy::current().get(),
72         external_mount_points,
73         storage_policy_.get(),
74         mock_quota_manager_->proxy(),
75         ScopedVector<FileSystemBackend>(),
76         std::vector<fileapi::URLRequestAutoMountHandler>(),
77         data_dir_.path(),
78         CreateAllowFileAccessOptions());
79   }
80
81   // Verifies a *valid* filesystem url has expected values.
82   void ExpectFileSystemURLMatches(const FileSystemURL& url,
83                                   const GURL& expect_origin,
84                                   FileSystemType expect_mount_type,
85                                   FileSystemType expect_type,
86                                   const base::FilePath& expect_path,
87                                   const base::FilePath& expect_virtual_path,
88                                   const std::string& expect_filesystem_id) {
89     EXPECT_TRUE(url.is_valid());
90
91     EXPECT_EQ(expect_origin, url.origin());
92     EXPECT_EQ(expect_mount_type, url.mount_type());
93     EXPECT_EQ(expect_type, url.type());
94     EXPECT_EQ(expect_path, url.path());
95     EXPECT_EQ(expect_virtual_path, url.virtual_path());
96     EXPECT_EQ(expect_filesystem_id, url.filesystem_id());
97   }
98
99  private:
100   base::ScopedTempDir data_dir_;
101   base::MessageLoop message_loop_;
102   scoped_refptr<quota::SpecialStoragePolicy> storage_policy_;
103   scoped_refptr<MockQuotaManager> mock_quota_manager_;
104 };
105
106 // It is not valid to pass NULL ExternalMountPoints to FileSystemContext on
107 // ChromeOS.
108 #if !defined(OS_CHROMEOS)
109 TEST_F(FileSystemContextTest, NullExternalMountPoints) {
110   scoped_refptr<FileSystemContext> file_system_context(
111       CreateFileSystemContextForTest(NULL));
112
113   // Cracking system external mount and isolated mount points should work.
114   std::string isolated_name = "root";
115   std::string isolated_id =
116       IsolatedContext::GetInstance()->RegisterFileSystemForPath(
117           fileapi::kFileSystemTypeNativeLocal,
118           base::FilePath(DRIVE FPL("/test/isolated/root")),
119           &isolated_name);
120   // Register system external mount point.
121   ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
122       "system",
123       fileapi::kFileSystemTypeNativeLocal,
124       FileSystemMountOption(),
125       base::FilePath(DRIVE FPL("/test/sys/"))));
126
127   FileSystemURL cracked_isolated = file_system_context->CrackURL(
128       CreateRawFileSystemURL("isolated", isolated_id));
129
130   ExpectFileSystemURLMatches(
131       cracked_isolated,
132       GURL(kTestOrigin),
133       fileapi::kFileSystemTypeIsolated,
134       fileapi::kFileSystemTypeNativeLocal,
135       base::FilePath(
136           DRIVE FPL("/test/isolated/root/file")).NormalizePathSeparators(),
137       base::FilePath::FromUTF8Unsafe(isolated_id).Append(FPL("root/file")).
138           NormalizePathSeparators(),
139       isolated_id);
140
141   FileSystemURL cracked_external = file_system_context->CrackURL(
142       CreateRawFileSystemURL("external", "system"));
143
144   ExpectFileSystemURLMatches(
145       cracked_external,
146       GURL(kTestOrigin),
147       fileapi::kFileSystemTypeExternal,
148       fileapi::kFileSystemTypeNativeLocal,
149       base::FilePath(
150           DRIVE FPL("/test/sys/root/file")).NormalizePathSeparators(),
151       base::FilePath(FPL("system/root/file")).NormalizePathSeparators(),
152       "system");
153
154
155   IsolatedContext::GetInstance()->RevokeFileSystem(isolated_id);
156   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("system");
157 }
158 #endif  // !defiend(OS_CHROMEOS)
159
160 TEST_F(FileSystemContextTest, FileSystemContextKeepsMountPointsAlive) {
161   scoped_refptr<ExternalMountPoints> mount_points =
162       ExternalMountPoints::CreateRefCounted();
163
164   // Register system external mount point.
165   ASSERT_TRUE(mount_points->RegisterFileSystem(
166       "system",
167       fileapi::kFileSystemTypeNativeLocal,
168       FileSystemMountOption(),
169       base::FilePath(DRIVE FPL("/test/sys/"))));
170
171   scoped_refptr<FileSystemContext> file_system_context(
172       CreateFileSystemContextForTest(mount_points.get()));
173
174   // Release a MountPoints reference created in the test.
175   mount_points = NULL;
176
177   // FileSystemContext should keep a reference to the |mount_points|, so it
178   // should be able to resolve the URL.
179   FileSystemURL cracked_external = file_system_context->CrackURL(
180       CreateRawFileSystemURL("external", "system"));
181
182   ExpectFileSystemURLMatches(
183       cracked_external,
184       GURL(kTestOrigin),
185       fileapi::kFileSystemTypeExternal,
186       fileapi::kFileSystemTypeNativeLocal,
187       base::FilePath(
188           DRIVE FPL("/test/sys/root/file")).NormalizePathSeparators(),
189       base::FilePath(FPL("system/root/file")).NormalizePathSeparators(),
190       "system");
191
192   // No need to revoke the registered filesystem since |mount_points| lifetime
193   // is bound to this test.
194 }
195
196 TEST_F(FileSystemContextTest, CrackFileSystemURL) {
197   scoped_refptr<ExternalMountPoints> external_mount_points(
198       ExternalMountPoints::CreateRefCounted());
199   scoped_refptr<FileSystemContext> file_system_context(
200       CreateFileSystemContextForTest(external_mount_points.get()));
201
202   // Register an isolated mount point.
203   std::string isolated_file_system_name = "root";
204   const std::string kIsolatedFileSystemID =
205       IsolatedContext::GetInstance()->RegisterFileSystemForPath(
206           fileapi::kFileSystemTypeNativeLocal,
207           base::FilePath(DRIVE FPL("/test/isolated/root")),
208           &isolated_file_system_name);
209   // Register system external mount point.
210   ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
211       "system",
212       fileapi::kFileSystemTypeDrive,
213       FileSystemMountOption(),
214       base::FilePath(DRIVE FPL("/test/sys/"))));
215   ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
216       "ext",
217       fileapi::kFileSystemTypeNativeLocal,
218       FileSystemMountOption(),
219       base::FilePath(DRIVE FPL("/test/ext"))));
220   // Register a system external mount point with the same name/id as the
221   // registered isolated mount point.
222   ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
223       kIsolatedFileSystemID,
224       fileapi::kFileSystemTypeRestrictedNativeLocal,
225       FileSystemMountOption(),
226       base::FilePath(DRIVE FPL("/test/system/isolated"))));
227   // Add a mount points with the same name as a system mount point to
228   // FileSystemContext's external mount points.
229   ASSERT_TRUE(external_mount_points->RegisterFileSystem(
230       "ext",
231        fileapi::kFileSystemTypeNativeLocal,
232        FileSystemMountOption(),
233        base::FilePath(DRIVE FPL("/test/local/ext/"))));
234
235   const GURL kTestOrigin = GURL("http://chromium.org/");
236   const base::FilePath kVirtualPathNoRoot = base::FilePath(FPL("root/file"));
237
238   struct TestCase {
239     // Test case values.
240     std::string root;
241     std::string type_str;
242
243     // Expected test results.
244     bool expect_is_valid;
245     FileSystemType expect_mount_type;
246     FileSystemType expect_type;
247     const base::FilePath::CharType* expect_path;
248     std::string expect_filesystem_id;
249   };
250
251   const TestCase kTestCases[] = {
252       // Following should not be handled by the url crackers:
253       {
254         "pers_mount", "persistent", true /* is_valid */,
255         fileapi::kFileSystemTypePersistent, fileapi::kFileSystemTypePersistent,
256         FPL("pers_mount/root/file"),
257         std::string()  /* filesystem id */
258       },
259       {
260         "temp_mount", "temporary", true /* is_valid */,
261         fileapi::kFileSystemTypeTemporary, fileapi::kFileSystemTypeTemporary,
262         FPL("temp_mount/root/file"),
263         std::string()  /* filesystem id */
264       },
265       // Should be cracked by isolated mount points:
266       {
267         kIsolatedFileSystemID, "isolated", true /* is_valid */,
268         fileapi::kFileSystemTypeIsolated, fileapi::kFileSystemTypeNativeLocal,
269         DRIVE FPL("/test/isolated/root/file"),
270         kIsolatedFileSystemID
271       },
272       // Should be cracked by system mount points:
273       {
274         "system", "external", true /* is_valid */,
275         fileapi::kFileSystemTypeExternal, fileapi::kFileSystemTypeDrive,
276         DRIVE FPL("/test/sys/root/file"),
277         "system"
278       },
279       {
280         kIsolatedFileSystemID, "external", true /* is_valid */,
281         fileapi::kFileSystemTypeExternal,
282         fileapi::kFileSystemTypeRestrictedNativeLocal,
283         DRIVE FPL("/test/system/isolated/root/file"),
284         kIsolatedFileSystemID
285       },
286       // Should be cracked by FileSystemContext's ExternalMountPoints.
287       {
288         "ext", "external", true /* is_valid */,
289         fileapi::kFileSystemTypeExternal, fileapi::kFileSystemTypeNativeLocal,
290         DRIVE FPL("/test/local/ext/root/file"),
291         "ext"
292       },
293       // Test for invalid filesystem url (made invalid by adding invalid
294       // filesystem type).
295       {
296         "sytem", "external", false /* is_valid */,
297         // The rest of values will be ignored.
298         fileapi::kFileSystemTypeUnknown, fileapi::kFileSystemTypeUnknown,
299         FPL(""), std::string()
300       },
301       // Test for URL with non-existing filesystem id.
302       {
303         "invalid", "external", false /* is_valid */,
304         // The rest of values will be ignored.
305         fileapi::kFileSystemTypeUnknown, fileapi::kFileSystemTypeUnknown,
306         FPL(""), std::string()
307       },
308   };
309
310   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
311     const base::FilePath virtual_path =
312         base::FilePath::FromUTF8Unsafe(
313             kTestCases[i].root).Append(kVirtualPathNoRoot);
314
315     GURL raw_url =
316         CreateRawFileSystemURL(kTestCases[i].type_str, kTestCases[i].root);
317     FileSystemURL cracked_url = file_system_context->CrackURL(raw_url);
318
319     SCOPED_TRACE(testing::Message() << "Test case " << i << ": "
320                                     << "Cracking URL: " << raw_url);
321
322     EXPECT_EQ(kTestCases[i].expect_is_valid, cracked_url.is_valid());
323     if (!kTestCases[i].expect_is_valid)
324       continue;
325
326     ExpectFileSystemURLMatches(
327         cracked_url,
328         GURL(kTestOrigin),
329         kTestCases[i].expect_mount_type,
330         kTestCases[i].expect_type,
331         base::FilePath(kTestCases[i].expect_path).NormalizePathSeparators(),
332         virtual_path.NormalizePathSeparators(),
333         kTestCases[i].expect_filesystem_id);
334   }
335
336   IsolatedContext::GetInstance()->RevokeFileSystemByPath(
337       base::FilePath(DRIVE FPL("/test/isolated/root")));
338   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("system");
339   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("ext");
340   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
341       kIsolatedFileSystemID);
342 }
343
344 TEST_F(FileSystemContextTest, CanServeURLRequest) {
345   scoped_refptr<ExternalMountPoints> external_mount_points(
346       ExternalMountPoints::CreateRefCounted());
347   scoped_refptr<FileSystemContext> context(
348       CreateFileSystemContextForTest(external_mount_points.get()));
349
350   // A request for a sandbox mount point should be served.
351   FileSystemURL cracked_url =
352       context->CrackURL(CreateRawFileSystemURL("persistent", "pers_mount"));
353   EXPECT_EQ(fileapi::kFileSystemTypePersistent, cracked_url.mount_type());
354   EXPECT_TRUE(context->CanServeURLRequest(cracked_url));
355
356   // A request for an isolated mount point should NOT be served.
357   std::string isolated_fs_name = "root";
358   std::string isolated_fs_id =
359       IsolatedContext::GetInstance()->RegisterFileSystemForPath(
360           fileapi::kFileSystemTypeNativeLocal,
361           base::FilePath(DRIVE FPL("/test/isolated/root")),
362           &isolated_fs_name);
363   cracked_url = context->CrackURL(
364       CreateRawFileSystemURL("isolated", isolated_fs_id));
365   EXPECT_EQ(fileapi::kFileSystemTypeIsolated, cracked_url.mount_type());
366   EXPECT_FALSE(context->CanServeURLRequest(cracked_url));
367
368   // A request for an external mount point should be served.
369   const std::string kExternalMountName = "ext_mount";
370   ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
371       kExternalMountName, fileapi::kFileSystemTypeDrive,
372       FileSystemMountOption(),
373       base::FilePath()));
374   cracked_url = context->CrackURL(
375       CreateRawFileSystemURL("external", kExternalMountName));
376   EXPECT_EQ(fileapi::kFileSystemTypeExternal, cracked_url.mount_type());
377   EXPECT_TRUE(context->CanServeURLRequest(cracked_url));
378
379   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
380       kExternalMountName);
381   IsolatedContext::GetInstance()->RevokeFileSystem(isolated_fs_id);
382 }
383
384 }  // namespace
385
386 }  // namespace content