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/fileapi/provider_async_file_util.h"
10 #include "base/files/file.h"
11 #include "base/files/file_path.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/run_loop.h"
16 #include "chrome/browser/chromeos/file_system_provider/fake_provided_file_system.h"
17 #include "chrome/browser/chromeos/file_system_provider/service.h"
18 #include "chrome/browser/chromeos/file_system_provider/service_factory.h"
19 #include "chrome/test/base/testing_browser_process.h"
20 #include "chrome/test/base/testing_profile.h"
21 #include "chrome/test/base/testing_profile_manager.h"
22 #include "content/public/test/test_browser_thread_bundle.h"
23 #include "content/public/test/test_file_system_context.h"
24 #include "extensions/browser/extension_registry.h"
25 #include "storage/browser/fileapi/async_file_util.h"
26 #include "storage/browser/fileapi/external_mount_points.h"
27 #include "storage/browser/fileapi/file_system_context.h"
28 #include "storage/browser/fileapi/file_system_url.h"
29 #include "storage/common/blob/shareable_file_reference.h"
30 #include "testing/gtest/include/gtest/gtest.h"
33 namespace file_system_provider {
36 const char kExtensionId[] = "mbflcebpggnecokmikipoihdbecnjfoj";
37 const char kFileSystemId[] = "testing-file-system";
39 // Logs callbacks invocations on the tested operations.
40 // TODO(mtomasz): Store and verify more arguments, once the operations return
41 // anything else than just an error.
45 virtual ~EventLogger() {}
47 void OnStatus(base::File::Error error) {
48 result_.reset(new base::File::Error(error));
51 void OnCreateOrOpen(base::File file,
52 const base::Closure& on_close_callback) {
54 result_.reset(new base::File::Error(base::File::FILE_OK));
56 result_.reset(new base::File::Error(file.error_details()));
59 void OnEnsureFileExists(base::File::Error error, bool created) {
60 result_.reset(new base::File::Error(error));
63 void OnGetFileInfo(base::File::Error error,
64 const base::File::Info& file_info) {
65 result_.reset(new base::File::Error(error));
68 void OnReadDirectory(base::File::Error error,
69 const storage::AsyncFileUtil::EntryList& file_list,
71 result_.reset(new base::File::Error(error));
74 void OnCreateSnapshotFile(
75 base::File::Error error,
76 const base::File::Info& file_info,
77 const base::FilePath& platform_path,
78 const scoped_refptr<storage::ShareableFileReference>& file_ref) {
79 result_.reset(new base::File::Error(error));
82 void OnCopyFileProgress(int64 size) {}
84 base::File::Error* result() { return result_.get(); }
87 scoped_ptr<base::File::Error> result_;
88 DISALLOW_COPY_AND_ASSIGN(EventLogger);
91 // Creates a cracked FileSystemURL for tests.
92 storage::FileSystemURL CreateFileSystemURL(const std::string& mount_point_name,
93 const base::FilePath& file_path) {
94 const std::string origin = std::string("chrome-extension://") + kExtensionId;
95 const storage::ExternalMountPoints* const mount_points =
96 storage::ExternalMountPoints::GetSystemInstance();
97 return mount_points->CreateCrackedFileSystemURL(
99 storage::kFileSystemTypeExternal,
100 base::FilePath::FromUTF8Unsafe(mount_point_name).Append(file_path));
103 // Creates a Service instance. Used to be able to destroy the service in
105 KeyedService* CreateService(content::BrowserContext* context) {
106 return new Service(Profile::FromBrowserContext(context),
107 extensions::ExtensionRegistry::Get(context));
112 // Tests in this file are very lightweight and just test integration between
113 // AsyncFileUtil and ProvideFileSystemInterface. Currently it tests if not
114 // implemented operations return a correct error code. For not allowed
115 // operations it is FILE_ERROR_ACCESS_DENIED, and for not implemented the error
116 // is FILE_ERROR_INVALID_OPERATION.
117 class FileSystemProviderProviderAsyncFileUtilTest : public testing::Test {
119 FileSystemProviderProviderAsyncFileUtilTest() {}
120 virtual ~FileSystemProviderProviderAsyncFileUtilTest() {}
122 virtual void SetUp() override {
123 ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
124 profile_manager_.reset(
125 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
126 ASSERT_TRUE(profile_manager_->SetUp());
127 profile_ = profile_manager_->CreateTestingProfile("testing-profile");
128 async_file_util_.reset(new internal::ProviderAsyncFileUtil);
130 file_system_context_ =
131 content::CreateFileSystemContextForTesting(NULL, data_dir_.path());
133 ServiceFactory::GetInstance()->SetTestingFactory(profile_, &CreateService);
134 Service* service = Service::Get(profile_); // Owned by its factory.
135 service->SetFileSystemFactoryForTesting(
136 base::Bind(&FakeProvidedFileSystem::Create));
138 const bool result = service->MountFileSystem(
139 kExtensionId, MountOptions(kFileSystemId, "Testing File System"));
141 const ProvidedFileSystemInfo& file_system_info =
142 service->GetProvidedFileSystem(kExtensionId, kFileSystemId)
143 ->GetFileSystemInfo();
144 const std::string mount_point_name =
145 file_system_info.mount_path().BaseName().AsUTF8Unsafe();
148 CreateFileSystemURL(mount_point_name,
149 base::FilePath::FromUTF8Unsafe(
150 kFakeFilePath + 1 /* No leading slash. */));
151 ASSERT_TRUE(file_url_.is_valid());
152 directory_url_ = CreateFileSystemURL(
153 mount_point_name, base::FilePath::FromUTF8Unsafe("hello"));
154 ASSERT_TRUE(directory_url_.is_valid());
155 root_url_ = CreateFileSystemURL(mount_point_name, base::FilePath());
156 ASSERT_TRUE(root_url_.is_valid());
159 virtual void TearDown() override {
160 // Setting the testing factory to NULL will destroy the created service
161 // associated with the testing profile.
162 ServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL);
165 scoped_ptr<storage::FileSystemOperationContext> CreateOperationContext() {
166 return make_scoped_ptr(
167 new storage::FileSystemOperationContext(file_system_context_.get()));
170 content::TestBrowserThreadBundle thread_bundle_;
171 base::ScopedTempDir data_dir_;
172 scoped_ptr<TestingProfileManager> profile_manager_;
173 TestingProfile* profile_; // Owned by TestingProfileManager.
174 scoped_ptr<storage::AsyncFileUtil> async_file_util_;
175 scoped_refptr<storage::FileSystemContext> file_system_context_;
176 storage::FileSystemURL file_url_;
177 storage::FileSystemURL directory_url_;
178 storage::FileSystemURL root_url_;
181 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_Create) {
184 async_file_util_->CreateOrOpen(
185 CreateOperationContext(),
187 base::File::FLAG_CREATE,
188 base::Bind(&EventLogger::OnCreateOrOpen, base::Unretained(&logger)));
190 ASSERT_TRUE(logger.result());
191 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
194 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_CreateAlways) {
197 async_file_util_->CreateOrOpen(
198 CreateOperationContext(),
200 base::File::FLAG_CREATE_ALWAYS,
201 base::Bind(&EventLogger::OnCreateOrOpen, base::Unretained(&logger)));
203 ASSERT_TRUE(logger.result());
204 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
207 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_OpenAlways) {
210 async_file_util_->CreateOrOpen(
211 CreateOperationContext(),
213 base::File::FLAG_OPEN_ALWAYS,
214 base::Bind(&EventLogger::OnCreateOrOpen, base::Unretained(&logger)));
216 ASSERT_TRUE(logger.result());
217 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
220 TEST_F(FileSystemProviderProviderAsyncFileUtilTest,
221 CreateOrOpen_OpenTruncated) {
224 async_file_util_->CreateOrOpen(
225 CreateOperationContext(),
227 base::File::FLAG_OPEN_TRUNCATED,
228 base::Bind(&EventLogger::OnCreateOrOpen, base::Unretained(&logger)));
230 ASSERT_TRUE(logger.result());
231 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
234 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_Open) {
237 async_file_util_->CreateOrOpen(
238 CreateOperationContext(),
240 base::File::FLAG_OPEN,
241 base::Bind(&EventLogger::OnCreateOrOpen, base::Unretained(&logger)));
243 ASSERT_TRUE(logger.result());
244 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, *logger.result());
247 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, EnsureFileExists) {
250 async_file_util_->EnsureFileExists(
251 CreateOperationContext(),
253 base::Bind(&EventLogger::OnEnsureFileExists, base::Unretained(&logger)));
254 base::RunLoop().RunUntilIdle();
256 ASSERT_TRUE(logger.result());
257 EXPECT_EQ(base::File::FILE_OK, *logger.result());
260 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateDirectory) {
263 async_file_util_->CreateDirectory(
264 CreateOperationContext(),
268 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
269 base::RunLoop().RunUntilIdle();
271 ASSERT_TRUE(logger.result());
272 EXPECT_EQ(base::File::FILE_OK, *logger.result());
275 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, GetFileInfo) {
278 async_file_util_->GetFileInfo(
279 CreateOperationContext(),
281 base::Bind(&EventLogger::OnGetFileInfo, base::Unretained(&logger)));
282 base::RunLoop().RunUntilIdle();
284 ASSERT_TRUE(logger.result());
285 EXPECT_EQ(base::File::FILE_OK, *logger.result());
288 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, ReadDirectory) {
291 async_file_util_->ReadDirectory(
292 CreateOperationContext(),
294 base::Bind(&EventLogger::OnReadDirectory, base::Unretained(&logger)));
295 base::RunLoop().RunUntilIdle();
297 ASSERT_TRUE(logger.result());
298 EXPECT_EQ(base::File::FILE_OK, *logger.result());
301 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Touch) {
304 async_file_util_->Touch(
305 CreateOperationContext(),
307 base::Time(), // last_modified_time
308 base::Time(), // last_access_time
309 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
311 ASSERT_TRUE(logger.result());
312 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
315 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Truncate) {
318 async_file_util_->Truncate(
319 CreateOperationContext(),
322 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
323 base::RunLoop().RunUntilIdle();
325 ASSERT_TRUE(logger.result());
326 EXPECT_EQ(base::File::FILE_OK, *logger.result());
329 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CopyFileLocal) {
332 async_file_util_->CopyFileLocal(
333 CreateOperationContext(),
334 file_url_, // src_url
335 file_url_, // dst_url
336 storage::FileSystemOperation::OPTION_NONE,
337 base::Bind(&EventLogger::OnCopyFileProgress, base::Unretained(&logger)),
338 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
339 base::RunLoop().RunUntilIdle();
341 ASSERT_TRUE(logger.result());
342 EXPECT_EQ(base::File::FILE_OK, *logger.result());
345 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, MoveFileLocal) {
348 async_file_util_->MoveFileLocal(
349 CreateOperationContext(),
350 file_url_, // src_url
351 file_url_, // dst_url
352 storage::FileSystemOperation::OPTION_NONE,
353 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
354 base::RunLoop().RunUntilIdle();
356 ASSERT_TRUE(logger.result());
357 EXPECT_EQ(base::File::FILE_OK, *logger.result());
360 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CopyInForeignFile) {
363 async_file_util_->CopyInForeignFile(
364 CreateOperationContext(),
365 base::FilePath(), // src_file_path
366 file_url_, // dst_url
367 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
369 ASSERT_TRUE(logger.result());
370 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
373 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteFile) {
376 async_file_util_->DeleteFile(
377 CreateOperationContext(),
379 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
380 base::RunLoop().RunUntilIdle();
382 ASSERT_TRUE(logger.result());
383 EXPECT_EQ(base::File::FILE_OK, *logger.result());
386 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteDirectory) {
389 async_file_util_->DeleteDirectory(
390 CreateOperationContext(),
392 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
393 base::RunLoop().RunUntilIdle();
395 ASSERT_TRUE(logger.result());
396 EXPECT_EQ(base::File::FILE_OK, *logger.result());
399 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteRecursively) {
402 async_file_util_->DeleteRecursively(
403 CreateOperationContext(),
405 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
406 base::RunLoop().RunUntilIdle();
408 ASSERT_TRUE(logger.result());
409 EXPECT_EQ(base::File::FILE_OK, *logger.result());
412 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateSnapshotFile) {
415 async_file_util_->CreateSnapshotFile(
416 CreateOperationContext(),
418 base::Bind(&EventLogger::OnCreateSnapshotFile,
419 base::Unretained(&logger)));
421 ASSERT_TRUE(logger.result());
422 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, *logger.result());
425 } // namespace file_system_provider
426 } // namespace chromeos