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 "webkit/browser/fileapi/file_system_operation_impl.h"
8 #include "base/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/run_loop.h"
14 #include "base/strings/stringprintf.h"
15 #include "content/browser/fileapi/mock_file_change_observer.h"
16 #include "content/public/test/async_file_test_helper.h"
17 #include "content/public/test/sandbox_file_system_test_helper.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 #include "webkit/browser/fileapi/file_system_context.h"
21 #include "webkit/browser/fileapi/file_system_file_util.h"
22 #include "webkit/browser/fileapi/file_system_operation_context.h"
23 #include "webkit/browser/fileapi/file_system_operation_runner.h"
24 #include "webkit/browser/fileapi/sandbox_file_system_backend.h"
25 #include "webkit/browser/quota/mock_quota_manager.h"
26 #include "webkit/browser/quota/mock_quota_manager_proxy.h"
27 #include "webkit/browser/quota/quota_manager.h"
28 #include "webkit/browser/quota/quota_manager_proxy.h"
29 #include "webkit/common/blob/shareable_file_reference.h"
30 #include "webkit/common/fileapi/file_system_util.h"
32 using content::AsyncFileTestHelper
;
33 using fileapi::FileSystemOperation
;
34 using fileapi::FileSystemOperationContext
;
35 using fileapi::FileSystemOperationRunner
;
36 using fileapi::FileSystemURL
;
37 using quota::QuotaManager
;
38 using quota::QuotaManagerProxy
;
39 using webkit_blob::ShareableFileReference
;
45 const int kFileOperationStatusNotSet
= 1;
47 void AssertFileErrorEq(const tracked_objects::Location
& from_here
,
48 base::File::Error expected
,
49 base::File::Error actual
) {
50 ASSERT_EQ(expected
, actual
) << from_here
.ToString();
55 // Test class for FileSystemOperationImpl.
56 class FileSystemOperationImplTest
57 : public testing::Test
{
59 FileSystemOperationImplTest()
60 : status_(kFileOperationStatusNotSet
),
61 weak_factory_(this) {}
64 virtual void SetUp() OVERRIDE
{
65 EXPECT_TRUE(base_
.CreateUniqueTempDir());
66 change_observers_
= fileapi::MockFileChangeObserver::CreateList(
69 base::FilePath base_dir
= base_
.path().AppendASCII("filesystem");
71 new quota::MockQuotaManager(false /* is_incognito */,
73 base::MessageLoopProxy::current().get(),
74 base::MessageLoopProxy::current().get(),
75 NULL
/* special storage policy */);
76 quota_manager_proxy_
= new quota::MockQuotaManagerProxy(
77 quota_manager(), base::MessageLoopProxy::current().get());
78 sandbox_file_system_
.SetUp(base_dir
, quota_manager_proxy_
.get());
79 sandbox_file_system_
.AddFileChangeObserver(&change_observer_
);
82 virtual void TearDown() OVERRIDE
{
83 // Let the client go away before dropping a ref of the quota manager proxy.
84 quota_manager_proxy()->SimulateQuotaManagerDestroyed();
85 quota_manager_
= NULL
;
86 quota_manager_proxy_
= NULL
;
87 sandbox_file_system_
.TearDown();
90 FileSystemOperationRunner
* operation_runner() {
91 return sandbox_file_system_
.operation_runner();
94 int status() const { return status_
; }
95 const base::File::Info
& info() const { return info_
; }
96 const base::FilePath
& path() const { return path_
; }
97 const std::vector
<fileapi::DirectoryEntry
>& entries() const {
101 const ShareableFileReference
* shareable_file_ref() const {
102 return shareable_file_ref_
.get();
105 quota::MockQuotaManager
* quota_manager() {
106 return static_cast<quota::MockQuotaManager
*>(quota_manager_
.get());
109 quota::MockQuotaManagerProxy
* quota_manager_proxy() {
110 return static_cast<quota::MockQuotaManagerProxy
*>(
111 quota_manager_proxy_
.get());
114 fileapi::FileSystemFileUtil
* file_util() {
115 return sandbox_file_system_
.file_util();
118 fileapi::MockFileChangeObserver
* change_observer() {
119 return &change_observer_
;
122 scoped_ptr
<FileSystemOperationContext
> NewContext() {
123 FileSystemOperationContext
* context
=
124 sandbox_file_system_
.NewOperationContext();
125 // Grant enough quota for all test cases.
126 context
->set_allowed_bytes_growth(1000000);
127 return make_scoped_ptr(context
);
130 FileSystemURL
URLForPath(const std::string
& path
) const {
131 return sandbox_file_system_
.CreateURLFromUTF8(path
);
134 base::FilePath
PlatformPath(const std::string
& path
) {
135 return sandbox_file_system_
.GetLocalPath(
136 base::FilePath::FromUTF8Unsafe(path
));
139 bool FileExists(const std::string
& path
) {
140 return AsyncFileTestHelper::FileExists(
141 sandbox_file_system_
.file_system_context(), URLForPath(path
),
142 AsyncFileTestHelper::kDontCheckSize
);
145 bool DirectoryExists(const std::string
& path
) {
146 return AsyncFileTestHelper::DirectoryExists(
147 sandbox_file_system_
.file_system_context(), URLForPath(path
));
150 FileSystemURL
CreateFile(const std::string
& path
) {
151 FileSystemURL url
= URLForPath(path
);
152 bool created
= false;
153 EXPECT_EQ(base::File::FILE_OK
,
154 file_util()->EnsureFileExists(NewContext().get(),
156 EXPECT_TRUE(created
);
160 FileSystemURL
CreateDirectory(const std::string
& path
) {
161 FileSystemURL url
= URLForPath(path
);
162 EXPECT_EQ(base::File::FILE_OK
,
163 file_util()->CreateDirectory(NewContext().get(), url
,
164 false /* exclusive */, true));
168 int64
GetFileSize(const std::string
& path
) {
169 base::File::Info info
;
170 EXPECT_TRUE(base::GetFileInfo(PlatformPath(path
), &info
));
174 // Callbacks for recording test results.
175 FileSystemOperation::StatusCallback
RecordStatusCallback() {
176 return base::Bind(&FileSystemOperationImplTest::DidFinish
,
177 weak_factory_
.GetWeakPtr());
180 FileSystemOperation::ReadDirectoryCallback
181 RecordReadDirectoryCallback() {
182 return base::Bind(&FileSystemOperationImplTest::DidReadDirectory
,
183 weak_factory_
.GetWeakPtr());
186 FileSystemOperation::GetMetadataCallback
RecordMetadataCallback() {
187 return base::Bind(&FileSystemOperationImplTest::DidGetMetadata
,
188 weak_factory_
.GetWeakPtr());
191 FileSystemOperation::SnapshotFileCallback
RecordSnapshotFileCallback() {
192 return base::Bind(&FileSystemOperationImplTest::DidCreateSnapshotFile
,
193 weak_factory_
.GetWeakPtr());
196 void DidFinish(base::File::Error status
) {
200 void DidReadDirectory(
201 base::File::Error status
,
202 const std::vector
<fileapi::DirectoryEntry
>& entries
,
203 bool /* has_more */) {
208 void DidGetMetadata(base::File::Error status
,
209 const base::File::Info
& info
) {
214 void DidCreateSnapshotFile(
215 base::File::Error status
,
216 const base::File::Info
& info
,
217 const base::FilePath
& platform_path
,
218 const scoped_refptr
<ShareableFileReference
>& shareable_file_ref
) {
220 path_
= platform_path
;
222 shareable_file_ref_
= shareable_file_ref
;
225 int64
GetDataSizeOnDisk() {
226 return sandbox_file_system_
.ComputeCurrentOriginUsage() -
227 sandbox_file_system_
.ComputeCurrentDirectoryDatabaseUsage();
230 void GetUsageAndQuota(int64
* usage
, int64
* quota
) {
231 quota::QuotaStatusCode status
=
232 AsyncFileTestHelper::GetUsageAndQuota(quota_manager_
.get(),
233 sandbox_file_system_
.origin(),
234 sandbox_file_system_
.type(),
237 base::RunLoop().RunUntilIdle();
238 ASSERT_EQ(quota::kQuotaStatusOk
, status
);
241 int64
ComputePathCost(const FileSystemURL
& url
) {
243 GetUsageAndQuota(&base_usage
, NULL
);
245 AsyncFileTestHelper::CreateFile(
246 sandbox_file_system_
.file_system_context(), url
);
247 operation_runner()->Remove(url
, false /* recursive */,
248 base::Bind(&AssertFileErrorEq
, FROM_HERE
,
249 base::File::FILE_OK
));
250 base::RunLoop().RunUntilIdle();
251 change_observer()->ResetCount();
254 GetUsageAndQuota(&total_usage
, NULL
);
255 return total_usage
- base_usage
;
258 void GrantQuotaForCurrentUsage() {
260 GetUsageAndQuota(&usage
, NULL
);
261 quota_manager()->SetQuota(sandbox_file_system_
.origin(),
262 sandbox_file_system_
.storage_type(),
268 GetUsageAndQuota(&usage
, NULL
);
272 void AddQuota(int64 quota_delta
) {
274 GetUsageAndQuota(NULL
, "a
);
275 quota_manager()->SetQuota(sandbox_file_system_
.origin(),
276 sandbox_file_system_
.storage_type(),
277 quota
+ quota_delta
);
281 base::MessageLoop message_loop_
;
282 scoped_refptr
<QuotaManager
> quota_manager_
;
283 scoped_refptr
<QuotaManagerProxy
> quota_manager_proxy_
;
285 // Common temp base for nondestructive uses.
286 base::ScopedTempDir base_
;
288 SandboxFileSystemTestHelper sandbox_file_system_
;
290 // For post-operation status.
292 base::File::Info info_
;
293 base::FilePath path_
;
294 std::vector
<fileapi::DirectoryEntry
> entries_
;
295 scoped_refptr
<ShareableFileReference
> shareable_file_ref_
;
297 fileapi::MockFileChangeObserver change_observer_
;
298 fileapi::ChangeObserverList change_observers_
;
300 base::WeakPtrFactory
<FileSystemOperationImplTest
> weak_factory_
;
302 DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImplTest
);
305 TEST_F(FileSystemOperationImplTest
, TestMoveFailureSrcDoesntExist
) {
306 change_observer()->ResetCount();
307 operation_runner()->Move(URLForPath("a"), URLForPath("b"),
308 FileSystemOperation::OPTION_NONE
,
309 RecordStatusCallback());
310 base::RunLoop().RunUntilIdle();
311 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, status());
312 EXPECT_TRUE(change_observer()->HasNoChange());
315 TEST_F(FileSystemOperationImplTest
, TestMoveFailureContainsPath
) {
316 FileSystemURL
src_dir(CreateDirectory("src"));
317 FileSystemURL
dest_dir(CreateDirectory("src/dest"));
319 operation_runner()->Move(src_dir
, dest_dir
,
320 FileSystemOperation::OPTION_NONE
,
321 RecordStatusCallback());
322 base::RunLoop().RunUntilIdle();
323 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION
, status());
324 EXPECT_TRUE(change_observer()->HasNoChange());
327 TEST_F(FileSystemOperationImplTest
, TestMoveFailureSrcDirExistsDestFile
) {
328 // Src exists and is dir. Dest is a file.
329 FileSystemURL
src_dir(CreateDirectory("src"));
330 FileSystemURL
dest_dir(CreateDirectory("dest"));
331 FileSystemURL
dest_file(CreateFile("dest/file"));
333 operation_runner()->Move(src_dir
, dest_file
,
334 FileSystemOperation::OPTION_NONE
,
335 RecordStatusCallback());
336 base::RunLoop().RunUntilIdle();
337 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION
, status());
338 EXPECT_TRUE(change_observer()->HasNoChange());
341 TEST_F(FileSystemOperationImplTest
,
342 TestMoveFailureSrcFileExistsDestNonEmptyDir
) {
343 // Src exists and is a directory. Dest is a non-empty directory.
344 FileSystemURL
src_dir(CreateDirectory("src"));
345 FileSystemURL
dest_dir(CreateDirectory("dest"));
346 FileSystemURL
dest_file(CreateFile("dest/file"));
348 operation_runner()->Move(src_dir
, dest_dir
,
349 FileSystemOperation::OPTION_NONE
,
350 RecordStatusCallback());
351 base::RunLoop().RunUntilIdle();
352 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY
, status());
353 EXPECT_TRUE(change_observer()->HasNoChange());
356 TEST_F(FileSystemOperationImplTest
, TestMoveFailureSrcFileExistsDestDir
) {
357 // Src exists and is a file. Dest is a directory.
358 FileSystemURL
src_dir(CreateDirectory("src"));
359 FileSystemURL
src_file(CreateFile("src/file"));
360 FileSystemURL
dest_dir(CreateDirectory("dest"));
362 operation_runner()->Move(src_file
, dest_dir
,
363 FileSystemOperation::OPTION_NONE
,
364 RecordStatusCallback());
365 base::RunLoop().RunUntilIdle();
366 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION
, status());
367 EXPECT_TRUE(change_observer()->HasNoChange());
370 TEST_F(FileSystemOperationImplTest
, TestMoveFailureDestParentDoesntExist
) {
371 // Dest. parent path does not exist.
372 FileSystemURL
src_dir(CreateDirectory("src"));
373 operation_runner()->Move(src_dir
, URLForPath("nonexistent/deset"),
374 FileSystemOperation::OPTION_NONE
,
375 RecordStatusCallback());
376 base::RunLoop().RunUntilIdle();
377 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, status());
378 EXPECT_TRUE(change_observer()->HasNoChange());
381 TEST_F(FileSystemOperationImplTest
, TestMoveSuccessSrcFileAndOverwrite
) {
382 FileSystemURL
src_file(CreateFile("src"));
383 FileSystemURL
dest_file(CreateFile("dest"));
385 operation_runner()->Move(src_file
, dest_file
,
386 FileSystemOperation::OPTION_NONE
,
387 RecordStatusCallback());
388 base::RunLoop().RunUntilIdle();
389 EXPECT_EQ(base::File::FILE_OK
, status());
390 EXPECT_TRUE(FileExists("dest"));
392 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
393 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
394 EXPECT_TRUE(change_observer()->HasNoChange());
396 EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count());
399 TEST_F(FileSystemOperationImplTest
, TestMoveSuccessSrcFileAndNew
) {
400 FileSystemURL
src_file(CreateFile("src"));
402 operation_runner()->Move(src_file
, URLForPath("new"),
403 FileSystemOperation::OPTION_NONE
,
404 RecordStatusCallback());
405 base::RunLoop().RunUntilIdle();
406 EXPECT_EQ(base::File::FILE_OK
, status());
407 EXPECT_TRUE(FileExists("new"));
409 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
410 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
411 EXPECT_TRUE(change_observer()->HasNoChange());
414 TEST_F(FileSystemOperationImplTest
, TestMoveSuccessSrcDirAndOverwrite
) {
415 FileSystemURL
src_dir(CreateDirectory("src"));
416 FileSystemURL
dest_dir(CreateDirectory("dest"));
418 operation_runner()->Move(src_dir
, dest_dir
,
419 FileSystemOperation::OPTION_NONE
,
420 RecordStatusCallback());
421 base::RunLoop().RunUntilIdle();
422 EXPECT_EQ(base::File::FILE_OK
, status());
423 EXPECT_FALSE(DirectoryExists("src"));
425 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
426 EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count());
427 EXPECT_TRUE(change_observer()->HasNoChange());
429 // Make sure we've overwritten but not moved the source under the |dest_dir|.
430 EXPECT_TRUE(DirectoryExists("dest"));
431 EXPECT_FALSE(DirectoryExists("dest/src"));
434 TEST_F(FileSystemOperationImplTest
, TestMoveSuccessSrcDirAndNew
) {
435 FileSystemURL
src_dir(CreateDirectory("src"));
436 FileSystemURL
dest_dir(CreateDirectory("dest"));
438 operation_runner()->Move(src_dir
, URLForPath("dest/new"),
439 FileSystemOperation::OPTION_NONE
,
440 RecordStatusCallback());
441 base::RunLoop().RunUntilIdle();
442 EXPECT_EQ(base::File::FILE_OK
, status());
443 EXPECT_FALSE(DirectoryExists("src"));
444 EXPECT_TRUE(DirectoryExists("dest/new"));
446 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
447 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
448 EXPECT_TRUE(change_observer()->HasNoChange());
451 TEST_F(FileSystemOperationImplTest
, TestMoveSuccessSrcDirRecursive
) {
452 FileSystemURL
src_dir(CreateDirectory("src"));
453 CreateDirectory("src/dir");
454 CreateFile("src/dir/sub");
456 FileSystemURL
dest_dir(CreateDirectory("dest"));
458 operation_runner()->Move(src_dir
, dest_dir
,
459 FileSystemOperation::OPTION_NONE
,
460 RecordStatusCallback());
461 base::RunLoop().RunUntilIdle();
462 EXPECT_EQ(base::File::FILE_OK
, status());
463 EXPECT_TRUE(DirectoryExists("dest/dir"));
464 EXPECT_TRUE(FileExists("dest/dir/sub"));
466 EXPECT_EQ(3, change_observer()->get_and_reset_remove_directory_count());
467 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
468 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
469 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
470 EXPECT_TRUE(change_observer()->HasNoChange());
473 TEST_F(FileSystemOperationImplTest
, TestMoveSuccessSamePath
) {
474 FileSystemURL
src_dir(CreateDirectory("src"));
475 CreateDirectory("src/dir");
476 CreateFile("src/dir/sub");
478 operation_runner()->Move(src_dir
, src_dir
,
479 FileSystemOperation::OPTION_NONE
,
480 RecordStatusCallback());
481 base::RunLoop().RunUntilIdle();
482 EXPECT_EQ(base::File::FILE_OK
, status());
483 EXPECT_TRUE(DirectoryExists("src/dir"));
484 EXPECT_TRUE(FileExists("src/dir/sub"));
486 EXPECT_EQ(0, change_observer()->get_and_reset_remove_directory_count());
487 EXPECT_EQ(0, change_observer()->get_and_reset_create_directory_count());
488 EXPECT_EQ(0, change_observer()->get_and_reset_remove_file_count());
489 EXPECT_EQ(0, change_observer()->get_and_reset_create_file_from_count());
490 EXPECT_TRUE(change_observer()->HasNoChange());
493 TEST_F(FileSystemOperationImplTest
, TestCopyFailureSrcDoesntExist
) {
494 operation_runner()->Copy(URLForPath("a"), URLForPath("b"),
495 FileSystemOperation::OPTION_NONE
,
496 FileSystemOperationRunner::CopyProgressCallback(),
497 RecordStatusCallback());
498 base::RunLoop().RunUntilIdle();
499 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, status());
500 EXPECT_TRUE(change_observer()->HasNoChange());
503 TEST_F(FileSystemOperationImplTest
, TestCopyFailureContainsPath
) {
504 FileSystemURL
src_dir(CreateDirectory("src"));
505 FileSystemURL
dest_dir(CreateDirectory("src/dir"));
507 operation_runner()->Copy(src_dir
, dest_dir
,
508 FileSystemOperation::OPTION_NONE
,
509 FileSystemOperationRunner::CopyProgressCallback(),
510 RecordStatusCallback());
511 base::RunLoop().RunUntilIdle();
512 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION
, status());
513 EXPECT_TRUE(change_observer()->HasNoChange());
516 TEST_F(FileSystemOperationImplTest
, TestCopyFailureSrcDirExistsDestFile
) {
517 // Src exists and is dir. Dest is a file.
518 FileSystemURL
src_dir(CreateDirectory("src"));
519 FileSystemURL
dest_dir(CreateDirectory("dest"));
520 FileSystemURL
dest_file(CreateFile("dest/file"));
522 operation_runner()->Copy(src_dir
, dest_file
,
523 FileSystemOperation::OPTION_NONE
,
524 FileSystemOperationRunner::CopyProgressCallback(),
525 RecordStatusCallback());
526 base::RunLoop().RunUntilIdle();
527 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION
, status());
528 EXPECT_TRUE(change_observer()->HasNoChange());
531 TEST_F(FileSystemOperationImplTest
,
532 TestCopyFailureSrcFileExistsDestNonEmptyDir
) {
533 // Src exists and is a directory. Dest is a non-empty directory.
534 FileSystemURL
src_dir(CreateDirectory("src"));
535 FileSystemURL
dest_dir(CreateDirectory("dest"));
536 FileSystemURL
dest_file(CreateFile("dest/file"));
538 operation_runner()->Copy(src_dir
, dest_dir
,
539 FileSystemOperation::OPTION_NONE
,
540 FileSystemOperationRunner::CopyProgressCallback(),
541 RecordStatusCallback());
542 base::RunLoop().RunUntilIdle();
543 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY
, status());
544 EXPECT_TRUE(change_observer()->HasNoChange());
547 TEST_F(FileSystemOperationImplTest
, TestCopyFailureSrcFileExistsDestDir
) {
548 // Src exists and is a file. Dest is a directory.
549 FileSystemURL
src_file(CreateFile("src"));
550 FileSystemURL
dest_dir(CreateDirectory("dest"));
552 operation_runner()->Copy(src_file
, dest_dir
,
553 FileSystemOperation::OPTION_NONE
,
554 FileSystemOperationRunner::CopyProgressCallback(),
555 RecordStatusCallback());
556 base::RunLoop().RunUntilIdle();
557 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION
, status());
558 EXPECT_TRUE(change_observer()->HasNoChange());
561 TEST_F(FileSystemOperationImplTest
, TestCopyFailureDestParentDoesntExist
) {
562 // Dest. parent path does not exist.
563 FileSystemURL
src_dir(CreateDirectory("src"));
565 operation_runner()->Copy(src_dir
, URLForPath("nonexistent/dest"),
566 FileSystemOperation::OPTION_NONE
,
567 FileSystemOperationRunner::CopyProgressCallback(),
568 RecordStatusCallback());
569 base::RunLoop().RunUntilIdle();
570 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, status());
571 EXPECT_TRUE(change_observer()->HasNoChange());
574 TEST_F(FileSystemOperationImplTest
, TestCopyFailureByQuota
) {
575 FileSystemURL
src_dir(CreateDirectory("src"));
576 FileSystemURL
src_file(CreateFile("src/file"));
577 FileSystemURL
dest_dir(CreateDirectory("dest"));
578 operation_runner()->Truncate(src_file
, 6, RecordStatusCallback());
579 base::RunLoop().RunUntilIdle();
580 EXPECT_EQ(base::File::FILE_OK
, status());
581 EXPECT_EQ(6, GetFileSize("src/file"));
583 FileSystemURL
dest_file(URLForPath("dest/file"));
584 int64 dest_path_cost
= ComputePathCost(dest_file
);
585 GrantQuotaForCurrentUsage();
586 AddQuota(6 + dest_path_cost
- 1);
588 operation_runner()->Copy(src_file
, dest_file
,
589 FileSystemOperation::OPTION_NONE
,
590 FileSystemOperationRunner::CopyProgressCallback(),
591 RecordStatusCallback());
592 base::RunLoop().RunUntilIdle();
593 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
, status());
594 EXPECT_FALSE(FileExists("dest/file"));
597 TEST_F(FileSystemOperationImplTest
, TestCopySuccessSrcFileAndOverwrite
) {
598 FileSystemURL
src_file(CreateFile("src"));
599 FileSystemURL
dest_file(CreateFile("dest"));
601 operation_runner()->Copy(src_file
, dest_file
,
602 FileSystemOperation::OPTION_NONE
,
603 FileSystemOperationRunner::CopyProgressCallback(),
604 RecordStatusCallback());
605 base::RunLoop().RunUntilIdle();
606 EXPECT_EQ(base::File::FILE_OK
, status());
607 EXPECT_TRUE(FileExists("dest"));
608 EXPECT_EQ(2, quota_manager_proxy()->notify_storage_accessed_count());
610 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
611 EXPECT_TRUE(change_observer()->HasNoChange());
614 TEST_F(FileSystemOperationImplTest
, TestCopySuccessSrcFileAndNew
) {
615 FileSystemURL
src_file(CreateFile("src"));
617 operation_runner()->Copy(src_file
, URLForPath("new"),
618 FileSystemOperation::OPTION_NONE
,
619 FileSystemOperationRunner::CopyProgressCallback(),
620 RecordStatusCallback());
621 base::RunLoop().RunUntilIdle();
622 EXPECT_EQ(base::File::FILE_OK
, status());
623 EXPECT_TRUE(FileExists("new"));
624 EXPECT_EQ(2, quota_manager_proxy()->notify_storage_accessed_count());
626 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
627 EXPECT_TRUE(change_observer()->HasNoChange());
630 TEST_F(FileSystemOperationImplTest
, TestCopySuccessSrcDirAndOverwrite
) {
631 FileSystemURL
src_dir(CreateDirectory("src"));
632 FileSystemURL
dest_dir(CreateDirectory("dest"));
634 operation_runner()->Copy(src_dir
, dest_dir
,
635 FileSystemOperation::OPTION_NONE
,
636 FileSystemOperationRunner::CopyProgressCallback(),
637 RecordStatusCallback());
638 base::RunLoop().RunUntilIdle();
639 EXPECT_EQ(base::File::FILE_OK
, status());
641 // Make sure we've overwritten but not copied the source under the |dest_dir|.
642 EXPECT_TRUE(DirectoryExists("dest"));
643 EXPECT_FALSE(DirectoryExists("dest/src"));
644 EXPECT_GE(quota_manager_proxy()->notify_storage_accessed_count(), 3);
646 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
647 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
648 EXPECT_TRUE(change_observer()->HasNoChange());
651 TEST_F(FileSystemOperationImplTest
, TestCopySuccessSrcDirAndNew
) {
652 FileSystemURL
src_dir(CreateDirectory("src"));
653 FileSystemURL
dest_dir_new(URLForPath("dest"));
655 operation_runner()->Copy(src_dir
, dest_dir_new
,
656 FileSystemOperation::OPTION_NONE
,
657 FileSystemOperationRunner::CopyProgressCallback(),
658 RecordStatusCallback());
659 base::RunLoop().RunUntilIdle();
660 EXPECT_EQ(base::File::FILE_OK
, status());
661 EXPECT_TRUE(DirectoryExists("dest"));
662 EXPECT_GE(quota_manager_proxy()->notify_storage_accessed_count(), 2);
664 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
665 EXPECT_TRUE(change_observer()->HasNoChange());
668 TEST_F(FileSystemOperationImplTest
, TestCopySuccessSrcDirRecursive
) {
669 FileSystemURL
src_dir(CreateDirectory("src"));
670 CreateDirectory("src/dir");
671 CreateFile("src/dir/sub");
673 FileSystemURL
dest_dir(CreateDirectory("dest"));
675 operation_runner()->Copy(src_dir
, dest_dir
,
676 FileSystemOperation::OPTION_NONE
,
677 FileSystemOperationRunner::CopyProgressCallback(),
678 RecordStatusCallback());
679 base::RunLoop().RunUntilIdle();
681 EXPECT_EQ(base::File::FILE_OK
, status());
682 EXPECT_TRUE(DirectoryExists("dest/dir"));
683 EXPECT_TRUE(FileExists("dest/dir/sub"));
685 // For recursive copy we may record multiple read access.
686 EXPECT_GE(quota_manager_proxy()->notify_storage_accessed_count(), 1);
688 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
689 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
690 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
691 EXPECT_TRUE(change_observer()->HasNoChange());
694 TEST_F(FileSystemOperationImplTest
, TestCopySuccessSamePath
) {
695 FileSystemURL
src_dir(CreateDirectory("src"));
696 CreateDirectory("src/dir");
697 CreateFile("src/dir/sub");
699 operation_runner()->Copy(src_dir
, src_dir
,
700 FileSystemOperation::OPTION_NONE
,
701 FileSystemOperationRunner::CopyProgressCallback(),
702 RecordStatusCallback());
703 base::RunLoop().RunUntilIdle();
705 EXPECT_EQ(base::File::FILE_OK
, status());
706 EXPECT_TRUE(DirectoryExists("src/dir"));
707 EXPECT_TRUE(FileExists("src/dir/sub"));
709 EXPECT_EQ(0, change_observer()->get_and_reset_create_directory_count());
710 EXPECT_EQ(0, change_observer()->get_and_reset_remove_file_count());
711 EXPECT_EQ(0, change_observer()->get_and_reset_create_file_from_count());
712 EXPECT_TRUE(change_observer()->HasNoChange());
715 TEST_F(FileSystemOperationImplTest
, TestCopyInForeignFileSuccess
) {
716 base::FilePath src_local_disk_file_path
;
717 base::CreateTemporaryFile(&src_local_disk_file_path
);
718 const char test_data
[] = "foo";
719 int data_size
= ARRAYSIZE_UNSAFE(test_data
);
720 base::WriteFile(src_local_disk_file_path
, test_data
, data_size
);
722 FileSystemURL
dest_dir(CreateDirectory("dest"));
725 GetUsageAndQuota(&before_usage
, NULL
);
727 // Check that the file copied and corresponding usage increased.
728 operation_runner()->CopyInForeignFile(src_local_disk_file_path
,
729 URLForPath("dest/file"),
730 RecordStatusCallback());
731 base::RunLoop().RunUntilIdle();
733 EXPECT_EQ(1, change_observer()->create_file_count());
734 EXPECT_EQ(base::File::FILE_OK
, status());
735 EXPECT_TRUE(FileExists("dest/file"));
737 GetUsageAndQuota(&after_usage
, NULL
);
738 EXPECT_GT(after_usage
, before_usage
);
740 // Compare contents of src and copied file.
742 EXPECT_EQ(data_size
, base::ReadFile(PlatformPath("dest/file"),
744 for (int i
= 0; i
< data_size
; ++i
)
745 EXPECT_EQ(test_data
[i
], buffer
[i
]);
748 TEST_F(FileSystemOperationImplTest
, TestCopyInForeignFileFailureByQuota
) {
749 base::FilePath src_local_disk_file_path
;
750 base::CreateTemporaryFile(&src_local_disk_file_path
);
751 const char test_data
[] = "foo";
752 base::WriteFile(src_local_disk_file_path
, test_data
,
753 ARRAYSIZE_UNSAFE(test_data
));
755 FileSystemURL
dest_dir(CreateDirectory("dest"));
757 GrantQuotaForCurrentUsage();
758 operation_runner()->CopyInForeignFile(src_local_disk_file_path
,
759 URLForPath("dest/file"),
760 RecordStatusCallback());
761 base::RunLoop().RunUntilIdle();
763 EXPECT_FALSE(FileExists("dest/file"));
764 EXPECT_EQ(0, change_observer()->create_file_count());
765 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
, status());
768 TEST_F(FileSystemOperationImplTest
, TestCreateFileFailure
) {
769 // Already existing file and exclusive true.
770 FileSystemURL
file(CreateFile("file"));
771 operation_runner()->CreateFile(file
, true, RecordStatusCallback());
772 base::RunLoop().RunUntilIdle();
773 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
, status());
774 EXPECT_TRUE(change_observer()->HasNoChange());
777 TEST_F(FileSystemOperationImplTest
, TestCreateFileSuccessFileExists
) {
778 // Already existing file and exclusive false.
779 FileSystemURL
file(CreateFile("file"));
780 operation_runner()->CreateFile(file
, false, RecordStatusCallback());
781 base::RunLoop().RunUntilIdle();
782 EXPECT_EQ(base::File::FILE_OK
, status());
783 EXPECT_TRUE(FileExists("file"));
785 // The file was already there; did nothing.
786 EXPECT_TRUE(change_observer()->HasNoChange());
789 TEST_F(FileSystemOperationImplTest
, TestCreateFileSuccessExclusive
) {
790 // File doesn't exist but exclusive is true.
791 operation_runner()->CreateFile(URLForPath("new"), true,
792 RecordStatusCallback());
793 base::RunLoop().RunUntilIdle();
794 EXPECT_EQ(base::File::FILE_OK
, status());
795 EXPECT_TRUE(FileExists("new"));
796 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
799 TEST_F(FileSystemOperationImplTest
, TestCreateFileSuccessFileDoesntExist
) {
800 // Non existing file.
801 operation_runner()->CreateFile(URLForPath("nonexistent"), false,
802 RecordStatusCallback());
803 base::RunLoop().RunUntilIdle();
804 EXPECT_EQ(base::File::FILE_OK
, status());
805 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
808 TEST_F(FileSystemOperationImplTest
,
809 TestCreateDirFailureDestParentDoesntExist
) {
810 // Dest. parent path does not exist.
811 operation_runner()->CreateDirectory(
812 URLForPath("nonexistent/dir"), false, false,
813 RecordStatusCallback());
814 base::RunLoop().RunUntilIdle();
815 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, status());
816 EXPECT_TRUE(change_observer()->HasNoChange());
819 TEST_F(FileSystemOperationImplTest
, TestCreateDirFailureDirExists
) {
820 // Exclusive and dir existing at path.
821 FileSystemURL
dir(CreateDirectory("dir"));
822 operation_runner()->CreateDirectory(dir
, true, false,
823 RecordStatusCallback());
824 base::RunLoop().RunUntilIdle();
825 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
, status());
826 EXPECT_TRUE(change_observer()->HasNoChange());
829 TEST_F(FileSystemOperationImplTest
, TestCreateDirFailureFileExists
) {
830 // Exclusive true and file existing at path.
831 FileSystemURL
file(CreateFile("file"));
832 operation_runner()->CreateDirectory(file
, true, false,
833 RecordStatusCallback());
834 base::RunLoop().RunUntilIdle();
835 EXPECT_EQ(base::File::FILE_ERROR_EXISTS
, status());
836 EXPECT_TRUE(change_observer()->HasNoChange());
839 TEST_F(FileSystemOperationImplTest
, TestCreateDirSuccess
) {
840 // Dir exists and exclusive is false.
841 FileSystemURL
dir(CreateDirectory("dir"));
842 operation_runner()->CreateDirectory(dir
, false, false,
843 RecordStatusCallback());
844 base::RunLoop().RunUntilIdle();
845 EXPECT_EQ(base::File::FILE_OK
, status());
846 EXPECT_TRUE(change_observer()->HasNoChange());
848 // Dir doesn't exist.
849 operation_runner()->CreateDirectory(URLForPath("new"), false, false,
850 RecordStatusCallback());
851 base::RunLoop().RunUntilIdle();
852 EXPECT_EQ(base::File::FILE_OK
, status());
853 EXPECT_TRUE(DirectoryExists("new"));
854 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
857 TEST_F(FileSystemOperationImplTest
, TestCreateDirSuccessExclusive
) {
858 // Dir doesn't exist.
859 operation_runner()->CreateDirectory(URLForPath("new"), true, false,
860 RecordStatusCallback());
861 base::RunLoop().RunUntilIdle();
862 EXPECT_EQ(base::File::FILE_OK
, status());
863 EXPECT_TRUE(DirectoryExists("new"));
864 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
865 EXPECT_TRUE(change_observer()->HasNoChange());
868 TEST_F(FileSystemOperationImplTest
, TestExistsAndMetadataFailure
) {
869 operation_runner()->GetMetadata(URLForPath("nonexistent"),
870 RecordMetadataCallback());
871 base::RunLoop().RunUntilIdle();
872 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, status());
874 operation_runner()->FileExists(URLForPath("nonexistent"),
875 RecordStatusCallback());
876 base::RunLoop().RunUntilIdle();
877 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, status());
879 operation_runner()->DirectoryExists(URLForPath("nonexistent"),
880 RecordStatusCallback());
881 base::RunLoop().RunUntilIdle();
882 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, status());
883 EXPECT_TRUE(change_observer()->HasNoChange());
886 TEST_F(FileSystemOperationImplTest
, TestExistsAndMetadataSuccess
) {
887 FileSystemURL
dir(CreateDirectory("dir"));
888 FileSystemURL
file(CreateFile("dir/file"));
891 operation_runner()->DirectoryExists(dir
, RecordStatusCallback());
892 base::RunLoop().RunUntilIdle();
893 EXPECT_EQ(base::File::FILE_OK
, status());
896 operation_runner()->GetMetadata(dir
, RecordMetadataCallback());
897 base::RunLoop().RunUntilIdle();
898 EXPECT_EQ(base::File::FILE_OK
, status());
899 EXPECT_TRUE(info().is_directory
);
902 operation_runner()->FileExists(file
, RecordStatusCallback());
903 base::RunLoop().RunUntilIdle();
904 EXPECT_EQ(base::File::FILE_OK
, status());
907 operation_runner()->GetMetadata(file
, RecordMetadataCallback());
908 base::RunLoop().RunUntilIdle();
909 EXPECT_EQ(base::File::FILE_OK
, status());
910 EXPECT_FALSE(info().is_directory
);
913 EXPECT_EQ(read_access
,
914 quota_manager_proxy()->notify_storage_accessed_count());
915 EXPECT_TRUE(change_observer()->HasNoChange());
918 TEST_F(FileSystemOperationImplTest
, TestTypeMismatchErrors
) {
919 FileSystemURL
dir(CreateDirectory("dir"));
920 operation_runner()->FileExists(dir
, RecordStatusCallback());
921 base::RunLoop().RunUntilIdle();
922 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE
, status());
924 FileSystemURL
file(CreateFile("file"));
925 operation_runner()->DirectoryExists(file
, RecordStatusCallback());
926 base::RunLoop().RunUntilIdle();
927 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
, status());
930 TEST_F(FileSystemOperationImplTest
, TestReadDirFailure
) {
931 // Path doesn't exist
932 operation_runner()->ReadDirectory(URLForPath("nonexistent"),
933 RecordReadDirectoryCallback());
934 base::RunLoop().RunUntilIdle();
935 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, status());
938 FileSystemURL
file(CreateFile("file"));
939 operation_runner()->ReadDirectory(file
, RecordReadDirectoryCallback());
940 base::RunLoop().RunUntilIdle();
941 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY
, status());
942 EXPECT_TRUE(change_observer()->HasNoChange());
945 TEST_F(FileSystemOperationImplTest
, TestReadDirSuccess
) {
948 // child_dir child_file
949 // Verify reading parent_dir.
950 FileSystemURL
parent_dir(CreateDirectory("dir"));
951 FileSystemURL
child_dir(CreateDirectory("dir/child_dir"));
952 FileSystemURL
child_file(CreateFile("dir/child_file"));
954 operation_runner()->ReadDirectory(parent_dir
, RecordReadDirectoryCallback());
955 base::RunLoop().RunUntilIdle();
956 EXPECT_EQ(base::File::FILE_OK
, status());
957 EXPECT_EQ(2u, entries().size());
959 for (size_t i
= 0; i
< entries().size(); ++i
) {
960 if (entries()[i
].is_directory
)
961 EXPECT_EQ(FILE_PATH_LITERAL("child_dir"), entries()[i
].name
);
963 EXPECT_EQ(FILE_PATH_LITERAL("child_file"), entries()[i
].name
);
965 EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count());
966 EXPECT_TRUE(change_observer()->HasNoChange());
969 TEST_F(FileSystemOperationImplTest
, TestRemoveFailure
) {
970 // Path doesn't exist.
971 operation_runner()->Remove(URLForPath("nonexistent"), false /* recursive */,
972 RecordStatusCallback());
973 base::RunLoop().RunUntilIdle();
974 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND
, status());
976 // It's an error to try to remove a non-empty directory if recursive flag
980 // child_dir child_file
981 // Verify deleting parent_dir.
982 FileSystemURL
parent_dir(CreateDirectory("dir"));
983 FileSystemURL
child_dir(CreateDirectory("dir/child_dir"));
984 FileSystemURL
child_file(CreateFile("dir/child_file"));
986 operation_runner()->Remove(parent_dir
, false /* recursive */,
987 RecordStatusCallback());
988 base::RunLoop().RunUntilIdle();
989 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY
, status());
990 EXPECT_TRUE(change_observer()->HasNoChange());
993 TEST_F(FileSystemOperationImplTest
, TestRemoveSuccess
) {
994 FileSystemURL
empty_dir(CreateDirectory("empty_dir"));
995 EXPECT_TRUE(DirectoryExists("empty_dir"));
996 operation_runner()->Remove(empty_dir
, false /* recursive */,
997 RecordStatusCallback());
998 base::RunLoop().RunUntilIdle();
999 EXPECT_EQ(base::File::FILE_OK
, status());
1000 EXPECT_FALSE(DirectoryExists("empty_dir"));
1002 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
1003 EXPECT_TRUE(change_observer()->HasNoChange());
1006 TEST_F(FileSystemOperationImplTest
, TestRemoveSuccessRecursive
) {
1007 // Removing a non-empty directory with recursive flag == true should be ok.
1010 // child_dir child_files
1014 // Verify deleting parent_dir.
1015 FileSystemURL
parent_dir(CreateDirectory("dir"));
1016 for (int i
= 0; i
< 8; ++i
)
1017 CreateFile(base::StringPrintf("dir/file-%d", i
));
1018 FileSystemURL
child_dir(CreateDirectory("dir/child_dir"));
1019 for (int i
= 0; i
< 8; ++i
)
1020 CreateFile(base::StringPrintf("dir/child_dir/file-%d", i
));
1022 operation_runner()->Remove(parent_dir
, true /* recursive */,
1023 RecordStatusCallback());
1024 base::RunLoop().RunUntilIdle();
1025 EXPECT_EQ(base::File::FILE_OK
, status());
1026 EXPECT_FALSE(DirectoryExists("parent_dir"));
1028 EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count());
1029 EXPECT_EQ(16, change_observer()->get_and_reset_remove_file_count());
1030 EXPECT_TRUE(change_observer()->HasNoChange());
1033 TEST_F(FileSystemOperationImplTest
, TestTruncate
) {
1034 FileSystemURL
file(CreateFile("file"));
1035 base::FilePath platform_path
= PlatformPath("file");
1037 char test_data
[] = "test data";
1038 int data_size
= static_cast<int>(sizeof(test_data
));
1039 EXPECT_EQ(data_size
,
1040 base::WriteFile(platform_path
, test_data
, data_size
));
1042 // Check that its length is the size of the data written.
1043 operation_runner()->GetMetadata(file
, RecordMetadataCallback());
1044 base::RunLoop().RunUntilIdle();
1045 EXPECT_EQ(base::File::FILE_OK
, status());
1046 EXPECT_FALSE(info().is_directory
);
1047 EXPECT_EQ(data_size
, info().size
);
1049 // Extend the file by truncating it.
1051 operation_runner()->Truncate(file
, length
, RecordStatusCallback());
1052 base::RunLoop().RunUntilIdle();
1053 EXPECT_EQ(base::File::FILE_OK
, status());
1055 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1056 EXPECT_TRUE(change_observer()->HasNoChange());
1058 // Check that its length is now 17 and that it's all zeroes after the test
1060 EXPECT_EQ(length
, GetFileSize("file"));
1062 EXPECT_EQ(length
, base::ReadFile(platform_path
, data
, length
));
1063 for (int i
= 0; i
< length
; ++i
) {
1064 if (i
< static_cast<int>(sizeof(test_data
)))
1065 EXPECT_EQ(test_data
[i
], data
[i
]);
1067 EXPECT_EQ(0, data
[i
]);
1070 // Shorten the file by truncating it.
1072 operation_runner()->Truncate(file
, length
, RecordStatusCallback());
1073 base::RunLoop().RunUntilIdle();
1074 EXPECT_EQ(base::File::FILE_OK
, status());
1076 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1077 EXPECT_TRUE(change_observer()->HasNoChange());
1079 // Check that its length is now 3 and that it contains only bits of test data.
1080 EXPECT_EQ(length
, GetFileSize("file"));
1081 EXPECT_EQ(length
, base::ReadFile(platform_path
, data
, length
));
1082 for (int i
= 0; i
< length
; ++i
)
1083 EXPECT_EQ(test_data
[i
], data
[i
]);
1085 // Truncate is not a 'read' access. (Here expected access count is 1
1086 // since we made 1 read access for GetMetadata.)
1087 EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count());
1090 TEST_F(FileSystemOperationImplTest
, TestTruncateFailureByQuota
) {
1091 FileSystemURL
dir(CreateDirectory("dir"));
1092 FileSystemURL
file(CreateFile("dir/file"));
1094 GrantQuotaForCurrentUsage();
1097 operation_runner()->Truncate(file
, 10, RecordStatusCallback());
1098 base::RunLoop().RunUntilIdle();
1099 EXPECT_EQ(base::File::FILE_OK
, status());
1100 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1101 EXPECT_TRUE(change_observer()->HasNoChange());
1103 EXPECT_EQ(10, GetFileSize("dir/file"));
1105 operation_runner()->Truncate(file
, 11, RecordStatusCallback());
1106 base::RunLoop().RunUntilIdle();
1107 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE
, status());
1108 EXPECT_TRUE(change_observer()->HasNoChange());
1110 EXPECT_EQ(10, GetFileSize("dir/file"));
1113 TEST_F(FileSystemOperationImplTest
, TestTouchFile
) {
1114 FileSystemURL
file(CreateFile("file"));
1115 base::FilePath platform_path
= PlatformPath("file");
1117 base::File::Info info
;
1118 EXPECT_TRUE(base::GetFileInfo(platform_path
, &info
));
1119 EXPECT_FALSE(info
.is_directory
);
1120 EXPECT_EQ(0, info
.size
);
1121 const base::Time last_modified
= info
.last_modified
;
1122 const base::Time last_accessed
= info
.last_accessed
;
1124 const base::Time new_modified_time
= base::Time::UnixEpoch();
1125 const base::Time new_accessed_time
= new_modified_time
+
1126 base::TimeDelta::FromHours(77);
1127 ASSERT_NE(last_modified
, new_modified_time
);
1128 ASSERT_NE(last_accessed
, new_accessed_time
);
1130 operation_runner()->TouchFile(file
, new_accessed_time
, new_modified_time
,
1131 RecordStatusCallback());
1132 base::RunLoop().RunUntilIdle();
1133 EXPECT_EQ(base::File::FILE_OK
, status());
1134 EXPECT_TRUE(change_observer()->HasNoChange());
1136 EXPECT_TRUE(base::GetFileInfo(platform_path
, &info
));
1137 // We compare as time_t here to lower our resolution, to avoid false
1138 // negatives caused by conversion to the local filesystem's native
1139 // representation and back.
1140 EXPECT_EQ(new_modified_time
.ToTimeT(), info
.last_modified
.ToTimeT());
1141 EXPECT_EQ(new_accessed_time
.ToTimeT(), info
.last_accessed
.ToTimeT());
1144 TEST_F(FileSystemOperationImplTest
, TestCreateSnapshotFile
) {
1145 FileSystemURL
dir(CreateDirectory("dir"));
1147 // Create a file for the testing.
1148 operation_runner()->DirectoryExists(dir
, RecordStatusCallback());
1149 FileSystemURL
file(CreateFile("dir/file"));
1150 operation_runner()->FileExists(file
, RecordStatusCallback());
1151 base::RunLoop().RunUntilIdle();
1152 EXPECT_EQ(base::File::FILE_OK
, status());
1154 // See if we can get a 'snapshot' file info for the file.
1155 // Since FileSystemOperationImpl assumes the file exists in the local
1156 // directory it should just returns the same metadata and platform_path
1157 // as the file itself.
1158 operation_runner()->CreateSnapshotFile(file
, RecordSnapshotFileCallback());
1159 base::RunLoop().RunUntilIdle();
1160 EXPECT_EQ(base::File::FILE_OK
, status());
1161 EXPECT_FALSE(info().is_directory
);
1162 EXPECT_EQ(PlatformPath("dir/file"), path());
1163 EXPECT_TRUE(change_observer()->HasNoChange());
1165 // The FileSystemOpration implementation does not create a
1166 // shareable file reference.
1167 EXPECT_EQ(NULL
, shareable_file_ref());
1170 TEST_F(FileSystemOperationImplTest
,
1171 TestMoveSuccessSrcDirRecursiveWithQuota
) {
1172 FileSystemURL
src(CreateDirectory("src"));
1173 int src_path_cost
= GetUsage();
1175 FileSystemURL
dest(CreateDirectory("dest"));
1176 FileSystemURL
child_file1(CreateFile("src/file1"));
1177 FileSystemURL
child_file2(CreateFile("src/file2"));
1178 FileSystemURL
child_dir(CreateDirectory("src/dir"));
1179 FileSystemURL
grandchild_file1(CreateFile("src/dir/file1"));
1180 FileSystemURL
grandchild_file2(CreateFile("src/dir/file2"));
1182 int total_path_cost
= GetUsage();
1183 EXPECT_EQ(0, GetDataSizeOnDisk());
1185 operation_runner()->Truncate(
1187 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1188 operation_runner()->Truncate(
1190 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1191 operation_runner()->Truncate(
1192 grandchild_file1
, 30,
1193 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1194 operation_runner()->Truncate(
1195 grandchild_file2
, 2,
1196 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1197 base::RunLoop().RunUntilIdle();
1199 const int64 all_file_size
= 5000 + 400 + 30 + 2;
1200 EXPECT_EQ(all_file_size
, GetDataSizeOnDisk());
1201 EXPECT_EQ(all_file_size
+ total_path_cost
, GetUsage());
1203 operation_runner()->Move(
1204 src
, dest
, FileSystemOperation::OPTION_NONE
,
1205 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1206 base::RunLoop().RunUntilIdle();
1208 EXPECT_FALSE(DirectoryExists("src/dir"));
1209 EXPECT_FALSE(FileExists("src/dir/file2"));
1210 EXPECT_TRUE(DirectoryExists("dest/dir"));
1211 EXPECT_TRUE(FileExists("dest/dir/file2"));
1213 EXPECT_EQ(all_file_size
, GetDataSizeOnDisk());
1214 EXPECT_EQ(all_file_size
+ total_path_cost
- src_path_cost
,
1218 TEST_F(FileSystemOperationImplTest
,
1219 TestCopySuccessSrcDirRecursiveWithQuota
) {
1220 FileSystemURL
src(CreateDirectory("src"));
1221 FileSystemURL
dest1(CreateDirectory("dest1"));
1222 FileSystemURL
dest2(CreateDirectory("dest2"));
1224 int64 usage
= GetUsage();
1225 FileSystemURL
child_file1(CreateFile("src/file1"));
1226 FileSystemURL
child_file2(CreateFile("src/file2"));
1227 FileSystemURL
child_dir(CreateDirectory("src/dir"));
1228 int64 child_path_cost
= GetUsage() - usage
;
1229 usage
+= child_path_cost
;
1231 FileSystemURL
grandchild_file1(CreateFile("src/dir/file1"));
1232 FileSystemURL
grandchild_file2(CreateFile("src/dir/file2"));
1233 int64 total_path_cost
= GetUsage();
1234 int64 grandchild_path_cost
= total_path_cost
- usage
;
1236 EXPECT_EQ(0, GetDataSizeOnDisk());
1238 operation_runner()->Truncate(
1240 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1241 operation_runner()->Truncate(
1243 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1244 operation_runner()->Truncate(
1245 grandchild_file1
, 60,
1246 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1247 operation_runner()->Truncate(
1248 grandchild_file2
, 5,
1249 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1250 base::RunLoop().RunUntilIdle();
1252 const int64 child_file_size
= 8000 + 700;
1253 const int64 grandchild_file_size
= 60 + 5;
1254 const int64 all_file_size
= child_file_size
+ grandchild_file_size
;
1255 int64 expected_usage
= all_file_size
+ total_path_cost
;
1258 EXPECT_EQ(all_file_size
, GetDataSizeOnDisk());
1259 EXPECT_EQ(expected_usage
, usage
);
1261 // Copy src to dest1.
1262 operation_runner()->Copy(
1263 src
, dest1
, FileSystemOperation::OPTION_NONE
,
1264 FileSystemOperationRunner::CopyProgressCallback(),
1265 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1266 base::RunLoop().RunUntilIdle();
1268 expected_usage
+= all_file_size
+ child_path_cost
+ grandchild_path_cost
;
1269 EXPECT_TRUE(DirectoryExists("src/dir"));
1270 EXPECT_TRUE(FileExists("src/dir/file2"));
1271 EXPECT_TRUE(DirectoryExists("dest1/dir"));
1272 EXPECT_TRUE(FileExists("dest1/dir/file2"));
1274 EXPECT_EQ(2 * all_file_size
, GetDataSizeOnDisk());
1275 EXPECT_EQ(expected_usage
, GetUsage());
1277 // Copy src/dir to dest2.
1278 operation_runner()->Copy(
1279 child_dir
, dest2
, FileSystemOperation::OPTION_NONE
,
1280 FileSystemOperationRunner::CopyProgressCallback(),
1281 base::Bind(&AssertFileErrorEq
, FROM_HERE
, base::File::FILE_OK
));
1282 base::RunLoop().RunUntilIdle();
1284 expected_usage
+= grandchild_file_size
+ grandchild_path_cost
;
1286 EXPECT_EQ(2 * child_file_size
+ 3 * grandchild_file_size
,
1287 GetDataSizeOnDisk());
1288 EXPECT_EQ(expected_usage
, usage
);
1291 } // namespace content