1 // Copyright 2014 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/files/file.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
12 #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
13 #include "chrome/browser/chromeos/file_system_provider/observer.h"
14 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
15 #include "chrome/browser/chromeos/file_system_provider/service.h"
16 #include "chrome/browser/chromeos/login/fake_user_manager.h"
17 #include "chrome/test/base/testing_profile.h"
18 #include "content/public/test/test_browser_thread_bundle.h"
19 #include "extensions/browser/extension_registry.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/manifest_constants.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "webkit/browser/fileapi/external_mount_points.h"
26 namespace file_system_provider
{
29 const char kExtensionId
[] = "mbflcebpggnecokmikipoihdbecnjfoj";
30 const char kFileSystemName
[] = "Camera Pictures";
32 // Utility observer, logging events from file_system_provider::Service.
33 class LoggingObserver
: public Observer
{
37 Event(const ProvidedFileSystemInfo
& file_system_info
,
38 base::File::Error error
)
39 : file_system_info_(file_system_info
), error_(error
) {}
42 const ProvidedFileSystemInfo
& file_system_info() {
43 return file_system_info_
;
45 base::File::Error
error() { return error_
; }
48 ProvidedFileSystemInfo file_system_info_
;
49 base::File::Error error_
;
53 virtual ~LoggingObserver() {}
55 // file_system_provider::Observer overrides.
56 virtual void OnProvidedFileSystemMount(
57 const ProvidedFileSystemInfo
& file_system_info
,
58 base::File::Error error
) OVERRIDE
{
59 mounts
.push_back(Event(file_system_info
, error
));
62 virtual void OnProvidedFileSystemUnmount(
63 const ProvidedFileSystemInfo
& file_system_info
,
64 base::File::Error error
) OVERRIDE
{
65 unmounts
.push_back(Event(file_system_info
, error
));
68 std::vector
<Event
> mounts
;
69 std::vector
<Event
> unmounts
;
72 // Creates a fake extension with the specified |extension_id|.
73 scoped_refptr
<extensions::Extension
> createFakeExtension(
74 const std::string
& extension_id
) {
75 base::DictionaryValue manifest
;
77 manifest
.SetString(extensions::manifest_keys::kVersion
, "1.0.0.0");
78 manifest
.SetString(extensions::manifest_keys::kName
, "unused");
79 return extensions::Extension::Create(base::FilePath(),
80 extensions::Manifest::UNPACKED
,
82 extensions::Extension::NO_FLAGS
,
89 class FileSystemProviderServiceTest
: public testing::Test
{
91 FileSystemProviderServiceTest() {}
92 virtual ~FileSystemProviderServiceTest() {}
94 virtual void SetUp() OVERRIDE
{
95 profile_
.reset(new TestingProfile
);
96 user_manager_
= new FakeUserManager();
97 user_manager_
->AddUser(profile_
->GetProfileName());
98 user_manager_enabler_
.reset(new ScopedUserManagerEnabler(user_manager_
));
99 extension_registry_
.reset(
100 new extensions::ExtensionRegistry(profile_
.get()));
101 file_system_provider_service_
.reset(
102 new Service(profile_
.get(), extension_registry_
.get()));
103 file_system_provider_service_
->SetFileSystemFactoryForTests(
104 base::Bind(&FakeProvidedFileSystem::Create
));
105 extension_
= createFakeExtension(kExtensionId
);
108 content::TestBrowserThreadBundle thread_bundle_
;
109 scoped_ptr
<TestingProfile
> profile_
;
110 FakeUserManager
* user_manager_
;
111 scoped_ptr
<ScopedUserManagerEnabler
> user_manager_enabler_
;
112 scoped_ptr
<extensions::ExtensionRegistry
> extension_registry_
;
113 scoped_ptr
<Service
> file_system_provider_service_
;
114 scoped_refptr
<extensions::Extension
> extension_
;
117 TEST_F(FileSystemProviderServiceTest
, MountFileSystem
) {
118 LoggingObserver observer
;
119 file_system_provider_service_
->AddObserver(&observer
);
121 int file_system_id
= file_system_provider_service_
->MountFileSystem(
122 kExtensionId
, kFileSystemName
);
124 EXPECT_LT(0, file_system_id
);
125 ASSERT_EQ(1u, observer
.mounts
.size());
126 EXPECT_EQ(kExtensionId
, observer
.mounts
[0].file_system_info().extension_id());
127 EXPECT_EQ(1, observer
.mounts
[0].file_system_info().file_system_id());
128 base::FilePath expected_mount_path
=
129 util::GetMountPath(profile_
.get(), kExtensionId
, file_system_id
);
130 EXPECT_EQ(expected_mount_path
.AsUTF8Unsafe(),
131 observer
.mounts
[0].file_system_info().mount_path().AsUTF8Unsafe());
132 EXPECT_EQ(kFileSystemName
,
133 observer
.mounts
[0].file_system_info().file_system_name());
134 EXPECT_EQ(base::File::FILE_OK
, observer
.mounts
[0].error());
135 ASSERT_EQ(0u, observer
.unmounts
.size());
137 std::vector
<ProvidedFileSystemInfo
> file_system_info_list
=
138 file_system_provider_service_
->GetProvidedFileSystemInfoList();
139 ASSERT_EQ(1u, file_system_info_list
.size());
141 file_system_provider_service_
->RemoveObserver(&observer
);
144 TEST_F(FileSystemProviderServiceTest
, MountFileSystem_UniqueIds
) {
145 LoggingObserver observer
;
146 file_system_provider_service_
->AddObserver(&observer
);
148 int file_system_first_id
= file_system_provider_service_
->MountFileSystem(
149 kExtensionId
, kFileSystemName
);
150 EXPECT_LT(0, file_system_first_id
);
152 int file_system_second_id
= file_system_provider_service_
->MountFileSystem(
153 kExtensionId
, kFileSystemName
);
154 EXPECT_LT(0, file_system_second_id
);
156 EXPECT_NE(file_system_first_id
, file_system_second_id
);
157 ASSERT_EQ(2u, observer
.mounts
.size());
158 EXPECT_EQ(base::File::FILE_OK
, observer
.mounts
[0].error());
159 EXPECT_EQ(base::File::FILE_OK
, observer
.mounts
[1].error());
161 std::vector
<ProvidedFileSystemInfo
> file_system_info_list
=
162 file_system_provider_service_
->GetProvidedFileSystemInfoList();
163 ASSERT_EQ(2u, file_system_info_list
.size());
165 file_system_provider_service_
->RemoveObserver(&observer
);
168 TEST_F(FileSystemProviderServiceTest
, MountFileSystem_StressTest
) {
169 LoggingObserver observer
;
170 file_system_provider_service_
->AddObserver(&observer
);
172 const size_t kMaxFileSystems
= 16;
173 for (size_t i
= 0; i
< kMaxFileSystems
; ++i
) {
174 int file_system_id
= file_system_provider_service_
->MountFileSystem(
175 kExtensionId
, kFileSystemName
);
176 EXPECT_LT(0, file_system_id
);
178 ASSERT_EQ(kMaxFileSystems
, observer
.mounts
.size());
180 // The next file system is out of limit, and registering it should fail.
181 int file_system_id
= file_system_provider_service_
->MountFileSystem(
182 kExtensionId
, kFileSystemName
);
183 EXPECT_EQ(0, file_system_id
);
185 ASSERT_EQ(kMaxFileSystems
+ 1, observer
.mounts
.size());
186 EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED
,
187 observer
.mounts
[kMaxFileSystems
].error());
189 std::vector
<ProvidedFileSystemInfo
> file_system_info_list
=
190 file_system_provider_service_
->GetProvidedFileSystemInfoList();
191 ASSERT_EQ(kMaxFileSystems
, file_system_info_list
.size());
193 file_system_provider_service_
->RemoveObserver(&observer
);
196 TEST_F(FileSystemProviderServiceTest
, UnmountFileSystem
) {
197 LoggingObserver observer
;
198 file_system_provider_service_
->AddObserver(&observer
);
200 int file_system_id
= file_system_provider_service_
->MountFileSystem(
201 kExtensionId
, kFileSystemName
);
202 EXPECT_LT(0, file_system_id
);
203 ASSERT_EQ(1u, observer
.mounts
.size());
205 const bool result
= file_system_provider_service_
->UnmountFileSystem(
206 kExtensionId
, file_system_id
);
208 ASSERT_EQ(1u, observer
.unmounts
.size());
209 EXPECT_EQ(base::File::FILE_OK
, observer
.unmounts
[0].error());
211 EXPECT_EQ(kExtensionId
,
212 observer
.unmounts
[0].file_system_info().extension_id());
213 EXPECT_EQ(1, observer
.unmounts
[0].file_system_info().file_system_id());
214 base::FilePath expected_mount_path
=
215 util::GetMountPath(profile_
.get(), kExtensionId
, file_system_id
);
217 expected_mount_path
.AsUTF8Unsafe(),
218 observer
.unmounts
[0].file_system_info().mount_path().AsUTF8Unsafe());
219 EXPECT_EQ(kFileSystemName
,
220 observer
.unmounts
[0].file_system_info().file_system_name());
222 std::vector
<ProvidedFileSystemInfo
> file_system_info_list
=
223 file_system_provider_service_
->GetProvidedFileSystemInfoList();
224 ASSERT_EQ(0u, file_system_info_list
.size());
226 file_system_provider_service_
->RemoveObserver(&observer
);
229 TEST_F(FileSystemProviderServiceTest
, UnmountFileSystem_OnExtensionUnload
) {
230 LoggingObserver observer
;
231 file_system_provider_service_
->AddObserver(&observer
);
233 int file_system_id
= file_system_provider_service_
->MountFileSystem(
234 kExtensionId
, kFileSystemName
);
235 EXPECT_LT(0, file_system_id
);
236 ASSERT_EQ(1u, observer
.mounts
.size());
238 // Directly call the observer's method.
239 file_system_provider_service_
->OnExtensionUnloaded(
242 extensions::UnloadedExtensionInfo::REASON_DISABLE
);
244 ASSERT_EQ(1u, observer
.unmounts
.size());
245 EXPECT_EQ(base::File::FILE_OK
, observer
.unmounts
[0].error());
247 EXPECT_EQ(kExtensionId
,
248 observer
.unmounts
[0].file_system_info().extension_id());
249 EXPECT_EQ(1, observer
.unmounts
[0].file_system_info().file_system_id());
250 base::FilePath expected_mount_path
=
251 util::GetMountPath(profile_
.get(), kExtensionId
, file_system_id
);
253 expected_mount_path
.AsUTF8Unsafe(),
254 observer
.unmounts
[0].file_system_info().mount_path().AsUTF8Unsafe());
255 EXPECT_EQ(kFileSystemName
,
256 observer
.unmounts
[0].file_system_info().file_system_name());
258 std::vector
<ProvidedFileSystemInfo
> file_system_info_list
=
259 file_system_provider_service_
->GetProvidedFileSystemInfoList();
260 ASSERT_EQ(0u, file_system_info_list
.size());
262 file_system_provider_service_
->RemoveObserver(&observer
);
265 TEST_F(FileSystemProviderServiceTest
, UnmountFileSystem_WrongExtensionId
) {
266 LoggingObserver observer
;
267 file_system_provider_service_
->AddObserver(&observer
);
269 const std::string kWrongExtensionId
= "helloworldhelloworldhelloworldhe";
271 int file_system_id
= file_system_provider_service_
->MountFileSystem(
272 kExtensionId
, kFileSystemName
);
273 EXPECT_LT(0, file_system_id
);
274 ASSERT_EQ(1u, observer
.mounts
.size());
277 file_system_provider_service_
->GetProvidedFileSystemInfoList().size());
279 const bool result
= file_system_provider_service_
->UnmountFileSystem(
280 kWrongExtensionId
, file_system_id
);
281 EXPECT_FALSE(result
);
282 ASSERT_EQ(1u, observer
.unmounts
.size());
283 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, observer
.unmounts
[0].error());
286 file_system_provider_service_
->GetProvidedFileSystemInfoList().size());
288 std::vector
<ProvidedFileSystemInfo
> file_system_info_list
=
289 file_system_provider_service_
->GetProvidedFileSystemInfoList();
290 ASSERT_EQ(1u, file_system_info_list
.size());
292 file_system_provider_service_
->RemoveObserver(&observer
);
295 } // namespace file_system_provider
296 } // namespace chromeos