Update broken references to image assets
[chromium-blink-merge.git] / chrome / browser / chromeos / file_system_provider / service_unittest.cc
bloba84598c7358e2749e079d51402c8a1b6e85aabd4
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.
5 #include "chrome/browser/chromeos/file_system_provider/service.h"
7 #include <string>
8 #include <vector>
10 #include "base/files/file.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
15 #include "chrome/browser/chromeos/file_system_provider/mount_path_util.h"
16 #include "chrome/browser/chromeos/file_system_provider/observer.h"
17 #include "chrome/browser/chromeos/file_system_provider/provided_file_system_info.h"
18 #include "chrome/browser/chromeos/file_system_provider/registry_interface.h"
19 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
20 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
21 #include "chrome/common/extensions/api/file_system_provider_capabilities/file_system_provider_capabilities_handler.h"
22 #include "chrome/test/base/testing_browser_process.h"
23 #include "chrome/test/base/testing_pref_service_syncable.h"
24 #include "chrome/test/base/testing_profile.h"
25 #include "chrome/test/base/testing_profile_manager.h"
26 #include "components/user_prefs/user_prefs.h"
27 #include "content/public/test/test_browser_thread_bundle.h"
28 #include "extensions/browser/extension_registry.h"
29 #include "extensions/common/extension.h"
30 #include "extensions/common/manifest_constants.h"
31 #include "storage/browser/fileapi/external_mount_points.h"
32 #include "testing/gtest/include/gtest/gtest.h"
34 namespace chromeos {
35 namespace file_system_provider {
36 namespace {
38 const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
39 const char kDisplayName[] = "Camera Pictures";
41 // The dot in the file system ID is there in order to check that saving to
42 // preferences works correctly. File System ID is used as a key in
43 // a base::DictionaryValue, so it has to be stored without path expansion.
44 const char kFileSystemId[] = "camera/pictures/id .!@#$%^&*()_+";
46 // Utility observer, logging events from file_system_provider::Service.
47 class LoggingObserver : public Observer {
48 public:
49 class Event {
50 public:
51 Event(const ProvidedFileSystemInfo& file_system_info,
52 MountContext context,
53 base::File::Error error)
54 : file_system_info_(file_system_info),
55 context_(context),
56 error_(error) {}
57 ~Event() {}
59 const ProvidedFileSystemInfo& file_system_info() const {
60 return file_system_info_;
62 MountContext context() const { return context_; }
63 base::File::Error error() const { return error_; }
65 private:
66 ProvidedFileSystemInfo file_system_info_;
67 MountContext context_;
68 base::File::Error error_;
71 LoggingObserver() {}
72 ~LoggingObserver() override {}
74 // file_system_provider::Observer overrides.
75 void OnProvidedFileSystemMount(const ProvidedFileSystemInfo& file_system_info,
76 MountContext context,
77 base::File::Error error) override {
78 mounts.push_back(Event(file_system_info, context, error));
81 void OnProvidedFileSystemUnmount(
82 const ProvidedFileSystemInfo& file_system_info,
83 base::File::Error error) override {
84 // TODO(mtomasz): Split these events, as mount context doesn't make sense
85 // for unmounting.
86 unmounts.push_back(Event(file_system_info, MOUNT_CONTEXT_USER, error));
89 std::vector<Event> mounts;
90 std::vector<Event> unmounts;
92 DISALLOW_COPY_AND_ASSIGN(LoggingObserver);
95 // Fake implementation of the registry, since it's already tested separately.
96 // For simplicity it can remember at most only one file system.
97 class FakeRegistry : public RegistryInterface {
98 public:
99 FakeRegistry() {}
100 ~FakeRegistry() override {}
102 // RegistryInterface overrides.
103 void RememberFileSystem(const ProvidedFileSystemInfo& file_system_info,
104 const Watchers& watchers) override {
105 file_system_info_.reset(new ProvidedFileSystemInfo(file_system_info));
106 watchers_.reset(new Watchers(watchers));
109 void ForgetFileSystem(const std::string& extension_id,
110 const std::string& file_system_id) override {
111 if (!file_system_info_.get() || !watchers_.get())
112 return;
113 if (file_system_info_->extension_id() == extension_id &&
114 file_system_info_->file_system_id() == file_system_id) {
115 file_system_info_.reset();
116 watchers_.reset();
120 scoped_ptr<RestoredFileSystems> RestoreFileSystems(
121 const std::string& extension_id) override {
122 scoped_ptr<RestoredFileSystems> result(new RestoredFileSystems);
124 if (file_system_info_.get() && watchers_.get()) {
125 RestoredFileSystem restored_file_system;
126 restored_file_system.extension_id = file_system_info_->extension_id();
128 MountOptions options;
129 options.file_system_id = file_system_info_->file_system_id();
130 options.display_name = file_system_info_->display_name();
131 options.writable = file_system_info_->writable();
132 options.supports_notify_tag = file_system_info_->supports_notify_tag();
133 restored_file_system.options = options;
134 restored_file_system.watchers = *watchers_.get();
136 result->push_back(restored_file_system);
139 return result;
142 void UpdateWatcherTag(const ProvidedFileSystemInfo& file_system_info,
143 const Watcher& watcher) override {
144 ASSERT_TRUE(watchers_.get());
145 const Watchers::iterator it =
146 watchers_->find(WatcherKey(watcher.entry_path, watcher.recursive));
147 ASSERT_NE(watchers_->end(), it);
148 it->second.last_tag = watcher.last_tag;
151 ProvidedFileSystemInfo* const file_system_info() const {
152 return file_system_info_.get();
154 Watchers* const watchers() const { return watchers_.get(); }
156 private:
157 scoped_ptr<ProvidedFileSystemInfo> file_system_info_;
158 scoped_ptr<Watchers> watchers_;
160 DISALLOW_COPY_AND_ASSIGN(FakeRegistry);
163 // Creates a fake extension with the specified |extension_id|.
164 scoped_refptr<extensions::Extension> CreateFakeExtension(
165 const std::string& extension_id) {
166 base::DictionaryValue manifest;
167 std::string error;
168 manifest.SetStringWithoutPathExpansion(extensions::manifest_keys::kVersion,
169 "1.0.0.0");
170 manifest.SetStringWithoutPathExpansion(extensions::manifest_keys::kName,
171 "unused");
172 return extensions::Extension::Create(base::FilePath(),
173 extensions::Manifest::UNPACKED,
174 manifest,
175 extensions::Extension::NO_FLAGS,
176 extension_id,
177 &error);
180 } // namespace
182 class FileSystemProviderServiceTest : public testing::Test {
183 protected:
184 FileSystemProviderServiceTest() : profile_(NULL) {}
186 ~FileSystemProviderServiceTest() override {}
188 void SetUp() override {
189 profile_manager_.reset(
190 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
191 ASSERT_TRUE(profile_manager_->SetUp());
192 profile_ = profile_manager_->CreateTestingProfile("test-user@example.com");
193 user_manager_ = new FakeChromeUserManager();
194 user_manager_->AddUser(profile_->GetProfileUserName());
195 user_manager_enabler_.reset(new ScopedUserManagerEnabler(user_manager_));
196 extension_registry_.reset(new extensions::ExtensionRegistry(profile_));
198 service_.reset(new Service(profile_, extension_registry_.get()));
199 service_->SetFileSystemFactoryForTesting(
200 base::Bind(&FakeProvidedFileSystem::Create));
201 extension_ = CreateFakeExtension(kExtensionId);
203 registry_ = new FakeRegistry;
204 // Passes ownership to the service instance.
205 service_->SetRegistryForTesting(make_scoped_ptr(registry_));
207 fake_watcher_.entry_path = base::FilePath(FILE_PATH_LITERAL("/a/b/c"));
208 fake_watcher_.recursive = true;
209 fake_watcher_.last_tag = "hello-world";
212 content::TestBrowserThreadBundle thread_bundle_;
213 scoped_ptr<TestingProfileManager> profile_manager_;
214 TestingProfile* profile_;
215 FakeChromeUserManager* user_manager_;
216 scoped_ptr<ScopedUserManagerEnabler> user_manager_enabler_;
217 scoped_ptr<extensions::ExtensionRegistry> extension_registry_;
218 scoped_ptr<Service> service_;
219 scoped_refptr<extensions::Extension> extension_;
220 FakeRegistry* registry_; // Owned by Service.
221 Watcher fake_watcher_;
224 TEST_F(FileSystemProviderServiceTest, MountFileSystem) {
225 LoggingObserver observer;
226 service_->AddObserver(&observer);
228 EXPECT_EQ(base::File::FILE_OK,
229 service_->MountFileSystem(
230 kExtensionId, MountOptions(kFileSystemId, kDisplayName)));
232 ASSERT_EQ(1u, observer.mounts.size());
233 EXPECT_EQ(kExtensionId, observer.mounts[0].file_system_info().extension_id());
234 EXPECT_EQ(kFileSystemId,
235 observer.mounts[0].file_system_info().file_system_id());
236 base::FilePath expected_mount_path =
237 util::GetMountPath(profile_, kExtensionId, kFileSystemId);
238 EXPECT_EQ(expected_mount_path.AsUTF8Unsafe(),
239 observer.mounts[0].file_system_info().mount_path().AsUTF8Unsafe());
240 EXPECT_EQ(kDisplayName, observer.mounts[0].file_system_info().display_name());
241 EXPECT_FALSE(observer.mounts[0].file_system_info().writable());
242 EXPECT_FALSE(observer.mounts[0].file_system_info().supports_notify_tag());
243 EXPECT_EQ(base::File::FILE_OK, observer.mounts[0].error());
244 EXPECT_EQ(MOUNT_CONTEXT_USER, observer.mounts[0].context());
245 ASSERT_EQ(0u, observer.unmounts.size());
247 std::vector<ProvidedFileSystemInfo> file_system_info_list =
248 service_->GetProvidedFileSystemInfoList();
249 ASSERT_EQ(1u, file_system_info_list.size());
251 service_->RemoveObserver(&observer);
254 TEST_F(FileSystemProviderServiceTest,
255 MountFileSystem_WritableAndSupportsNotifyTag) {
256 LoggingObserver observer;
257 service_->AddObserver(&observer);
259 MountOptions options(kFileSystemId, kDisplayName);
260 options.writable = true;
261 options.supports_notify_tag = true;
262 EXPECT_EQ(base::File::FILE_OK,
263 service_->MountFileSystem(kExtensionId, options));
265 ASSERT_EQ(1u, observer.mounts.size());
266 EXPECT_TRUE(observer.mounts[0].file_system_info().writable());
267 EXPECT_TRUE(observer.mounts[0].file_system_info().supports_notify_tag());
268 ASSERT_EQ(0u, observer.unmounts.size());
269 std::vector<ProvidedFileSystemInfo> file_system_info_list =
270 service_->GetProvidedFileSystemInfoList();
271 ASSERT_EQ(1u, file_system_info_list.size());
273 service_->RemoveObserver(&observer);
276 TEST_F(FileSystemProviderServiceTest, MountFileSystem_UniqueIds) {
277 LoggingObserver observer;
278 service_->AddObserver(&observer);
280 EXPECT_EQ(base::File::FILE_OK,
281 service_->MountFileSystem(
282 kExtensionId, MountOptions(kFileSystemId, kDisplayName)));
283 EXPECT_EQ(base::File::FILE_ERROR_EXISTS,
284 service_->MountFileSystem(
285 kExtensionId, MountOptions(kFileSystemId, kDisplayName)));
287 ASSERT_EQ(2u, observer.mounts.size());
288 EXPECT_EQ(base::File::FILE_OK, observer.mounts[0].error());
289 EXPECT_EQ(base::File::FILE_ERROR_EXISTS, observer.mounts[1].error());
291 std::vector<ProvidedFileSystemInfo> file_system_info_list =
292 service_->GetProvidedFileSystemInfoList();
293 ASSERT_EQ(1u, file_system_info_list.size());
295 service_->RemoveObserver(&observer);
298 TEST_F(FileSystemProviderServiceTest, MountFileSystem_StressTest) {
299 LoggingObserver observer;
300 service_->AddObserver(&observer);
302 const size_t kMaxFileSystems = 16;
303 for (size_t i = 0; i < kMaxFileSystems; ++i) {
304 const std::string file_system_id =
305 std::string("test-") + base::IntToString(i);
306 EXPECT_EQ(base::File::FILE_OK,
307 service_->MountFileSystem(
308 kExtensionId, MountOptions(file_system_id, kDisplayName)));
310 ASSERT_EQ(kMaxFileSystems, observer.mounts.size());
312 // The next file system is out of limit, and registering it should fail.
313 EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED,
314 service_->MountFileSystem(
315 kExtensionId, MountOptions(kFileSystemId, kDisplayName)));
317 ASSERT_EQ(kMaxFileSystems + 1, observer.mounts.size());
318 EXPECT_EQ(base::File::FILE_ERROR_TOO_MANY_OPENED,
319 observer.mounts[kMaxFileSystems].error());
321 std::vector<ProvidedFileSystemInfo> file_system_info_list =
322 service_->GetProvidedFileSystemInfoList();
323 ASSERT_EQ(kMaxFileSystems, file_system_info_list.size());
325 service_->RemoveObserver(&observer);
328 TEST_F(FileSystemProviderServiceTest, UnmountFileSystem) {
329 LoggingObserver observer;
330 service_->AddObserver(&observer);
332 EXPECT_EQ(base::File::FILE_OK,
333 service_->MountFileSystem(
334 kExtensionId, MountOptions(kFileSystemId, kDisplayName)));
335 ASSERT_EQ(1u, observer.mounts.size());
337 EXPECT_EQ(base::File::FILE_OK,
338 service_->UnmountFileSystem(kExtensionId, kFileSystemId,
339 Service::UNMOUNT_REASON_USER));
340 ASSERT_EQ(1u, observer.unmounts.size());
341 EXPECT_EQ(base::File::FILE_OK, observer.unmounts[0].error());
343 EXPECT_EQ(kExtensionId,
344 observer.unmounts[0].file_system_info().extension_id());
345 EXPECT_EQ(kFileSystemId,
346 observer.unmounts[0].file_system_info().file_system_id());
348 std::vector<ProvidedFileSystemInfo> file_system_info_list =
349 service_->GetProvidedFileSystemInfoList();
350 ASSERT_EQ(0u, file_system_info_list.size());
352 service_->RemoveObserver(&observer);
355 TEST_F(FileSystemProviderServiceTest, UnmountFileSystem_OnExtensionUnload) {
356 LoggingObserver observer;
357 service_->AddObserver(&observer);
359 EXPECT_EQ(base::File::FILE_OK,
360 service_->MountFileSystem(
361 kExtensionId, MountOptions(kFileSystemId, kDisplayName)));
362 ASSERT_EQ(1u, observer.mounts.size());
364 // Directly call the observer's method.
365 service_->OnExtensionUnloaded(
366 profile_,
367 extension_.get(),
368 extensions::UnloadedExtensionInfo::REASON_DISABLE);
370 ASSERT_EQ(1u, observer.unmounts.size());
371 EXPECT_EQ(base::File::FILE_OK, observer.unmounts[0].error());
373 EXPECT_EQ(kExtensionId,
374 observer.unmounts[0].file_system_info().extension_id());
375 EXPECT_EQ(kFileSystemId,
376 observer.unmounts[0].file_system_info().file_system_id());
378 std::vector<ProvidedFileSystemInfo> file_system_info_list =
379 service_->GetProvidedFileSystemInfoList();
380 ASSERT_EQ(0u, file_system_info_list.size());
382 service_->RemoveObserver(&observer);
385 TEST_F(FileSystemProviderServiceTest, UnmountFileSystem_WrongExtensionId) {
386 LoggingObserver observer;
387 service_->AddObserver(&observer);
389 const std::string kWrongExtensionId = "helloworldhelloworldhelloworldhe";
391 EXPECT_EQ(base::File::FILE_OK,
392 service_->MountFileSystem(
393 kExtensionId, MountOptions(kFileSystemId, kDisplayName)));
394 ASSERT_EQ(1u, observer.mounts.size());
395 ASSERT_EQ(1u, service_->GetProvidedFileSystemInfoList().size());
397 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
398 service_->UnmountFileSystem(kWrongExtensionId, kFileSystemId,
399 Service::UNMOUNT_REASON_USER));
400 ASSERT_EQ(1u, observer.unmounts.size());
401 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, observer.unmounts[0].error());
402 ASSERT_EQ(1u, service_->GetProvidedFileSystemInfoList().size());
404 std::vector<ProvidedFileSystemInfo> file_system_info_list =
405 service_->GetProvidedFileSystemInfoList();
406 ASSERT_EQ(1u, file_system_info_list.size());
408 service_->RemoveObserver(&observer);
411 TEST_F(FileSystemProviderServiceTest, RestoreFileSystem_OnExtensionLoad) {
412 LoggingObserver observer;
413 service_->AddObserver(&observer);
415 // Remember a fake file system first in order to be able to restore it.
416 MountOptions options(kFileSystemId, kDisplayName);
417 options.supports_notify_tag = true;
418 ProvidedFileSystemInfo file_system_info(
419 kExtensionId, options, base::FilePath(FILE_PATH_LITERAL("/a/b/c")),
420 false /* configurable */, false /* watchable */, extensions::SOURCE_FILE);
421 Watchers fake_watchers;
422 fake_watchers[WatcherKey(fake_watcher_.entry_path, fake_watcher_.recursive)] =
423 fake_watcher_;
424 registry_->RememberFileSystem(file_system_info, fake_watchers);
426 EXPECT_EQ(0u, observer.mounts.size());
428 // Directly call the observer's method.
429 service_->OnExtensionLoaded(profile_, extension_.get());
431 ASSERT_EQ(1u, observer.mounts.size());
432 EXPECT_EQ(base::File::FILE_OK, observer.mounts[0].error());
433 EXPECT_EQ(MOUNT_CONTEXT_RESTORE, observer.mounts[0].context());
435 EXPECT_EQ(file_system_info.extension_id(),
436 observer.mounts[0].file_system_info().extension_id());
437 EXPECT_EQ(file_system_info.file_system_id(),
438 observer.mounts[0].file_system_info().file_system_id());
439 EXPECT_EQ(file_system_info.writable(),
440 observer.mounts[0].file_system_info().watchable());
441 EXPECT_EQ(file_system_info.supports_notify_tag(),
442 observer.mounts[0].file_system_info().supports_notify_tag());
444 std::vector<ProvidedFileSystemInfo> file_system_info_list =
445 service_->GetProvidedFileSystemInfoList();
446 ASSERT_EQ(1u, file_system_info_list.size());
448 ProvidedFileSystemInterface* const file_system =
449 service_->GetProvidedFileSystem(kExtensionId, kFileSystemId);
450 ASSERT_TRUE(file_system);
452 const Watchers* const watchers = file_system->GetWatchers();
453 ASSERT_TRUE(watchers);
454 ASSERT_EQ(1u, watchers->size());
456 const Watchers::const_iterator restored_watcher_it = watchers->find(
457 WatcherKey(fake_watcher_.entry_path, fake_watcher_.recursive));
458 ASSERT_NE(watchers->end(), restored_watcher_it);
460 EXPECT_EQ(fake_watcher_.entry_path, restored_watcher_it->second.entry_path);
461 EXPECT_EQ(fake_watcher_.recursive, restored_watcher_it->second.recursive);
462 EXPECT_EQ(fake_watcher_.last_tag, restored_watcher_it->second.last_tag);
464 service_->RemoveObserver(&observer);
467 TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnMount) {
468 LoggingObserver observer;
469 service_->AddObserver(&observer);
471 EXPECT_FALSE(registry_->file_system_info());
472 EXPECT_FALSE(registry_->watchers());
474 EXPECT_EQ(base::File::FILE_OK,
475 service_->MountFileSystem(
476 kExtensionId, MountOptions(kFileSystemId, kDisplayName)));
477 ASSERT_EQ(1u, observer.mounts.size());
479 ASSERT_TRUE(registry_->file_system_info());
480 EXPECT_EQ(kExtensionId, registry_->file_system_info()->extension_id());
481 EXPECT_EQ(kFileSystemId, registry_->file_system_info()->file_system_id());
482 EXPECT_EQ(kDisplayName, registry_->file_system_info()->display_name());
483 EXPECT_FALSE(registry_->file_system_info()->writable());
484 EXPECT_FALSE(registry_->file_system_info()->configurable());
485 EXPECT_FALSE(registry_->file_system_info()->watchable());
486 EXPECT_FALSE(registry_->file_system_info()->supports_notify_tag());
487 ASSERT_TRUE(registry_->watchers());
489 service_->RemoveObserver(&observer);
492 TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnUnmountOnShutdown) {
493 LoggingObserver observer;
494 service_->AddObserver(&observer);
497 EXPECT_FALSE(registry_->file_system_info());
498 EXPECT_FALSE(registry_->watchers());
499 EXPECT_EQ(base::File::FILE_OK,
500 service_->MountFileSystem(
501 kExtensionId, MountOptions(kFileSystemId, kDisplayName)));
503 EXPECT_EQ(1u, observer.mounts.size());
504 EXPECT_TRUE(registry_->file_system_info());
505 EXPECT_TRUE(registry_->watchers());
509 EXPECT_EQ(base::File::FILE_OK,
510 service_->UnmountFileSystem(kExtensionId, kFileSystemId,
511 Service::UNMOUNT_REASON_SHUTDOWN));
513 EXPECT_EQ(1u, observer.unmounts.size());
514 EXPECT_TRUE(registry_->file_system_info());
515 EXPECT_TRUE(registry_->watchers());
518 service_->RemoveObserver(&observer);
521 TEST_F(FileSystemProviderServiceTest, RememberFileSystem_OnUnmountByUser) {
522 LoggingObserver observer;
523 service_->AddObserver(&observer);
526 EXPECT_FALSE(registry_->file_system_info());
527 EXPECT_FALSE(registry_->watchers());
528 EXPECT_EQ(base::File::FILE_OK,
529 service_->MountFileSystem(
530 kExtensionId, MountOptions(kFileSystemId, kDisplayName)));
532 EXPECT_EQ(1u, observer.mounts.size());
533 EXPECT_TRUE(registry_->file_system_info());
534 EXPECT_TRUE(registry_->watchers());
538 EXPECT_EQ(base::File::FILE_OK,
539 service_->UnmountFileSystem(kExtensionId, kFileSystemId,
540 Service::UNMOUNT_REASON_USER));
542 EXPECT_EQ(1u, observer.unmounts.size());
543 EXPECT_FALSE(registry_->file_system_info());
544 EXPECT_FALSE(registry_->watchers());
547 service_->RemoveObserver(&observer);
550 } // namespace file_system_provider
551 } // namespace chromeos