Make USB permissions work in the new permission message system
[chromium-blink-merge.git] / content / browser / fileapi / file_system_context_unittest.cc
blobb1ffb6359d0f7d21aa7f4192bb93b612f80482a8
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.
5 #include "storage/browser/fileapi/file_system_context.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/thread_task_runner_handle.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"
18 #define FPL(x) FILE_PATH_LITERAL(x)
20 #if defined(FILE_PATH_USES_DRIVE_LETTERS)
21 #define DRIVE FPL("C:")
22 #else
23 #define DRIVE
24 #endif
26 using storage::ExternalMountPoints;
27 using storage::FileSystemBackend;
28 using storage::FileSystemContext;
29 using storage::FileSystemMountOption;
30 using storage::FileSystemURL;
31 using storage::IsolatedContext;
33 namespace content {
35 namespace {
37 const char kTestOrigin[] = "http://chromium.org/";
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);
48 class FileSystemContextTest : public testing::Test {
49 public:
50 FileSystemContextTest() {}
52 void SetUp() override {
53 ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
55 storage_policy_ = new MockSpecialStoragePolicy();
57 mock_quota_manager_ = new MockQuotaManager(
58 false /* is_incognito */, data_dir_.path(),
59 base::ThreadTaskRunnerHandle::Get().get(),
60 base::ThreadTaskRunnerHandle::Get().get(), storage_policy_.get());
63 protected:
64 FileSystemContext* CreateFileSystemContextForTest(
65 storage::ExternalMountPoints* external_mount_points) {
66 return new FileSystemContext(
67 base::ThreadTaskRunnerHandle::Get().get(),
68 base::ThreadTaskRunnerHandle::Get().get(), external_mount_points,
69 storage_policy_.get(), mock_quota_manager_->proxy(),
70 ScopedVector<FileSystemBackend>(),
71 std::vector<storage::URLRequestAutoMountHandler>(), data_dir_.path(),
72 CreateAllowFileAccessOptions());
75 // Verifies a *valid* filesystem url has expected values.
76 void ExpectFileSystemURLMatches(const FileSystemURL& url,
77 const GURL& expect_origin,
78 storage::FileSystemType expect_mount_type,
79 storage::FileSystemType expect_type,
80 const base::FilePath& expect_path,
81 const base::FilePath& expect_virtual_path,
82 const std::string& expect_filesystem_id) {
83 EXPECT_TRUE(url.is_valid());
85 EXPECT_EQ(expect_origin, url.origin());
86 EXPECT_EQ(expect_mount_type, url.mount_type());
87 EXPECT_EQ(expect_type, url.type());
88 EXPECT_EQ(expect_path, url.path());
89 EXPECT_EQ(expect_virtual_path, url.virtual_path());
90 EXPECT_EQ(expect_filesystem_id, url.filesystem_id());
93 private:
94 base::ScopedTempDir data_dir_;
95 base::MessageLoop message_loop_;
96 scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
97 scoped_refptr<MockQuotaManager> mock_quota_manager_;
100 // It is not valid to pass NULL ExternalMountPoints to FileSystemContext on
101 // ChromeOS.
102 #if !defined(OS_CHROMEOS)
103 TEST_F(FileSystemContextTest, NullExternalMountPoints) {
104 scoped_refptr<FileSystemContext> file_system_context(
105 CreateFileSystemContextForTest(NULL));
107 // Cracking system external mount and isolated mount points should work.
108 std::string isolated_name = "root";
109 std::string isolated_id =
110 IsolatedContext::GetInstance()->RegisterFileSystemForPath(
111 storage::kFileSystemTypeNativeLocal,
112 std::string(),
113 base::FilePath(DRIVE FPL("/test/isolated/root")),
114 &isolated_name);
115 // Register system external mount point.
116 ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
117 "system",
118 storage::kFileSystemTypeNativeLocal,
119 FileSystemMountOption(),
120 base::FilePath(DRIVE FPL("/test/sys/"))));
122 FileSystemURL cracked_isolated = file_system_context->CrackURL(
123 CreateRawFileSystemURL("isolated", isolated_id));
125 ExpectFileSystemURLMatches(
126 cracked_isolated,
127 GURL(kTestOrigin),
128 storage::kFileSystemTypeIsolated,
129 storage::kFileSystemTypeNativeLocal,
130 base::FilePath(DRIVE FPL("/test/isolated/root/file"))
131 .NormalizePathSeparators(),
132 base::FilePath::FromUTF8Unsafe(isolated_id)
133 .Append(FPL("root/file"))
134 .NormalizePathSeparators(),
135 isolated_id);
137 FileSystemURL cracked_external = file_system_context->CrackURL(
138 CreateRawFileSystemURL("external", "system"));
140 ExpectFileSystemURLMatches(
141 cracked_external,
142 GURL(kTestOrigin),
143 storage::kFileSystemTypeExternal,
144 storage::kFileSystemTypeNativeLocal,
145 base::FilePath(DRIVE FPL("/test/sys/root/file"))
146 .NormalizePathSeparators(),
147 base::FilePath(FPL("system/root/file")).NormalizePathSeparators(),
148 "system");
150 IsolatedContext::GetInstance()->RevokeFileSystem(isolated_id);
151 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("system");
153 #endif // !defiend(OS_CHROMEOS)
155 TEST_F(FileSystemContextTest, FileSystemContextKeepsMountPointsAlive) {
156 scoped_refptr<ExternalMountPoints> mount_points =
157 ExternalMountPoints::CreateRefCounted();
159 // Register system external mount point.
160 ASSERT_TRUE(mount_points->RegisterFileSystem(
161 "system",
162 storage::kFileSystemTypeNativeLocal,
163 FileSystemMountOption(),
164 base::FilePath(DRIVE FPL("/test/sys/"))));
166 scoped_refptr<FileSystemContext> file_system_context(
167 CreateFileSystemContextForTest(mount_points.get()));
169 // Release a MountPoints reference created in the test.
170 mount_points = NULL;
172 // FileSystemContext should keep a reference to the |mount_points|, so it
173 // should be able to resolve the URL.
174 FileSystemURL cracked_external = file_system_context->CrackURL(
175 CreateRawFileSystemURL("external", "system"));
177 ExpectFileSystemURLMatches(
178 cracked_external,
179 GURL(kTestOrigin),
180 storage::kFileSystemTypeExternal,
181 storage::kFileSystemTypeNativeLocal,
182 base::FilePath(DRIVE FPL("/test/sys/root/file"))
183 .NormalizePathSeparators(),
184 base::FilePath(FPL("system/root/file")).NormalizePathSeparators(),
185 "system");
187 // No need to revoke the registered filesystem since |mount_points| lifetime
188 // is bound to this test.
191 TEST_F(FileSystemContextTest, CrackFileSystemURL) {
192 scoped_refptr<ExternalMountPoints> external_mount_points(
193 ExternalMountPoints::CreateRefCounted());
194 scoped_refptr<FileSystemContext> file_system_context(
195 CreateFileSystemContextForTest(external_mount_points.get()));
197 // Register an isolated mount point.
198 std::string isolated_file_system_name = "root";
199 const std::string kIsolatedFileSystemID =
200 IsolatedContext::GetInstance()->RegisterFileSystemForPath(
201 storage::kFileSystemTypeNativeLocal,
202 std::string(),
203 base::FilePath(DRIVE FPL("/test/isolated/root")),
204 &isolated_file_system_name);
205 // Register system external mount point.
206 ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
207 "system",
208 storage::kFileSystemTypeDrive,
209 FileSystemMountOption(),
210 base::FilePath(DRIVE FPL("/test/sys/"))));
211 ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
212 "ext",
213 storage::kFileSystemTypeNativeLocal,
214 FileSystemMountOption(),
215 base::FilePath(DRIVE FPL("/test/ext"))));
216 // Register a system external mount point with the same name/id as the
217 // registered isolated mount point.
218 ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
219 kIsolatedFileSystemID,
220 storage::kFileSystemTypeRestrictedNativeLocal,
221 FileSystemMountOption(),
222 base::FilePath(DRIVE FPL("/test/system/isolated"))));
223 // Add a mount points with the same name as a system mount point to
224 // FileSystemContext's external mount points.
225 ASSERT_TRUE(external_mount_points->RegisterFileSystem(
226 "ext",
227 storage::kFileSystemTypeNativeLocal,
228 FileSystemMountOption(),
229 base::FilePath(DRIVE FPL("/test/local/ext/"))));
231 const GURL kTestOrigin = GURL("http://chromium.org/");
232 const base::FilePath kVirtualPathNoRoot = base::FilePath(FPL("root/file"));
234 struct TestCase {
235 // Test case values.
236 std::string root;
237 std::string type_str;
239 // Expected test results.
240 bool expect_is_valid;
241 storage::FileSystemType expect_mount_type;
242 storage::FileSystemType expect_type;
243 const base::FilePath::CharType* expect_path;
244 std::string expect_filesystem_id;
247 const TestCase kTestCases[] = {
248 // Following should not be handled by the url crackers:
250 "pers_mount", "persistent", true /* is_valid */,
251 storage::kFileSystemTypePersistent, storage::kFileSystemTypePersistent,
252 FPL("pers_mount/root/file"), std::string() /* filesystem id */
255 "temp_mount", "temporary", true /* is_valid */,
256 storage::kFileSystemTypeTemporary, storage::kFileSystemTypeTemporary,
257 FPL("temp_mount/root/file"), std::string() /* filesystem id */
259 // Should be cracked by isolated mount points:
260 {kIsolatedFileSystemID, "isolated", true /* is_valid */,
261 storage::kFileSystemTypeIsolated, storage::kFileSystemTypeNativeLocal,
262 DRIVE FPL("/test/isolated/root/file"), kIsolatedFileSystemID},
263 // Should be cracked by system mount points:
264 {"system", "external", true /* is_valid */,
265 storage::kFileSystemTypeExternal, storage::kFileSystemTypeDrive,
266 DRIVE FPL("/test/sys/root/file"), "system"},
267 {kIsolatedFileSystemID, "external", true /* is_valid */,
268 storage::kFileSystemTypeExternal,
269 storage::kFileSystemTypeRestrictedNativeLocal,
270 DRIVE FPL("/test/system/isolated/root/file"), kIsolatedFileSystemID},
271 // Should be cracked by FileSystemContext's ExternalMountPoints.
272 {"ext", "external", true /* is_valid */, storage::kFileSystemTypeExternal,
273 storage::kFileSystemTypeNativeLocal,
274 DRIVE FPL("/test/local/ext/root/file"), "ext"},
275 // Test for invalid filesystem url (made invalid by adding invalid
276 // filesystem type).
277 {"sytem", "external", false /* is_valid */,
278 // The rest of values will be ignored.
279 storage::kFileSystemTypeUnknown, storage::kFileSystemTypeUnknown,
280 FPL(""), std::string()},
281 // Test for URL with non-existing filesystem id.
282 {"invalid", "external", false /* is_valid */,
283 // The rest of values will be ignored.
284 storage::kFileSystemTypeUnknown, storage::kFileSystemTypeUnknown,
285 FPL(""), std::string()},
288 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
289 const base::FilePath virtual_path =
290 base::FilePath::FromUTF8Unsafe(
291 kTestCases[i].root).Append(kVirtualPathNoRoot);
293 GURL raw_url =
294 CreateRawFileSystemURL(kTestCases[i].type_str, kTestCases[i].root);
295 FileSystemURL cracked_url = file_system_context->CrackURL(raw_url);
297 SCOPED_TRACE(testing::Message() << "Test case " << i << ": "
298 << "Cracking URL: " << raw_url);
300 EXPECT_EQ(kTestCases[i].expect_is_valid, cracked_url.is_valid());
301 if (!kTestCases[i].expect_is_valid)
302 continue;
304 ExpectFileSystemURLMatches(
305 cracked_url,
306 GURL(kTestOrigin),
307 kTestCases[i].expect_mount_type,
308 kTestCases[i].expect_type,
309 base::FilePath(kTestCases[i].expect_path).NormalizePathSeparators(),
310 virtual_path.NormalizePathSeparators(),
311 kTestCases[i].expect_filesystem_id);
314 IsolatedContext::GetInstance()->RevokeFileSystemByPath(
315 base::FilePath(DRIVE FPL("/test/isolated/root")));
316 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("system");
317 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("ext");
318 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
319 kIsolatedFileSystemID);
322 TEST_F(FileSystemContextTest, CanServeURLRequest) {
323 scoped_refptr<ExternalMountPoints> external_mount_points(
324 ExternalMountPoints::CreateRefCounted());
325 scoped_refptr<FileSystemContext> context(
326 CreateFileSystemContextForTest(external_mount_points.get()));
328 // A request for a sandbox mount point should be served.
329 FileSystemURL cracked_url =
330 context->CrackURL(CreateRawFileSystemURL("persistent", "pers_mount"));
331 EXPECT_EQ(storage::kFileSystemTypePersistent, cracked_url.mount_type());
332 EXPECT_TRUE(context->CanServeURLRequest(cracked_url));
334 // A request for an isolated mount point should NOT be served.
335 std::string isolated_fs_name = "root";
336 std::string isolated_fs_id =
337 IsolatedContext::GetInstance()->RegisterFileSystemForPath(
338 storage::kFileSystemTypeNativeLocal,
339 std::string(),
340 base::FilePath(DRIVE FPL("/test/isolated/root")),
341 &isolated_fs_name);
342 cracked_url = context->CrackURL(
343 CreateRawFileSystemURL("isolated", isolated_fs_id));
344 EXPECT_EQ(storage::kFileSystemTypeIsolated, cracked_url.mount_type());
345 EXPECT_FALSE(context->CanServeURLRequest(cracked_url));
347 // A request for an external mount point should be served.
348 const std::string kExternalMountName = "ext_mount";
349 ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
350 kExternalMountName,
351 storage::kFileSystemTypeDrive,
352 FileSystemMountOption(),
353 base::FilePath()));
354 cracked_url = context->CrackURL(
355 CreateRawFileSystemURL("external", kExternalMountName));
356 EXPECT_EQ(storage::kFileSystemTypeExternal, cracked_url.mount_type());
357 EXPECT_TRUE(context->CanServeURLRequest(cracked_url));
359 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
360 kExternalMountName);
361 IsolatedContext::GetInstance()->RevokeFileSystem(isolated_fs_id);
364 // Ensures that a backend exists for each common isolated file system type.
365 // See http://crbug.com/447027
366 TEST_F(FileSystemContextTest, IsolatedFileSystemsTypesHandled) {
367 // This does not provide any "additional" file system handlers. In particular,
368 // on Chrome OS it does not provide chromeos::FileSystemBackend.
369 scoped_refptr<FileSystemContext> file_system_context(
370 CreateFileSystemContextForTest(nullptr));
372 // Isolated file system types are handled.
373 EXPECT_TRUE(file_system_context->GetFileSystemBackend(
374 storage::kFileSystemTypeIsolated));
375 EXPECT_TRUE(file_system_context->GetFileSystemBackend(
376 storage::kFileSystemTypeDragged));
377 EXPECT_TRUE(file_system_context->GetFileSystemBackend(
378 storage::kFileSystemTypeForTransientFile));
379 EXPECT_TRUE(file_system_context->GetFileSystemBackend(
380 storage::kFileSystemTypeNativeLocal));
381 EXPECT_TRUE(file_system_context->GetFileSystemBackend(
382 storage::kFileSystemTypeNativeForPlatformApp));
385 } // namespace
387 } // namespace content