1 // Copyright (c) 2012 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.
8 #include "base/basictypes.h"
10 #include "base/file_util.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/message_loop.h"
16 #include "base/message_loop_proxy.h"
17 #include "base/strings/sys_string_conversions.h"
18 #include "base/utf_string_conversions.h"
19 #include "googleurl/src/gurl.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "webkit/fileapi/external_mount_points.h"
22 #include "webkit/fileapi/file_system_context.h"
23 #include "webkit/fileapi/file_system_task_runners.h"
24 #include "webkit/fileapi/file_system_url.h"
25 #include "webkit/fileapi/file_system_util.h"
26 #include "webkit/fileapi/mock_file_system_options.h"
27 #include "webkit/fileapi/sandbox_mount_point_provider.h"
28 #include "webkit/quota/mock_special_storage_policy.h"
30 #if defined(OS_CHROMEOS)
31 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h"
38 // PS stands for path separator.
39 #if defined(FILE_PATH_USES_WIN_SEPARATORS)
45 struct RootPathTestCase
{
46 fileapi::FileSystemType type
;
47 const char* origin_url
;
48 const char* expected_path
;
51 const struct RootPathTest
{
52 fileapi::FileSystemType type
;
53 const char* origin_url
;
54 const char* expected_path
;
55 } kRootPathTestCases
[] = {
56 { fileapi::kFileSystemTypeTemporary
, "http://foo:1/",
58 { fileapi::kFileSystemTypePersistent
, "http://foo:1/",
60 { fileapi::kFileSystemTypeTemporary
, "http://bar.com/",
62 { fileapi::kFileSystemTypePersistent
, "http://bar.com/",
64 { fileapi::kFileSystemTypeTemporary
, "https://foo:2/",
66 { fileapi::kFileSystemTypePersistent
, "https://foo:2/",
68 { fileapi::kFileSystemTypeTemporary
, "https://bar.com/",
70 { fileapi::kFileSystemTypePersistent
, "https://bar.com/",
72 #if defined(OS_CHROMEOS)
73 { fileapi::kFileSystemTypeExternal
, "chrome-extension://foo/",
74 "chrome-extension__0" /* unused, only for logging */ },
78 const struct RootPathFileURITest
{
79 fileapi::FileSystemType type
;
80 const char* origin_url
;
81 const char* expected_path
;
82 const char* virtual_path
;
83 } kRootPathFileURITestCases
[] = {
84 { fileapi::kFileSystemTypeTemporary
, "file:///",
86 { fileapi::kFileSystemTypePersistent
, "file:///",
90 const struct CheckValidPathTest
{
91 base::FilePath::StringType path
;
93 } kCheckValidPathTestCases
[] = {
94 { FILE_PATH_LITERAL("//tmp/foo.txt"), false, },
95 { FILE_PATH_LITERAL("//etc/hosts"), false, },
96 { FILE_PATH_LITERAL("foo.txt"), true, },
97 { FILE_PATH_LITERAL("a/b/c"), true, },
98 // Any paths that includes parent references are considered invalid.
99 { FILE_PATH_LITERAL(".."), false, },
100 { FILE_PATH_LITERAL("tmp/.."), false, },
101 { FILE_PATH_LITERAL("a/b/../c/.."), false, },
104 // For External filesystem.
105 const base::FilePath::CharType kMountPoint
[] = FILE_PATH_LITERAL("/tmp/testing");
106 const base::FilePath::CharType kRootPath
[] = FILE_PATH_LITERAL("/tmp");
107 const base::FilePath::CharType kVirtualPath
[] = FILE_PATH_LITERAL("testing");
111 class FileSystemMountPointProviderTest
: public testing::Test
{
113 FileSystemMountPointProviderTest()
114 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
117 virtual void SetUp() {
118 ASSERT_TRUE(data_dir_
.CreateUniqueTempDir());
119 special_storage_policy_
= new quota::MockSpecialStoragePolicy
;
123 void SetupNewContext(const FileSystemOptions
& options
) {
124 scoped_refptr
<ExternalMountPoints
> external_mount_points(
125 ExternalMountPoints::CreateRefCounted());
126 file_system_context_
= new FileSystemContext(
127 FileSystemTaskRunners::CreateMockTaskRunners(),
128 external_mount_points
.get(),
129 special_storage_policy_
,
133 #if defined(OS_CHROMEOS)
134 base::FilePath mount_point_path
= base::FilePath(kMountPoint
);
135 external_mount_points
->RegisterFileSystem(
136 mount_point_path
.BaseName().AsUTF8Unsafe(),
137 kFileSystemTypeNativeLocal
,
142 FileSystemMountPointProvider
* provider(FileSystemType type
) {
143 DCHECK(file_system_context_
);
144 return file_system_context_
->GetMountPointProvider(type
);
147 bool GetRootPath(const GURL
& origin_url
,
148 fileapi::FileSystemType type
,
150 base::FilePath
* root_path
) {
151 base::FilePath virtual_path
= base::FilePath();
152 if (type
== kFileSystemTypeExternal
)
153 virtual_path
= base::FilePath(kVirtualPath
);
154 FileSystemURL url
= file_system_context_
->CreateCrackedFileSystemURL(
155 origin_url
, type
, virtual_path
);
156 base::FilePath returned_root_path
=
157 provider(type
)->GetFileSystemRootPathOnFileThread(url
, create
);
159 *root_path
= returned_root_path
;
160 return !returned_root_path
.empty();
163 base::FilePath
data_path() const { return data_dir_
.path(); }
164 base::FilePath
file_system_path() const {
165 return data_dir_
.path().Append(
166 SandboxMountPointProvider::kFileSystemDirectory
);
168 FileSystemContext
* file_system_context() const {
169 return file_system_context_
.get();
173 base::ScopedTempDir data_dir_
;
174 MessageLoop message_loop_
;
175 base::WeakPtrFactory
<FileSystemMountPointProviderTest
> weak_factory_
;
177 scoped_refptr
<quota::SpecialStoragePolicy
> special_storage_policy_
;
178 scoped_refptr
<FileSystemContext
> file_system_context_
;
180 DISALLOW_COPY_AND_ASSIGN(FileSystemMountPointProviderTest
);
183 TEST_F(FileSystemMountPointProviderTest
, GetRootPathCreateAndExamine
) {
184 std::vector
<base::FilePath
> returned_root_path(
185 ARRAYSIZE_UNSAFE(kRootPathTestCases
));
186 SetupNewContext(CreateAllowFileAccessOptions());
188 // Create a new root directory.
189 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kRootPathTestCases
); ++i
) {
190 SCOPED_TRACE(testing::Message() << "RootPath (create) #" << i
<< " "
191 << kRootPathTestCases
[i
].expected_path
);
193 base::FilePath root_path
;
194 EXPECT_TRUE(GetRootPath(GURL(kRootPathTestCases
[i
].origin_url
),
195 kRootPathTestCases
[i
].type
,
196 true /* create */, &root_path
));
198 if (kRootPathTestCases
[i
].type
!= kFileSystemTypeExternal
) {
199 base::FilePath expected
= file_system_path().AppendASCII(
200 kRootPathTestCases
[i
].expected_path
);
201 EXPECT_EQ(expected
.value(), root_path
.value());
202 EXPECT_TRUE(file_util::DirectoryExists(root_path
));
204 // External file system root path is virtual one and does not match
205 // anything from the actual file system.
206 EXPECT_EQ(kRootPath
, root_path
.value());
208 ASSERT_TRUE(returned_root_path
.size() > i
);
209 returned_root_path
[i
] = root_path
;
212 // Get the root directory with create=false and see if we get the
214 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kRootPathTestCases
); ++i
) {
215 SCOPED_TRACE(testing::Message() << "RootPath (get) #" << i
<< " "
216 << kRootPathTestCases
[i
].expected_path
);
218 base::FilePath root_path
;
219 EXPECT_TRUE(GetRootPath(GURL(kRootPathTestCases
[i
].origin_url
),
220 kRootPathTestCases
[i
].type
,
221 false /* create */, &root_path
));
222 ASSERT_TRUE(returned_root_path
.size() > i
);
223 EXPECT_EQ(returned_root_path
[i
].value(), root_path
.value());
227 TEST_F(FileSystemMountPointProviderTest
,
228 GetRootPathCreateAndExamineWithNewProvider
) {
229 std::vector
<base::FilePath
> returned_root_path(
230 ARRAYSIZE_UNSAFE(kRootPathTestCases
));
231 SetupNewContext(CreateAllowFileAccessOptions());
233 GURL
origin_url("http://foo.com:1/");
235 base::FilePath root_path1
;
236 EXPECT_TRUE(GetRootPath(origin_url
,
237 kFileSystemTypeTemporary
, true, &root_path1
));
239 SetupNewContext(CreateDisallowFileAccessOptions());
240 base::FilePath root_path2
;
241 EXPECT_TRUE(GetRootPath(origin_url
,
242 kFileSystemTypeTemporary
, false, &root_path2
));
244 EXPECT_EQ(root_path1
.value(), root_path2
.value());
247 TEST_F(FileSystemMountPointProviderTest
, GetRootPathGetWithoutCreate
) {
248 SetupNewContext(CreateDisallowFileAccessOptions());
250 // Try to get a root directory without creating.
251 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kRootPathTestCases
); ++i
) {
252 SCOPED_TRACE(testing::Message() << "RootPath (create=false) #" << i
<< " "
253 << kRootPathTestCases
[i
].expected_path
);
254 // External type does not check the directory existence.
255 if (kRootPathTestCases
[i
].type
!= kFileSystemTypeExternal
) {
256 EXPECT_FALSE(GetRootPath(GURL(kRootPathTestCases
[i
].origin_url
),
257 kRootPathTestCases
[i
].type
,
258 false /* create */, NULL
));
263 TEST_F(FileSystemMountPointProviderTest
, GetRootPathInIncognito
) {
264 SetupNewContext(CreateIncognitoFileSystemOptions());
266 // Try to get a root directory.
267 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kRootPathTestCases
); ++i
) {
268 SCOPED_TRACE(testing::Message() << "RootPath (incognito) #" << i
<< " "
269 << kRootPathTestCases
[i
].expected_path
);
270 // External type does not change the behavior in incognito mode.
271 if (kRootPathTestCases
[i
].type
!= kFileSystemTypeExternal
) {
272 EXPECT_FALSE(GetRootPath(GURL(kRootPathTestCases
[i
].origin_url
),
273 kRootPathTestCases
[i
].type
,
274 true /* create */, NULL
));
279 TEST_F(FileSystemMountPointProviderTest
, GetRootPathFileURI
) {
280 SetupNewContext(CreateDisallowFileAccessOptions());
281 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kRootPathFileURITestCases
); ++i
) {
282 SCOPED_TRACE(testing::Message() << "RootPathFileURI (disallow) #"
283 << i
<< " " << kRootPathFileURITestCases
[i
].expected_path
);
284 EXPECT_FALSE(GetRootPath(GURL(kRootPathFileURITestCases
[i
].origin_url
),
285 kRootPathFileURITestCases
[i
].type
,
286 true /* create */, NULL
));
290 TEST_F(FileSystemMountPointProviderTest
, GetRootPathFileURIWithAllowFlag
) {
291 SetupNewContext(CreateAllowFileAccessOptions());
292 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kRootPathFileURITestCases
); ++i
) {
293 SCOPED_TRACE(testing::Message() << "RootPathFileURI (allow) #"
294 << i
<< " " << kRootPathFileURITestCases
[i
].expected_path
);
295 base::FilePath root_path
;
296 EXPECT_TRUE(GetRootPath(GURL(kRootPathFileURITestCases
[i
].origin_url
),
297 kRootPathFileURITestCases
[i
].type
,
298 true /* create */, &root_path
));
299 base::FilePath expected
= file_system_path().AppendASCII(
300 kRootPathFileURITestCases
[i
].expected_path
);
301 EXPECT_EQ(expected
.value(), root_path
.value());
302 EXPECT_TRUE(file_util::DirectoryExists(root_path
));
306 } // namespace fileapi