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(kExtensionId,
140 "Testing File System",
141 false /* writable */);
143 const ProvidedFileSystemInfo& file_system_info =
144 service->GetProvidedFileSystem(kExtensionId, kFileSystemId)
145 ->GetFileSystemInfo();
146 const std::string mount_point_name =
147 file_system_info.mount_path().BaseName().AsUTF8Unsafe();
150 CreateFileSystemURL(mount_point_name,
151 base::FilePath::FromUTF8Unsafe(
152 kFakeFilePath + 1 /* No leading slash. */));
153 ASSERT_TRUE(file_url_.is_valid());
154 directory_url_ = CreateFileSystemURL(
155 mount_point_name, base::FilePath::FromUTF8Unsafe("hello"));
156 ASSERT_TRUE(directory_url_.is_valid());
157 root_url_ = CreateFileSystemURL(mount_point_name, base::FilePath());
158 ASSERT_TRUE(root_url_.is_valid());
161 virtual void TearDown() OVERRIDE {
162 // Setting the testing factory to NULL will destroy the created service
163 // associated with the testing profile.
164 ServiceFactory::GetInstance()->SetTestingFactory(profile_, NULL);
167 scoped_ptr<storage::FileSystemOperationContext> CreateOperationContext() {
168 return make_scoped_ptr(
169 new storage::FileSystemOperationContext(file_system_context_.get()));
172 content::TestBrowserThreadBundle thread_bundle_;
173 base::ScopedTempDir data_dir_;
174 scoped_ptr<TestingProfileManager> profile_manager_;
175 TestingProfile* profile_; // Owned by TestingProfileManager.
176 scoped_ptr<storage::AsyncFileUtil> async_file_util_;
177 scoped_refptr<storage::FileSystemContext> file_system_context_;
178 storage::FileSystemURL file_url_;
179 storage::FileSystemURL directory_url_;
180 storage::FileSystemURL root_url_;
183 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_Create) {
186 async_file_util_->CreateOrOpen(
187 CreateOperationContext(),
189 base::File::FLAG_CREATE,
190 base::Bind(&EventLogger::OnCreateOrOpen, base::Unretained(&logger)));
192 ASSERT_TRUE(logger.result());
193 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
196 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_CreateAlways) {
199 async_file_util_->CreateOrOpen(
200 CreateOperationContext(),
202 base::File::FLAG_CREATE_ALWAYS,
203 base::Bind(&EventLogger::OnCreateOrOpen, base::Unretained(&logger)));
205 ASSERT_TRUE(logger.result());
206 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
209 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_OpenAlways) {
212 async_file_util_->CreateOrOpen(
213 CreateOperationContext(),
215 base::File::FLAG_OPEN_ALWAYS,
216 base::Bind(&EventLogger::OnCreateOrOpen, base::Unretained(&logger)));
218 ASSERT_TRUE(logger.result());
219 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
222 TEST_F(FileSystemProviderProviderAsyncFileUtilTest,
223 CreateOrOpen_OpenTruncated) {
226 async_file_util_->CreateOrOpen(
227 CreateOperationContext(),
229 base::File::FLAG_OPEN_TRUNCATED,
230 base::Bind(&EventLogger::OnCreateOrOpen, base::Unretained(&logger)));
232 ASSERT_TRUE(logger.result());
233 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
236 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateOrOpen_Open) {
239 async_file_util_->CreateOrOpen(
240 CreateOperationContext(),
242 base::File::FLAG_OPEN,
243 base::Bind(&EventLogger::OnCreateOrOpen, base::Unretained(&logger)));
245 ASSERT_TRUE(logger.result());
246 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, *logger.result());
249 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, EnsureFileExists) {
252 async_file_util_->EnsureFileExists(
253 CreateOperationContext(),
255 base::Bind(&EventLogger::OnEnsureFileExists, base::Unretained(&logger)));
256 base::RunLoop().RunUntilIdle();
258 ASSERT_TRUE(logger.result());
259 EXPECT_EQ(base::File::FILE_OK, *logger.result());
262 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateDirectory) {
265 async_file_util_->CreateDirectory(
266 CreateOperationContext(),
270 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
271 base::RunLoop().RunUntilIdle();
273 ASSERT_TRUE(logger.result());
274 EXPECT_EQ(base::File::FILE_OK, *logger.result());
277 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, GetFileInfo) {
280 async_file_util_->GetFileInfo(
281 CreateOperationContext(),
283 base::Bind(&EventLogger::OnGetFileInfo, base::Unretained(&logger)));
284 base::RunLoop().RunUntilIdle();
286 ASSERT_TRUE(logger.result());
287 EXPECT_EQ(base::File::FILE_OK, *logger.result());
290 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, ReadDirectory) {
293 async_file_util_->ReadDirectory(
294 CreateOperationContext(),
296 base::Bind(&EventLogger::OnReadDirectory, base::Unretained(&logger)));
297 base::RunLoop().RunUntilIdle();
299 ASSERT_TRUE(logger.result());
300 EXPECT_EQ(base::File::FILE_OK, *logger.result());
303 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Touch) {
306 async_file_util_->Touch(
307 CreateOperationContext(),
309 base::Time(), // last_modified_time
310 base::Time(), // last_access_time
311 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
313 ASSERT_TRUE(logger.result());
314 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
317 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, Truncate) {
320 async_file_util_->Truncate(
321 CreateOperationContext(),
324 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
325 base::RunLoop().RunUntilIdle();
327 ASSERT_TRUE(logger.result());
328 EXPECT_EQ(base::File::FILE_OK, *logger.result());
331 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CopyFileLocal) {
334 async_file_util_->CopyFileLocal(
335 CreateOperationContext(),
336 file_url_, // src_url
337 file_url_, // dst_url
338 storage::FileSystemOperation::OPTION_NONE,
339 base::Bind(&EventLogger::OnCopyFileProgress, base::Unretained(&logger)),
340 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
341 base::RunLoop().RunUntilIdle();
343 ASSERT_TRUE(logger.result());
344 EXPECT_EQ(base::File::FILE_OK, *logger.result());
347 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, MoveFileLocal) {
350 async_file_util_->MoveFileLocal(
351 CreateOperationContext(),
352 file_url_, // src_url
353 file_url_, // dst_url
354 storage::FileSystemOperation::OPTION_NONE,
355 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
356 base::RunLoop().RunUntilIdle();
358 ASSERT_TRUE(logger.result());
359 EXPECT_EQ(base::File::FILE_OK, *logger.result());
362 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CopyInForeignFile) {
365 async_file_util_->CopyInForeignFile(
366 CreateOperationContext(),
367 base::FilePath(), // src_file_path
368 file_url_, // dst_url
369 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
371 ASSERT_TRUE(logger.result());
372 EXPECT_EQ(base::File::FILE_ERROR_ACCESS_DENIED, *logger.result());
375 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteFile) {
378 async_file_util_->DeleteFile(
379 CreateOperationContext(),
381 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
382 base::RunLoop().RunUntilIdle();
384 ASSERT_TRUE(logger.result());
385 EXPECT_EQ(base::File::FILE_OK, *logger.result());
388 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteDirectory) {
391 async_file_util_->DeleteDirectory(
392 CreateOperationContext(),
394 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
395 base::RunLoop().RunUntilIdle();
397 ASSERT_TRUE(logger.result());
398 EXPECT_EQ(base::File::FILE_OK, *logger.result());
401 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, DeleteRecursively) {
404 async_file_util_->DeleteRecursively(
405 CreateOperationContext(),
407 base::Bind(&EventLogger::OnStatus, base::Unretained(&logger)));
408 base::RunLoop().RunUntilIdle();
410 ASSERT_TRUE(logger.result());
411 EXPECT_EQ(base::File::FILE_OK, *logger.result());
414 TEST_F(FileSystemProviderProviderAsyncFileUtilTest, CreateSnapshotFile) {
417 async_file_util_->CreateSnapshotFile(
418 CreateOperationContext(),
420 base::Bind(&EventLogger::OnCreateSnapshotFile,
421 base::Unretained(&logger)));
423 ASSERT_TRUE(logger.result());
424 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, *logger.result());
427 } // namespace file_system_provider
428 } // namespace chromeos