Upstream version 10.39.225.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 "storage/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 "storage/browser/fileapi/external_mount_points.h"
14 #include "storage/browser/fileapi/file_system_backend.h"
15 #include "storage/browser/fileapi/isolated_context.h"
16 #include "testing/gtest/include/gtest/gtest.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 storage::ExternalMountPoints;
27 using storage::FileSystemBackend;
28 using storage::FileSystemContext;
29 using storage::FileSystemMountOption;
30 using storage::FileSystemURL;
31 using storage::IsolatedContext;
32
33 namespace content {
34
35 namespace {
36
37 const char kTestOrigin[] = "http://chromium.org/";
38
39 GURL CreateRawFileSystemURL(const std::string& type_str,
40                             const std::string& fs_id) {
41   std::string url_str = base::StringPrintf(
42       "filesystem:http://chromium.org/%s/%s/root/file",
43       type_str.c_str(),
44       fs_id.c_str());
45   return GURL(url_str);
46 }
47
48 class FileSystemContextTest : public testing::Test {
49  public:
50   FileSystemContextTest() {}
51
52   virtual void SetUp() {
53     ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
54
55     storage_policy_ = new MockSpecialStoragePolicy();
56
57     mock_quota_manager_ =
58         new MockQuotaManager(false /* is_incognito */,
59                                     data_dir_.path(),
60                                     base::MessageLoopProxy::current().get(),
61                                     base::MessageLoopProxy::current().get(),
62                                     storage_policy_.get());
63   }
64
65  protected:
66   FileSystemContext* CreateFileSystemContextForTest(
67       storage::ExternalMountPoints* external_mount_points) {
68     return new FileSystemContext(
69         base::MessageLoopProxy::current().get(),
70         base::MessageLoopProxy::current().get(),
71         external_mount_points,
72         storage_policy_.get(),
73         mock_quota_manager_->proxy(),
74         ScopedVector<FileSystemBackend>(),
75         std::vector<storage::URLRequestAutoMountHandler>(),
76         data_dir_.path(),
77         CreateAllowFileAccessOptions());
78   }
79
80   // Verifies a *valid* filesystem url has expected values.
81   void ExpectFileSystemURLMatches(const FileSystemURL& url,
82                                   const GURL& expect_origin,
83                                   storage::FileSystemType expect_mount_type,
84                                   storage::FileSystemType expect_type,
85                                   const base::FilePath& expect_path,
86                                   const base::FilePath& expect_virtual_path,
87                                   const std::string& expect_filesystem_id) {
88     EXPECT_TRUE(url.is_valid());
89
90     EXPECT_EQ(expect_origin, url.origin());
91     EXPECT_EQ(expect_mount_type, url.mount_type());
92     EXPECT_EQ(expect_type, url.type());
93     EXPECT_EQ(expect_path, url.path());
94     EXPECT_EQ(expect_virtual_path, url.virtual_path());
95     EXPECT_EQ(expect_filesystem_id, url.filesystem_id());
96   }
97
98  private:
99   base::ScopedTempDir data_dir_;
100   base::MessageLoop message_loop_;
101   scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
102   scoped_refptr<MockQuotaManager> mock_quota_manager_;
103 };
104
105 // It is not valid to pass NULL ExternalMountPoints to FileSystemContext on
106 // ChromeOS.
107 #if !defined(OS_CHROMEOS)
108 TEST_F(FileSystemContextTest, NullExternalMountPoints) {
109   scoped_refptr<FileSystemContext> file_system_context(
110       CreateFileSystemContextForTest(NULL));
111
112   // Cracking system external mount and isolated mount points should work.
113   std::string isolated_name = "root";
114   std::string isolated_id =
115       IsolatedContext::GetInstance()->RegisterFileSystemForPath(
116           storage::kFileSystemTypeNativeLocal,
117           std::string(),
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       storage::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       storage::kFileSystemTypeIsolated,
134       storage::kFileSystemTypeNativeLocal,
135       base::FilePath(DRIVE FPL("/test/isolated/root/file"))
136           .NormalizePathSeparators(),
137       base::FilePath::FromUTF8Unsafe(isolated_id)
138           .Append(FPL("root/file"))
139           .NormalizePathSeparators(),
140       isolated_id);
141
142   FileSystemURL cracked_external = file_system_context->CrackURL(
143       CreateRawFileSystemURL("external", "system"));
144
145   ExpectFileSystemURLMatches(
146       cracked_external,
147       GURL(kTestOrigin),
148       storage::kFileSystemTypeExternal,
149       storage::kFileSystemTypeNativeLocal,
150       base::FilePath(DRIVE FPL("/test/sys/root/file"))
151           .NormalizePathSeparators(),
152       base::FilePath(FPL("system/root/file")).NormalizePathSeparators(),
153       "system");
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       storage::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       storage::kFileSystemTypeExternal,
186       storage::kFileSystemTypeNativeLocal,
187       base::FilePath(DRIVE FPL("/test/sys/root/file"))
188           .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           storage::kFileSystemTypeNativeLocal,
207           std::string(),
208           base::FilePath(DRIVE FPL("/test/isolated/root")),
209           &isolated_file_system_name);
210   // Register system external mount point.
211   ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
212       "system",
213       storage::kFileSystemTypeDrive,
214       FileSystemMountOption(),
215       base::FilePath(DRIVE FPL("/test/sys/"))));
216   ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
217       "ext",
218       storage::kFileSystemTypeNativeLocal,
219       FileSystemMountOption(),
220       base::FilePath(DRIVE FPL("/test/ext"))));
221   // Register a system external mount point with the same name/id as the
222   // registered isolated mount point.
223   ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
224       kIsolatedFileSystemID,
225       storage::kFileSystemTypeRestrictedNativeLocal,
226       FileSystemMountOption(),
227       base::FilePath(DRIVE FPL("/test/system/isolated"))));
228   // Add a mount points with the same name as a system mount point to
229   // FileSystemContext's external mount points.
230   ASSERT_TRUE(external_mount_points->RegisterFileSystem(
231       "ext",
232       storage::kFileSystemTypeNativeLocal,
233       FileSystemMountOption(),
234       base::FilePath(DRIVE FPL("/test/local/ext/"))));
235
236   const GURL kTestOrigin = GURL("http://chromium.org/");
237   const base::FilePath kVirtualPathNoRoot = base::FilePath(FPL("root/file"));
238
239   struct TestCase {
240     // Test case values.
241     std::string root;
242     std::string type_str;
243
244     // Expected test results.
245     bool expect_is_valid;
246     storage::FileSystemType expect_mount_type;
247     storage::FileSystemType expect_type;
248     const base::FilePath::CharType* expect_path;
249     std::string expect_filesystem_id;
250   };
251
252   const TestCase kTestCases[] = {
253       // Following should not be handled by the url crackers:
254       {
255        "pers_mount", "persistent", true /* is_valid */,
256        storage::kFileSystemTypePersistent, storage::kFileSystemTypePersistent,
257        FPL("pers_mount/root/file"), std::string() /* filesystem id */
258       },
259       {
260        "temp_mount", "temporary", true /* is_valid */,
261        storage::kFileSystemTypeTemporary, storage::kFileSystemTypeTemporary,
262        FPL("temp_mount/root/file"), std::string() /* filesystem id */
263       },
264       // Should be cracked by isolated mount points:
265       {kIsolatedFileSystemID, "isolated", true /* is_valid */,
266        storage::kFileSystemTypeIsolated, storage::kFileSystemTypeNativeLocal,
267        DRIVE FPL("/test/isolated/root/file"), kIsolatedFileSystemID},
268       // Should be cracked by system mount points:
269       {"system", "external", true /* is_valid */,
270        storage::kFileSystemTypeExternal, storage::kFileSystemTypeDrive,
271        DRIVE FPL("/test/sys/root/file"), "system"},
272       {kIsolatedFileSystemID, "external", true /* is_valid */,
273        storage::kFileSystemTypeExternal,
274        storage::kFileSystemTypeRestrictedNativeLocal,
275        DRIVE FPL("/test/system/isolated/root/file"), kIsolatedFileSystemID},
276       // Should be cracked by FileSystemContext's ExternalMountPoints.
277       {"ext", "external", true /* is_valid */, storage::kFileSystemTypeExternal,
278        storage::kFileSystemTypeNativeLocal,
279        DRIVE FPL("/test/local/ext/root/file"), "ext"},
280       // Test for invalid filesystem url (made invalid by adding invalid
281       // filesystem type).
282       {"sytem", "external", false /* is_valid */,
283        // The rest of values will be ignored.
284        storage::kFileSystemTypeUnknown, storage::kFileSystemTypeUnknown,
285        FPL(""), std::string()},
286       // Test for URL with non-existing filesystem id.
287       {"invalid", "external", false /* is_valid */,
288        // The rest of values will be ignored.
289        storage::kFileSystemTypeUnknown, storage::kFileSystemTypeUnknown,
290        FPL(""), std::string()},
291   };
292
293   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
294     const base::FilePath virtual_path =
295         base::FilePath::FromUTF8Unsafe(
296             kTestCases[i].root).Append(kVirtualPathNoRoot);
297
298     GURL raw_url =
299         CreateRawFileSystemURL(kTestCases[i].type_str, kTestCases[i].root);
300     FileSystemURL cracked_url = file_system_context->CrackURL(raw_url);
301
302     SCOPED_TRACE(testing::Message() << "Test case " << i << ": "
303                                     << "Cracking URL: " << raw_url);
304
305     EXPECT_EQ(kTestCases[i].expect_is_valid, cracked_url.is_valid());
306     if (!kTestCases[i].expect_is_valid)
307       continue;
308
309     ExpectFileSystemURLMatches(
310         cracked_url,
311         GURL(kTestOrigin),
312         kTestCases[i].expect_mount_type,
313         kTestCases[i].expect_type,
314         base::FilePath(kTestCases[i].expect_path).NormalizePathSeparators(),
315         virtual_path.NormalizePathSeparators(),
316         kTestCases[i].expect_filesystem_id);
317   }
318
319   IsolatedContext::GetInstance()->RevokeFileSystemByPath(
320       base::FilePath(DRIVE FPL("/test/isolated/root")));
321   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("system");
322   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("ext");
323   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
324       kIsolatedFileSystemID);
325 }
326
327 TEST_F(FileSystemContextTest, CanServeURLRequest) {
328   scoped_refptr<ExternalMountPoints> external_mount_points(
329       ExternalMountPoints::CreateRefCounted());
330   scoped_refptr<FileSystemContext> context(
331       CreateFileSystemContextForTest(external_mount_points.get()));
332
333   // A request for a sandbox mount point should be served.
334   FileSystemURL cracked_url =
335       context->CrackURL(CreateRawFileSystemURL("persistent", "pers_mount"));
336   EXPECT_EQ(storage::kFileSystemTypePersistent, cracked_url.mount_type());
337   EXPECT_TRUE(context->CanServeURLRequest(cracked_url));
338
339   // A request for an isolated mount point should NOT be served.
340   std::string isolated_fs_name = "root";
341   std::string isolated_fs_id =
342       IsolatedContext::GetInstance()->RegisterFileSystemForPath(
343           storage::kFileSystemTypeNativeLocal,
344           std::string(),
345           base::FilePath(DRIVE FPL("/test/isolated/root")),
346           &isolated_fs_name);
347   cracked_url = context->CrackURL(
348       CreateRawFileSystemURL("isolated", isolated_fs_id));
349   EXPECT_EQ(storage::kFileSystemTypeIsolated, cracked_url.mount_type());
350   EXPECT_FALSE(context->CanServeURLRequest(cracked_url));
351
352   // A request for an external mount point should be served.
353   const std::string kExternalMountName = "ext_mount";
354   ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
355       kExternalMountName,
356       storage::kFileSystemTypeDrive,
357       FileSystemMountOption(),
358       base::FilePath()));
359   cracked_url = context->CrackURL(
360       CreateRawFileSystemURL("external", kExternalMountName));
361   EXPECT_EQ(storage::kFileSystemTypeExternal, cracked_url.mount_type());
362   EXPECT_TRUE(context->CanServeURLRequest(cracked_url));
363
364   ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
365       kExternalMountName);
366   IsolatedContext::GetInstance()->RevokeFileSystem(isolated_fs_id);
367 }
368
369 }  // namespace
370
371 }  // namespace content