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 "base/basictypes.h"
6 #include "base/files/file_util.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "base/run_loop.h"
12 #include "content/public/test/async_file_test_helper.h"
13 #include "content/public/test/test_file_system_context.h"
14 #include "content/public/test/test_file_system_options.h"
15 #include "storage/browser/fileapi/file_system_context.h"
16 #include "storage/browser/fileapi/isolated_context.h"
17 #include "storage/browser/fileapi/obfuscated_file_util.h"
18 #include "storage/browser/fileapi/plugin_private_file_system_backend.h"
19 #include "storage/common/fileapi/file_system_util.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using content::AsyncFileTestHelper
;
23 using storage::FileSystemContext
;
24 using storage::FileSystemURL
;
25 using storage::IsolatedContext
;
31 const GURL
kOrigin1("http://www.example.com");
32 const GURL
kOrigin2("https://www.example.com");
33 const std::string
kPlugin1("plugin1");
34 const std::string
kPlugin2("plugin2");
35 const storage::FileSystemType kType
= storage::kFileSystemTypePluginPrivate
;
36 const std::string kRootName
= "pluginprivate";
38 void DidOpenFileSystem(base::File::Error
* error_out
,
39 base::File::Error error
) {
43 std::string
RegisterFileSystem() {
44 return IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
45 kType
, kRootName
, base::FilePath());
50 class PluginPrivateFileSystemBackendTest
: public testing::Test
{
52 void SetUp() override
{
53 ASSERT_TRUE(data_dir_
.CreateUniqueTempDir());
54 context_
= CreateFileSystemContextForTesting(
55 NULL
/* quota_manager_proxy */,
59 FileSystemURL
CreateURL(const GURL
& root_url
, const std::string
& relative
) {
60 FileSystemURL root
= context_
->CrackURL(root_url
);
61 return context_
->CreateCrackedFileSystemURL(
64 root
.virtual_path().AppendASCII(relative
));
67 storage::PluginPrivateFileSystemBackend
* backend() const {
68 return context_
->plugin_private_backend();
71 const base::FilePath
& base_path() const { return backend()->base_path(); }
73 base::ScopedTempDir data_dir_
;
74 base::MessageLoop message_loop_
;
75 scoped_refptr
<FileSystemContext
> context_
;
78 // TODO(kinuko,nhiroki): There are a lot of duplicate code in these tests. Write
79 // helper functions to simplify the tests.
81 TEST_F(PluginPrivateFileSystemBackendTest
, OpenFileSystemBasic
) {
82 const std::string filesystem_id1
= RegisterFileSystem();
83 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
84 backend()->OpenPrivateFileSystem(
89 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
,
90 base::Bind(&DidOpenFileSystem
, &error
));
91 base::RunLoop().RunUntilIdle();
92 ASSERT_EQ(base::File::FILE_OK
, error
);
94 // Run this again with FAIL_IF_NONEXISTENT to see if it succeeds.
95 const std::string filesystem_id2
= RegisterFileSystem();
96 error
= base::File::FILE_ERROR_FAILED
;
97 backend()->OpenPrivateFileSystem(
102 storage::OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT
,
103 base::Bind(&DidOpenFileSystem
, &error
));
104 base::RunLoop().RunUntilIdle();
105 ASSERT_EQ(base::File::FILE_OK
, error
);
107 const GURL
root_url(storage::GetIsolatedFileSystemRootURIString(
108 kOrigin1
, filesystem_id1
, kRootName
));
109 FileSystemURL file
= CreateURL(root_url
, "foo");
110 base::FilePath platform_path
;
111 EXPECT_EQ(base::File::FILE_OK
,
112 AsyncFileTestHelper::CreateFile(context_
.get(), file
));
113 EXPECT_EQ(base::File::FILE_OK
,
114 AsyncFileTestHelper::GetPlatformPath(context_
.get(), file
,
116 EXPECT_TRUE(base_path().AppendASCII("000").AppendASCII(kPlugin1
).IsParent(
120 TEST_F(PluginPrivateFileSystemBackendTest
, PluginIsolation
) {
121 // Open filesystem for kPlugin1 and kPlugin2.
122 const std::string filesystem_id1
= RegisterFileSystem();
123 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
124 backend()->OpenPrivateFileSystem(
129 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
,
130 base::Bind(&DidOpenFileSystem
, &error
));
131 base::RunLoop().RunUntilIdle();
132 ASSERT_EQ(base::File::FILE_OK
, error
);
134 const std::string filesystem_id2
= RegisterFileSystem();
135 error
= base::File::FILE_ERROR_FAILED
;
136 backend()->OpenPrivateFileSystem(
141 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
,
142 base::Bind(&DidOpenFileSystem
, &error
));
143 base::RunLoop().RunUntilIdle();
144 ASSERT_EQ(base::File::FILE_OK
, error
);
146 // Create 'foo' in kPlugin1.
147 const GURL
root_url1(storage::GetIsolatedFileSystemRootURIString(
148 kOrigin1
, filesystem_id1
, kRootName
));
149 FileSystemURL file1
= CreateURL(root_url1
, "foo");
150 EXPECT_EQ(base::File::FILE_OK
,
151 AsyncFileTestHelper::CreateFile(context_
.get(), file1
));
152 EXPECT_TRUE(AsyncFileTestHelper::FileExists(
153 context_
.get(), file1
, AsyncFileTestHelper::kDontCheckSize
));
155 // See the same path is not available in kPlugin2.
156 const GURL
root_url2(storage::GetIsolatedFileSystemRootURIString(
157 kOrigin1
, filesystem_id2
, kRootName
));
158 FileSystemURL file2
= CreateURL(root_url2
, "foo");
159 EXPECT_FALSE(AsyncFileTestHelper::FileExists(
160 context_
.get(), file2
, AsyncFileTestHelper::kDontCheckSize
));
163 TEST_F(PluginPrivateFileSystemBackendTest
, OriginIsolation
) {
164 // Open filesystem for kOrigin1 and kOrigin2.
165 const std::string filesystem_id1
= RegisterFileSystem();
166 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
167 backend()->OpenPrivateFileSystem(
172 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
,
173 base::Bind(&DidOpenFileSystem
, &error
));
174 base::RunLoop().RunUntilIdle();
175 ASSERT_EQ(base::File::FILE_OK
, error
);
177 const std::string filesystem_id2
= RegisterFileSystem();
178 error
= base::File::FILE_ERROR_FAILED
;
179 backend()->OpenPrivateFileSystem(
184 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
,
185 base::Bind(&DidOpenFileSystem
, &error
));
186 base::RunLoop().RunUntilIdle();
187 ASSERT_EQ(base::File::FILE_OK
, error
);
189 // Create 'foo' in kOrigin1.
190 const GURL
root_url1(storage::GetIsolatedFileSystemRootURIString(
191 kOrigin1
, filesystem_id1
, kRootName
));
192 FileSystemURL file1
= CreateURL(root_url1
, "foo");
193 EXPECT_EQ(base::File::FILE_OK
,
194 AsyncFileTestHelper::CreateFile(context_
.get(), file1
));
195 EXPECT_TRUE(AsyncFileTestHelper::FileExists(
196 context_
.get(), file1
, AsyncFileTestHelper::kDontCheckSize
));
198 // See the same path is not available in kOrigin2.
199 const GURL
root_url2(storage::GetIsolatedFileSystemRootURIString(
200 kOrigin2
, filesystem_id2
, kRootName
));
201 FileSystemURL file2
= CreateURL(root_url2
, "foo");
202 EXPECT_FALSE(AsyncFileTestHelper::FileExists(
203 context_
.get(), file2
, AsyncFileTestHelper::kDontCheckSize
));
206 TEST_F(PluginPrivateFileSystemBackendTest
, DeleteOriginDirectory
) {
207 // Open filesystem for kOrigin1 and kOrigin2.
208 const std::string filesystem_id1
= RegisterFileSystem();
209 base::File::Error error
= base::File::FILE_ERROR_FAILED
;
210 backend()->OpenPrivateFileSystem(
215 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
,
216 base::Bind(&DidOpenFileSystem
, &error
));
217 base::RunLoop().RunUntilIdle();
218 ASSERT_EQ(base::File::FILE_OK
, error
);
220 const std::string filesystem_id2
= RegisterFileSystem();
221 error
= base::File::FILE_ERROR_FAILED
;
222 backend()->OpenPrivateFileSystem(
227 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
,
228 base::Bind(&DidOpenFileSystem
, &error
));
229 base::RunLoop().RunUntilIdle();
230 ASSERT_EQ(base::File::FILE_OK
, error
);
232 // Create 'foo' in kOrigin1.
233 const GURL
root_url1(storage::GetIsolatedFileSystemRootURIString(
234 kOrigin1
, filesystem_id1
, kRootName
));
235 FileSystemURL file1
= CreateURL(root_url1
, "foo");
236 EXPECT_EQ(base::File::FILE_OK
,
237 AsyncFileTestHelper::CreateFile(context_
.get(), file1
));
238 EXPECT_TRUE(AsyncFileTestHelper::FileExists(
239 context_
.get(), file1
, AsyncFileTestHelper::kDontCheckSize
));
241 // Create 'foo' in kOrigin2.
242 const GURL
root_url2(storage::GetIsolatedFileSystemRootURIString(
243 kOrigin2
, filesystem_id2
, kRootName
));
244 FileSystemURL file2
= CreateURL(root_url2
, "foo");
245 EXPECT_EQ(base::File::FILE_OK
,
246 AsyncFileTestHelper::CreateFile(context_
.get(), file2
));
247 EXPECT_TRUE(AsyncFileTestHelper::FileExists(
248 context_
.get(), file2
, AsyncFileTestHelper::kDontCheckSize
));
250 // Delete data for kOrigin1.
251 error
= backend()->DeleteOriginDataOnFileTaskRunner(
252 context_
.get(), NULL
, kOrigin1
, kType
);
253 EXPECT_EQ(base::File::FILE_OK
, error
);
255 // Confirm 'foo' in kOrigin1 is deleted.
256 EXPECT_FALSE(AsyncFileTestHelper::FileExists(
257 context_
.get(), file1
, AsyncFileTestHelper::kDontCheckSize
));
259 // Confirm 'foo' in kOrigin2 is NOT deleted.
260 EXPECT_TRUE(AsyncFileTestHelper::FileExists(
261 context_
.get(), file2
, AsyncFileTestHelper::kDontCheckSize
));
263 // Re-open filesystem for kOrigin1.
264 const std::string filesystem_id3
= RegisterFileSystem();
265 error
= base::File::FILE_ERROR_FAILED
;
266 backend()->OpenPrivateFileSystem(
271 storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
,
272 base::Bind(&DidOpenFileSystem
, &error
));
273 base::RunLoop().RunUntilIdle();
274 ASSERT_EQ(base::File::FILE_OK
, error
);
276 // Re-create 'foo' in kOrigin1.
277 const GURL
root_url3(storage::GetIsolatedFileSystemRootURIString(
278 kOrigin1
, filesystem_id3
, kRootName
));
279 FileSystemURL file3
= CreateURL(root_url3
, "foo");
280 EXPECT_EQ(base::File::FILE_OK
,
281 AsyncFileTestHelper::CreateFile(context_
.get(), file3
));
282 EXPECT_TRUE(AsyncFileTestHelper::FileExists(
283 context_
.get(), file3
, AsyncFileTestHelper::kDontCheckSize
));
285 // Confirm 'foo' in kOrigin1 is re-created.
286 EXPECT_TRUE(AsyncFileTestHelper::FileExists(
287 context_
.get(), file3
, AsyncFileTestHelper::kDontCheckSize
));
290 } // namespace content