1 // Copyright (c) 2012 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/fileapi/local_file_system_operation.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop.h"
12 #include "base/scoped_temp_dir.h"
13 #include "base/string_number_conversions.h"
14 #include "googleurl/src/gurl.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webkit/blob/shareable_file_reference.h"
17 #include "webkit/fileapi/file_system_context.h"
18 #include "webkit/fileapi/file_system_file_util.h"
19 #include "webkit/fileapi/file_system_mount_point_provider.h"
20 #include "webkit/fileapi/file_system_quota_util.h"
21 #include "webkit/fileapi/file_system_util.h"
22 #include "webkit/fileapi/file_util_helper.h"
23 #include "webkit/fileapi/local_file_system_test_helper.h"
24 #include "webkit/fileapi/mock_file_change_observer.h"
25 #include "webkit/quota/quota_manager.h"
27 using quota::QuotaClient
;
28 using quota::QuotaManager
;
29 using quota::QuotaManagerProxy
;
30 using quota::StorageType
;
31 using webkit_blob::ShareableFileReference
;
37 const int kFileOperationStatusNotSet
= 1;
39 void AssertFileErrorEq(base::PlatformFileError expected
,
40 base::PlatformFileError actual
) {
41 ASSERT_EQ(expected
, actual
);
44 class MockQuotaManager
: public QuotaManager
{
46 MockQuotaManager(const FilePath
& base_dir
,
49 : QuotaManager(false /* is_incognito */, base_dir
,
50 base::MessageLoopProxy::current(),
51 base::MessageLoopProxy::current(),
59 virtual void GetUsageAndQuota(
60 const GURL
& origin
, quota::StorageType type
,
61 const GetUsageAndQuotaCallback
& callback
) OVERRIDE
{
62 EXPECT_EQ(origin_
, origin
);
63 EXPECT_EQ(type_
, type
);
64 callback
.Run(quota::kQuotaStatusOk
, usage_
, quota_
);
68 virtual ~MockQuotaManager() {}
71 friend class MockQuotaManagerProxy
;
73 void SetQuota(const GURL
& origin
, StorageType type
, int64 quota
) {
74 EXPECT_EQ(origin_
, origin
);
75 EXPECT_EQ(type_
, type
);
79 void RecordStorageAccessed(const GURL
& origin
, StorageType type
) {
80 EXPECT_EQ(origin_
, origin
);
81 EXPECT_EQ(type_
, type
);
85 void UpdateUsage(const GURL
& origin
, StorageType type
, int64 delta
) {
86 EXPECT_EQ(origin_
, origin
);
87 EXPECT_EQ(type_
, type
);
92 const StorageType type_
;
98 class MockQuotaManagerProxy
: public QuotaManagerProxy
{
100 explicit MockQuotaManagerProxy(QuotaManager
* quota_manager
)
101 : QuotaManagerProxy(quota_manager
,
102 base::MessageLoopProxy::current()),
103 registered_client_(NULL
) {
106 virtual void RegisterClient(QuotaClient
* client
) OVERRIDE
{
107 EXPECT_FALSE(registered_client_
);
108 registered_client_
= client
;
111 void SimulateQuotaManagerDestroyed() {
112 if (registered_client_
) {
113 // We cannot call this in the destructor as the client (indirectly)
114 // holds a refptr of the proxy.
115 registered_client_
->OnQuotaManagerDestroyed();
116 registered_client_
= NULL
;
120 // We don't mock them.
121 virtual void NotifyOriginInUse(const GURL
& origin
) OVERRIDE
{}
122 virtual void NotifyOriginNoLongerInUse(const GURL
& origin
) OVERRIDE
{}
124 virtual void NotifyStorageAccessed(QuotaClient::ID client_id
,
126 StorageType type
) OVERRIDE
{
127 mock_manager()->RecordStorageAccessed(origin
, type
);
130 virtual void NotifyStorageModified(QuotaClient::ID client_id
,
133 int64 delta
) OVERRIDE
{
134 mock_manager()->UpdateUsage(origin
, type
, delta
);
137 int storage_accessed_count() const {
138 return mock_manager()->accessed_
;
141 void SetQuota(const GURL
& origin
, StorageType type
, int64 quota
) {
142 mock_manager()->SetQuota(origin
, type
, quota
);
146 virtual ~MockQuotaManagerProxy() {
147 EXPECT_FALSE(registered_client_
);
151 MockQuotaManager
* mock_manager() const {
152 return static_cast<MockQuotaManager
*>(quota_manager());
155 QuotaClient
* registered_client_
;
158 FilePath
ASCIIToFilePath(const std::string
& str
) {
159 return FilePath().AppendASCII(str
);
162 } // namespace (anonymous)
164 // Test class for LocalFileSystemOperation.
165 class LocalFileSystemOperationTest
166 : public testing::Test
,
167 public base::SupportsWeakPtr
<LocalFileSystemOperationTest
> {
169 LocalFileSystemOperationTest()
170 : status_(kFileOperationStatusNotSet
),
171 next_unique_path_suffix_(0) {
172 EXPECT_TRUE(base_
.CreateUniqueTempDir());
173 change_observers_
= MockFileChangeObserver::CreateList(&change_observer_
);
176 LocalFileSystemOperation
* operation();
178 int status() const { return status_
; }
179 const base::PlatformFileInfo
& info() const { return info_
; }
180 const FilePath
& path() const { return path_
; }
181 const std::vector
<base::FileUtilProxy::Entry
>& entries() const {
184 const ShareableFileReference
* shareable_file_ref() const {
185 return shareable_file_ref_
;
188 virtual void SetUp() OVERRIDE
;
189 virtual void TearDown() OVERRIDE
;
192 // Common temp base for nondestructive uses.
195 MockQuotaManagerProxy
* quota_manager_proxy() {
196 return static_cast<MockQuotaManagerProxy
*>(quota_manager_proxy_
.get());
199 FileSystemFileUtil
* file_util() {
200 return test_helper_
.file_util();
203 const ChangeObserverList
& change_observers() const {
204 return change_observers_
;
207 MockFileChangeObserver
* change_observer() {
208 return &change_observer_
;
211 FileSystemOperationContext
* NewContext() {
212 FileSystemOperationContext
* context
= test_helper_
.NewOperationContext();
213 // Grant enough quota for all test cases.
214 context
->set_allowed_bytes_growth(1000000);
218 FileSystemURL
URLForPath(const FilePath
& path
) const {
219 return test_helper_
.CreateURL(path
);
222 FilePath
PlatformPath(const FilePath
& virtual_path
) {
223 return test_helper_
.GetLocalPath(virtual_path
);
226 bool FileExists(const FilePath
& virtual_path
) {
227 FileSystemURL path
= test_helper_
.CreateURL(virtual_path
);
228 scoped_ptr
<FileSystemOperationContext
> context(NewContext());
229 if (!FileUtilHelper::PathExists(context
.get(), file_util(), path
))
232 context
.reset(NewContext());
233 return !FileUtilHelper::DirectoryExists(context
.get(), file_util(), path
);
236 bool DirectoryExists(const FilePath
& virtual_path
) {
237 FileSystemURL url
= test_helper_
.CreateURL(virtual_path
);
238 scoped_ptr
<FileSystemOperationContext
> context(NewContext());
239 return FileUtilHelper::DirectoryExists(context
.get(), file_util(), url
);
242 FilePath
CreateUniqueFileInDir(const FilePath
& virtual_dir_path
) {
243 FilePath file_name
= FilePath::FromUTF8Unsafe(
244 "tmpfile-" + base::IntToString(next_unique_path_suffix_
++));
245 FileSystemURL url
= test_helper_
.CreateURL(
246 virtual_dir_path
.Append(file_name
));
248 scoped_ptr
<FileSystemOperationContext
> context(NewContext());
250 EXPECT_EQ(base::PLATFORM_FILE_OK
,
251 file_util()->EnsureFileExists(context
.get(), url
, &created
));
252 EXPECT_TRUE(created
);
256 FilePath
CreateUniqueDirInDir(const FilePath
& virtual_dir_path
) {
257 FilePath dir_name
= FilePath::FromUTF8Unsafe(
258 "tmpdir-" + base::IntToString(next_unique_path_suffix_
++));
259 FileSystemURL url
= test_helper_
.CreateURL(
260 virtual_dir_path
.Append(dir_name
));
262 scoped_ptr
<FileSystemOperationContext
> context(NewContext());
263 EXPECT_EQ(base::PLATFORM_FILE_OK
,
264 file_util()->CreateDirectory(context
.get(), url
, false, true));
268 FilePath
CreateUniqueDir() {
269 return CreateUniqueDirInDir(FilePath());
272 LocalFileSystemTestOriginHelper test_helper_
;
274 // Callbacks for recording test results.
275 FileSystemOperation::StatusCallback
RecordStatusCallback() {
276 return base::Bind(&LocalFileSystemOperationTest::DidFinish
, AsWeakPtr());
279 FileSystemOperation::ReadDirectoryCallback
280 RecordReadDirectoryCallback() {
281 return base::Bind(&LocalFileSystemOperationTest::DidReadDirectory
,
285 FileSystemOperation::GetMetadataCallback
RecordMetadataCallback() {
286 return base::Bind(&LocalFileSystemOperationTest::DidGetMetadata
,
290 FileSystemOperation::SnapshotFileCallback
RecordSnapshotFileCallback() {
291 return base::Bind(&LocalFileSystemOperationTest::DidCreateSnapshotFile
,
295 void DidFinish(base::PlatformFileError status
) {
299 void DidReadDirectory(
300 base::PlatformFileError status
,
301 const std::vector
<base::FileUtilProxy::Entry
>& entries
,
302 bool /* has_more */) {
307 void DidGetMetadata(base::PlatformFileError status
,
308 const base::PlatformFileInfo
& info
,
309 const FilePath
& platform_path
) {
311 path_
= platform_path
;
315 void DidCreateSnapshotFile(
316 base::PlatformFileError status
,
317 const base::PlatformFileInfo
& info
,
318 const FilePath
& platform_path
,
319 const scoped_refptr
<ShareableFileReference
>& shareable_file_ref
) {
321 path_
= platform_path
;
323 shareable_file_ref_
= shareable_file_ref
;
326 static void DidGetUsageAndQuota(quota::QuotaStatusCode
* status_out
,
329 quota::QuotaStatusCode status
,
333 *status_out
= status
;
342 void GetUsageAndQuota(int64
* usage
, int64
* quota
) {
343 quota::QuotaStatusCode status
= quota::kQuotaStatusUnknown
;
344 quota_manager_
->GetUsageAndQuota(
345 test_helper_
.origin(),
346 test_helper_
.storage_type(),
347 base::Bind(&LocalFileSystemOperationTest::DidGetUsageAndQuota
,
348 &status
, usage
, quota
));
349 MessageLoop::current()->RunAllPending();
350 ASSERT_EQ(quota::kQuotaStatusOk
, status
);
353 void GenerateUniquePathInDir(const FilePath
& dir
,
357 GetUsageAndQuota(&base_usage
, NULL
);
358 *file_path
= CreateUniqueFileInDir(dir
);
359 operation()->Remove(URLForPath(*file_path
),
360 false /* recursive */,
361 base::Bind(&AssertFileErrorEq
,
362 base::PLATFORM_FILE_OK
));
363 MessageLoop::current()->RunAllPending();
366 GetUsageAndQuota(&total_usage
, NULL
);
367 *path_cost
= total_usage
- base_usage
;
370 void GrantQuotaForCurrentUsage() {
372 GetUsageAndQuota(&usage
, NULL
);
373 quota_manager_proxy()->SetQuota(test_helper_
.origin(),
374 test_helper_
.storage_type(),
378 void AddQuota(int64 quota_delta
) {
380 GetUsageAndQuota(NULL
, "a
);
381 quota_manager_proxy()->SetQuota(test_helper_
.origin(),
382 test_helper_
.storage_type(),
383 quota
+ quota_delta
);
386 // For post-operation status.
388 base::PlatformFileInfo info_
;
390 std::vector
<base::FileUtilProxy::Entry
> entries_
;
391 scoped_refptr
<ShareableFileReference
> shareable_file_ref_
;
394 MessageLoop message_loop_
;
395 scoped_refptr
<QuotaManager
> quota_manager_
;
396 scoped_refptr
<QuotaManagerProxy
> quota_manager_proxy_
;
398 MockFileChangeObserver change_observer_
;
399 ChangeObserverList change_observers_
;
401 int next_unique_path_suffix_
;
403 DISALLOW_COPY_AND_ASSIGN(LocalFileSystemOperationTest
);
406 void LocalFileSystemOperationTest::SetUp() {
407 FilePath base_dir
= base_
.path().AppendASCII("filesystem");
408 quota_manager_
= new MockQuotaManager(
409 base_dir
, test_helper_
.origin(), test_helper_
.storage_type());
410 quota_manager_proxy_
= new MockQuotaManagerProxy(quota_manager_
.get());
411 test_helper_
.SetUp(base_dir
,
412 false /* unlimited quota */,
413 quota_manager_proxy_
.get(),
417 void LocalFileSystemOperationTest::TearDown() {
418 // Let the client go away before dropping a ref of the quota manager proxy.
419 quota_manager_proxy()->SimulateQuotaManagerDestroyed();
420 quota_manager_
= NULL
;
421 quota_manager_proxy_
= NULL
;
422 test_helper_
.TearDown();
425 LocalFileSystemOperation
* LocalFileSystemOperationTest::operation() {
426 LocalFileSystemOperation
* operation
= test_helper_
.NewOperation();
427 operation
->operation_context()->set_change_observers(change_observers());
431 TEST_F(LocalFileSystemOperationTest
, TestMoveFailureSrcDoesntExist
) {
432 FileSystemURL
src(URLForPath(FilePath(FILE_PATH_LITERAL("a"))));
433 FileSystemURL
dest(URLForPath(FilePath(FILE_PATH_LITERAL("b"))));
434 change_observer()->ResetCount();
435 operation()->Move(src
, dest
, RecordStatusCallback());
436 MessageLoop::current()->RunAllPending();
437 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
438 EXPECT_TRUE(change_observer()->HasNoChange());
441 TEST_F(LocalFileSystemOperationTest
, TestMoveFailureContainsPath
) {
442 FilePath
src_dir_path(CreateUniqueDir());
443 FilePath
dest_dir_path(CreateUniqueDirInDir(src_dir_path
));
444 operation()->Move(URLForPath(src_dir_path
), URLForPath(dest_dir_path
),
445 RecordStatusCallback());
446 MessageLoop::current()->RunAllPending();
447 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION
, status());
448 EXPECT_TRUE(change_observer()->HasNoChange());
451 TEST_F(LocalFileSystemOperationTest
, TestMoveFailureSrcDirExistsDestFile
) {
452 // Src exists and is dir. Dest is a file.
453 FilePath
src_dir_path(CreateUniqueDir());
454 FilePath
dest_dir_path(CreateUniqueDir());
455 FilePath
dest_file_path(CreateUniqueFileInDir(dest_dir_path
));
457 operation()->Move(URLForPath(src_dir_path
), URLForPath(dest_file_path
),
458 RecordStatusCallback());
459 MessageLoop::current()->RunAllPending();
460 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION
, status());
461 EXPECT_TRUE(change_observer()->HasNoChange());
464 TEST_F(LocalFileSystemOperationTest
,
465 TestMoveFailureSrcFileExistsDestNonEmptyDir
) {
466 // Src exists and is a directory. Dest is a non-empty directory.
467 FilePath
src_dir_path(CreateUniqueDir());
468 FilePath
dest_dir_path(CreateUniqueDir());
469 FilePath
child_file_path(CreateUniqueFileInDir(dest_dir_path
));
471 operation()->Move(URLForPath(src_dir_path
), URLForPath(dest_dir_path
),
472 RecordStatusCallback());
473 MessageLoop::current()->RunAllPending();
474 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY
, status());
475 EXPECT_TRUE(change_observer()->HasNoChange());
478 TEST_F(LocalFileSystemOperationTest
, TestMoveFailureSrcFileExistsDestDir
) {
479 // Src exists and is a file. Dest is a directory.
480 FilePath
src_dir_path(CreateUniqueDir());
481 FilePath
src_file_path(CreateUniqueFileInDir(src_dir_path
));
482 FilePath
dest_dir_path(CreateUniqueDir());
484 operation()->Move(URLForPath(src_file_path
), URLForPath(dest_dir_path
),
485 RecordStatusCallback());
486 MessageLoop::current()->RunAllPending();
487 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION
, status());
488 EXPECT_TRUE(change_observer()->HasNoChange());
491 TEST_F(LocalFileSystemOperationTest
, TestMoveFailureDestParentDoesntExist
) {
492 // Dest. parent path does not exist.
493 FilePath
src_dir_path(CreateUniqueDir());
494 FilePath nonexisting_file
= FilePath(FILE_PATH_LITERAL("NonexistingDir")).
495 Append(FILE_PATH_LITERAL("NonexistingFile"));
497 operation()->Move(URLForPath(src_dir_path
), URLForPath(nonexisting_file
),
498 RecordStatusCallback());
499 MessageLoop::current()->RunAllPending();
500 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
501 EXPECT_TRUE(change_observer()->HasNoChange());
504 TEST_F(LocalFileSystemOperationTest
, TestMoveSuccessSrcFileAndOverwrite
) {
505 FilePath
src_dir_path(CreateUniqueDir());
506 FilePath
src_file_path(CreateUniqueFileInDir(src_dir_path
));
507 FilePath
dest_dir_path(CreateUniqueDir());
508 FilePath
dest_file_path(CreateUniqueFileInDir(dest_dir_path
));
510 operation()->Move(URLForPath(src_file_path
), URLForPath(dest_file_path
),
511 RecordStatusCallback());
512 MessageLoop::current()->RunAllPending();
513 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
514 EXPECT_TRUE(FileExists(dest_file_path
));
516 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
517 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
518 EXPECT_TRUE(change_observer()->HasNoChange());
520 // Move is considered 'write' access (for both side), and won't be counted
522 EXPECT_EQ(0, quota_manager_proxy()->storage_accessed_count());
525 TEST_F(LocalFileSystemOperationTest
, TestMoveSuccessSrcFileAndNew
) {
526 FilePath
src_dir_path(CreateUniqueDir());
527 FilePath
src_file_path(CreateUniqueFileInDir(src_dir_path
));
528 FilePath
dest_dir_path(CreateUniqueDir());
529 FilePath
dest_file_path(dest_dir_path
.Append(FILE_PATH_LITERAL("NewFile")));
531 operation()->Move(URLForPath(src_file_path
), URLForPath(dest_file_path
),
532 RecordStatusCallback());
533 MessageLoop::current()->RunAllPending();
534 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
535 EXPECT_TRUE(FileExists(dest_file_path
));
537 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
538 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
539 EXPECT_TRUE(change_observer()->HasNoChange());
542 TEST_F(LocalFileSystemOperationTest
, TestMoveSuccessSrcDirAndOverwrite
) {
543 FilePath
src_dir_path(CreateUniqueDir());
544 FilePath
dest_dir_path(CreateUniqueDir());
546 operation()->Move(URLForPath(src_dir_path
), URLForPath(dest_dir_path
),
547 RecordStatusCallback());
548 MessageLoop::current()->RunAllPending();
549 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
550 EXPECT_FALSE(DirectoryExists(src_dir_path
));
552 EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count());
553 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
554 EXPECT_TRUE(change_observer()->HasNoChange());
556 // Make sure we've overwritten but not moved the source under the |dest_dir|.
557 EXPECT_TRUE(DirectoryExists(dest_dir_path
));
558 EXPECT_FALSE(DirectoryExists(
559 dest_dir_path
.Append(VirtualPath::BaseName(src_dir_path
))));
562 TEST_F(LocalFileSystemOperationTest
, TestMoveSuccessSrcDirAndNew
) {
563 FilePath
src_dir_path(CreateUniqueDir());
564 FilePath
dest_parent_dir_path(CreateUniqueDir());
565 FilePath
dest_child_dir_path(dest_parent_dir_path
.
566 Append(FILE_PATH_LITERAL("NewDirectory")));
568 operation()->Move(URLForPath(src_dir_path
), URLForPath(dest_child_dir_path
),
569 RecordStatusCallback());
570 MessageLoop::current()->RunAllPending();
571 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
572 EXPECT_FALSE(DirectoryExists(src_dir_path
));
573 EXPECT_TRUE(DirectoryExists(dest_child_dir_path
));
575 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
576 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
577 EXPECT_TRUE(change_observer()->HasNoChange());
580 TEST_F(LocalFileSystemOperationTest
, TestMoveSuccessSrcDirRecursive
) {
581 FilePath
src_dir_path(CreateUniqueDir());
582 FilePath
child_dir_path(CreateUniqueDirInDir(src_dir_path
));
583 FilePath
grandchild_file_path(
584 CreateUniqueFileInDir(child_dir_path
));
586 FilePath
dest_dir_path(CreateUniqueDir());
588 operation()->Move(URLForPath(src_dir_path
), URLForPath(dest_dir_path
),
589 RecordStatusCallback());
590 MessageLoop::current()->RunAllPending();
591 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
592 EXPECT_TRUE(DirectoryExists(dest_dir_path
.Append(
593 VirtualPath::BaseName(child_dir_path
))));
594 EXPECT_TRUE(FileExists(dest_dir_path
.Append(
595 VirtualPath::BaseName(child_dir_path
)).Append(
596 VirtualPath::BaseName(grandchild_file_path
))));
598 EXPECT_EQ(3, change_observer()->get_and_reset_remove_directory_count());
599 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
600 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
601 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
602 EXPECT_TRUE(change_observer()->HasNoChange());
605 TEST_F(LocalFileSystemOperationTest
, TestCopyFailureSrcDoesntExist
) {
606 operation()->Copy(URLForPath(FilePath(FILE_PATH_LITERAL("a"))),
607 URLForPath(FilePath(FILE_PATH_LITERAL("b"))),
608 RecordStatusCallback());
609 MessageLoop::current()->RunAllPending();
610 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
611 EXPECT_TRUE(change_observer()->HasNoChange());
614 TEST_F(LocalFileSystemOperationTest
, TestCopyFailureContainsPath
) {
615 FilePath
src_dir_path(CreateUniqueDir());
616 FilePath
dest_dir_path(CreateUniqueDirInDir(src_dir_path
));
617 operation()->Copy(URLForPath(src_dir_path
), URLForPath(dest_dir_path
),
618 RecordStatusCallback());
619 MessageLoop::current()->RunAllPending();
620 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION
, status());
621 EXPECT_TRUE(change_observer()->HasNoChange());
624 TEST_F(LocalFileSystemOperationTest
, TestCopyFailureSrcDirExistsDestFile
) {
625 // Src exists and is dir. Dest is a file.
626 FilePath
src_dir_path(CreateUniqueDir());
627 FilePath
dest_dir_path(CreateUniqueDir());
628 FilePath
dest_file_path(CreateUniqueFileInDir(dest_dir_path
));
630 operation()->Copy(URLForPath(src_dir_path
), URLForPath(dest_file_path
),
631 RecordStatusCallback());
632 MessageLoop::current()->RunAllPending();
633 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION
, status());
634 EXPECT_TRUE(change_observer()->HasNoChange());
637 TEST_F(LocalFileSystemOperationTest
,
638 TestCopyFailureSrcFileExistsDestNonEmptyDir
) {
639 // Src exists and is a directory. Dest is a non-empty directory.
640 FilePath
src_dir_path(CreateUniqueDir());
641 FilePath
dest_dir_path(CreateUniqueDir());
642 FilePath
child_file_path(CreateUniqueFileInDir(dest_dir_path
));
644 operation()->Copy(URLForPath(src_dir_path
), URLForPath(dest_dir_path
),
645 RecordStatusCallback());
646 MessageLoop::current()->RunAllPending();
647 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY
, status());
648 EXPECT_TRUE(change_observer()->HasNoChange());
651 TEST_F(LocalFileSystemOperationTest
, TestCopyFailureSrcFileExistsDestDir
) {
652 // Src exists and is a file. Dest is a directory.
653 FilePath
src_dir_path(CreateUniqueDir());
654 FilePath
src_file_path(CreateUniqueFileInDir(src_dir_path
));
655 FilePath
dest_dir_path(CreateUniqueDir());
657 operation()->Copy(URLForPath(src_file_path
), URLForPath(dest_dir_path
),
658 RecordStatusCallback());
659 MessageLoop::current()->RunAllPending();
660 EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION
, status());
661 EXPECT_TRUE(change_observer()->HasNoChange());
664 TEST_F(LocalFileSystemOperationTest
, TestCopyFailureDestParentDoesntExist
) {
665 // Dest. parent path does not exist.
666 FilePath
src_dir_path(CreateUniqueDir());
667 FilePath nonexisting_path
= FilePath(FILE_PATH_LITERAL("DontExistDir"));
668 file_util::EnsureEndsWithSeparator(&nonexisting_path
);
669 FilePath
nonexisting_file_path(nonexisting_path
.Append(
670 FILE_PATH_LITERAL("DontExistFile")));
672 operation()->Copy(URLForPath(src_dir_path
),
673 URLForPath(nonexisting_file_path
),
674 RecordStatusCallback());
675 MessageLoop::current()->RunAllPending();
676 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
677 EXPECT_TRUE(change_observer()->HasNoChange());
680 TEST_F(LocalFileSystemOperationTest
, TestCopyFailureByQuota
) {
681 base::PlatformFileInfo info
;
683 FilePath
src_dir_path(CreateUniqueDir());
684 FilePath
src_file_path(CreateUniqueFileInDir(src_dir_path
));
685 FilePath
dest_dir_path(CreateUniqueDir());
687 FilePath dest_file_path
;
688 int64 dest_path_cost
;
689 GenerateUniquePathInDir(dest_dir_path
, &dest_file_path
, &dest_path_cost
);
691 GrantQuotaForCurrentUsage();
694 operation()->Truncate(URLForPath(src_file_path
), 6,
695 RecordStatusCallback());
696 MessageLoop::current()->RunAllPending();
697 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
699 AddQuota(6 + dest_path_cost
- 1);
701 EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(src_file_path
), &info
));
702 EXPECT_EQ(6, info
.size
);
704 operation()->Copy(URLForPath(src_file_path
), URLForPath(dest_file_path
),
705 RecordStatusCallback());
706 MessageLoop::current()->RunAllPending();
707 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
, status());
708 EXPECT_FALSE(FileExists(dest_file_path
));
711 TEST_F(LocalFileSystemOperationTest
, TestCopySuccessSrcFileAndOverwrite
) {
712 FilePath
src_dir_path(CreateUniqueDir());
713 FilePath
src_file_path(CreateUniqueFileInDir(src_dir_path
));
714 FilePath
dest_dir_path(CreateUniqueDir());
715 FilePath
dest_file_path(CreateUniqueFileInDir(dest_dir_path
));
717 operation()->Copy(URLForPath(src_file_path
), URLForPath(dest_file_path
),
718 RecordStatusCallback());
719 MessageLoop::current()->RunAllPending();
720 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
721 EXPECT_TRUE(FileExists(dest_file_path
));
722 EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
724 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
725 EXPECT_TRUE(change_observer()->HasNoChange());
728 TEST_F(LocalFileSystemOperationTest
, TestCopySuccessSrcFileAndNew
) {
729 FilePath
src_dir_path(CreateUniqueDir());
730 FilePath
src_file_path(CreateUniqueFileInDir(src_dir_path
));
731 FilePath
dest_dir_path(CreateUniqueDir());
732 FilePath
dest_file_path(dest_dir_path
.Append(FILE_PATH_LITERAL("NewFile")));
734 operation()->Copy(URLForPath(src_file_path
), URLForPath(dest_file_path
),
735 RecordStatusCallback());
736 MessageLoop::current()->RunAllPending();
737 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
738 EXPECT_TRUE(FileExists(dest_file_path
));
739 EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
741 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
742 EXPECT_TRUE(change_observer()->HasNoChange());
745 TEST_F(LocalFileSystemOperationTest
, TestCopySuccessSrcDirAndOverwrite
) {
746 FilePath
src_dir_path(CreateUniqueDir());
747 FilePath
dest_dir_path(CreateUniqueDir());
749 operation()->Copy(URLForPath(src_dir_path
), URLForPath(dest_dir_path
),
750 RecordStatusCallback());
751 MessageLoop::current()->RunAllPending();
752 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
754 // Make sure we've overwritten but not copied the source under the |dest_dir|.
755 EXPECT_TRUE(DirectoryExists(dest_dir_path
));
756 EXPECT_FALSE(DirectoryExists(
757 dest_dir_path
.Append(VirtualPath::BaseName(src_dir_path
))));
758 EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
760 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
761 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
762 EXPECT_TRUE(change_observer()->HasNoChange());
765 TEST_F(LocalFileSystemOperationTest
, TestCopySuccessSrcDirAndNew
) {
766 FilePath
src_dir_path(CreateUniqueDir());
767 FilePath
dest_parent_dir_path(CreateUniqueDir());
768 FilePath
dest_child_dir_path(dest_parent_dir_path
.
769 Append(FILE_PATH_LITERAL("NewDirectory")));
771 operation()->Copy(URLForPath(src_dir_path
), URLForPath(dest_child_dir_path
),
772 RecordStatusCallback());
773 MessageLoop::current()->RunAllPending();
774 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
775 EXPECT_TRUE(DirectoryExists(dest_child_dir_path
));
776 EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
778 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
779 EXPECT_TRUE(change_observer()->HasNoChange());
782 TEST_F(LocalFileSystemOperationTest
, TestCopySuccessSrcDirRecursive
) {
783 FilePath
src_dir_path(CreateUniqueDir());
784 FilePath
child_dir_path(CreateUniqueDirInDir(src_dir_path
));
785 FilePath
grandchild_file_path(
786 CreateUniqueFileInDir(child_dir_path
));
788 FilePath
dest_dir_path(CreateUniqueDir());
789 operation()->Copy(URLForPath(src_dir_path
), URLForPath(dest_dir_path
),
790 RecordStatusCallback());
791 MessageLoop::current()->RunAllPending();
792 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
793 EXPECT_TRUE(DirectoryExists(dest_dir_path
.Append(
794 VirtualPath::BaseName(child_dir_path
))));
795 EXPECT_TRUE(FileExists(dest_dir_path
.Append(
796 VirtualPath::BaseName(child_dir_path
)).Append(
797 VirtualPath::BaseName(grandchild_file_path
))));
798 EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
800 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
801 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
802 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
803 EXPECT_TRUE(change_observer()->HasNoChange());
806 TEST_F(LocalFileSystemOperationTest
, TestCopyInForeignFileSuccess
) {
807 FilePath src_local_disk_file_path
;
808 file_util::CreateTemporaryFile(&src_local_disk_file_path
);
809 const char test_data
[] = "foo";
810 int data_size
= ARRAYSIZE_UNSAFE(test_data
);
811 file_util::WriteFile(src_local_disk_file_path
, test_data
, data_size
);
812 FilePath
dest_dir_path(CreateUniqueDir());
813 FilePath
dest_file_path(dest_dir_path
.Append(
814 src_local_disk_file_path
.BaseName()));
815 FileSystemURL dest_file_url
= URLForPath(dest_file_path
);
817 GetUsageAndQuota(&before_usage
, NULL
);
819 // Check that the file copied and corresponding usage increased.
820 operation()->CopyInForeignFile(src_local_disk_file_path
,
822 RecordStatusCallback());
823 MessageLoop::current()->RunAllPending();
824 EXPECT_EQ(1, change_observer()->create_file_count());
825 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
826 EXPECT_TRUE(FileExists(dest_file_path
));
828 GetUsageAndQuota(&after_usage
, NULL
);
829 EXPECT_GT(after_usage
, before_usage
);
831 // Compare contents of src and copied file.
833 EXPECT_EQ(data_size
, file_util::ReadFile(PlatformPath(dest_file_path
),
835 for (int i
= 0; i
< data_size
; ++i
)
836 EXPECT_EQ(test_data
[i
], buffer
[i
]);
839 TEST_F(LocalFileSystemOperationTest
, TestCopyInForeignFileFailureByQuota
) {
840 FilePath src_local_disk_file_path
;
841 file_util::CreateTemporaryFile(&src_local_disk_file_path
);
842 const char test_data
[] = "foo";
843 file_util::WriteFile(src_local_disk_file_path
, test_data
,
844 ARRAYSIZE_UNSAFE(test_data
));
846 FilePath
dest_dir_path(CreateUniqueDir());
847 FilePath
dest_file_path(dest_dir_path
.Append(
848 src_local_disk_file_path
.BaseName()));
849 FileSystemURL dest_file_url
= URLForPath(dest_file_path
);
851 // Set quota of 0 which should force copy to fail by quota.
852 quota_manager_proxy()->SetQuota(dest_file_url
.origin(),
853 test_helper_
.storage_type(),
854 static_cast<int64
>(0));
855 operation()->CopyInForeignFile(src_local_disk_file_path
,
857 RecordStatusCallback());
858 MessageLoop::current()->RunAllPending();
860 EXPECT_TRUE(!FileExists(dest_file_path
));
861 EXPECT_EQ(0, change_observer()->create_file_count());
862 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
, status());
865 TEST_F(LocalFileSystemOperationTest
, TestCreateFileFailure
) {
866 // Already existing file and exclusive true.
867 FilePath
dir_path(CreateUniqueDir());
868 FilePath
file_path(CreateUniqueFileInDir(dir_path
));
869 operation()->CreateFile(URLForPath(file_path
), true,
870 RecordStatusCallback());
871 MessageLoop::current()->RunAllPending();
872 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
, status());
873 EXPECT_TRUE(change_observer()->HasNoChange());
876 TEST_F(LocalFileSystemOperationTest
, TestCreateFileSuccessFileExists
) {
877 // Already existing file and exclusive false.
878 FilePath
dir_path(CreateUniqueDir());
879 FilePath
file_path(CreateUniqueFileInDir(dir_path
));
880 operation()->CreateFile(URLForPath(file_path
), false,
881 RecordStatusCallback());
882 MessageLoop::current()->RunAllPending();
883 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
884 EXPECT_TRUE(FileExists(file_path
));
886 // The file was already there; did nothing.
887 EXPECT_TRUE(change_observer()->HasNoChange());
890 TEST_F(LocalFileSystemOperationTest
, TestCreateFileSuccessExclusive
) {
891 // File doesn't exist but exclusive is true.
892 FilePath
dir_path(CreateUniqueDir());
893 FilePath
file_path(dir_path
.Append(FILE_PATH_LITERAL("FileDoesntExist")));
894 operation()->CreateFile(URLForPath(file_path
), true,
895 RecordStatusCallback());
896 MessageLoop::current()->RunAllPending();
897 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
898 EXPECT_TRUE(FileExists(file_path
));
899 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
902 TEST_F(LocalFileSystemOperationTest
, TestCreateFileSuccessFileDoesntExist
) {
903 // Non existing file.
904 FilePath
dir_path(CreateUniqueDir());
905 FilePath
file_path(dir_path
.Append(FILE_PATH_LITERAL("FileDoesntExist")));
906 operation()->CreateFile(URLForPath(file_path
), false,
907 RecordStatusCallback());
908 MessageLoop::current()->RunAllPending();
909 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
910 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
913 TEST_F(LocalFileSystemOperationTest
,
914 TestCreateDirFailureDestParentDoesntExist
) {
915 // Dest. parent path does not exist.
916 FilePath
nonexisting_path(FilePath(
917 FILE_PATH_LITERAL("DirDoesntExist")));
918 FilePath
nonexisting_file_path(nonexisting_path
.Append(
919 FILE_PATH_LITERAL("FileDoesntExist")));
920 operation()->CreateDirectory(URLForPath(nonexisting_file_path
), false, false,
921 RecordStatusCallback());
922 MessageLoop::current()->RunAllPending();
923 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
924 EXPECT_TRUE(change_observer()->HasNoChange());
927 TEST_F(LocalFileSystemOperationTest
, TestCreateDirFailureDirExists
) {
928 // Exclusive and dir existing at path.
929 FilePath
src_dir_path(CreateUniqueDir());
930 operation()->CreateDirectory(URLForPath(src_dir_path
), true, false,
931 RecordStatusCallback());
932 MessageLoop::current()->RunAllPending();
933 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
, status());
934 EXPECT_TRUE(change_observer()->HasNoChange());
937 TEST_F(LocalFileSystemOperationTest
, TestCreateDirFailureFileExists
) {
938 // Exclusive true and file existing at path.
939 FilePath
dir_path(CreateUniqueDir());
940 FilePath
file_path(CreateUniqueFileInDir(dir_path
));
941 operation()->CreateDirectory(URLForPath(file_path
), true, false,
942 RecordStatusCallback());
943 MessageLoop::current()->RunAllPending();
944 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS
, status());
945 EXPECT_TRUE(change_observer()->HasNoChange());
948 TEST_F(LocalFileSystemOperationTest
, TestCreateDirSuccess
) {
949 // Dir exists and exclusive is false.
950 FilePath
dir_path(CreateUniqueDir());
951 operation()->CreateDirectory(URLForPath(dir_path
), false, false,
952 RecordStatusCallback());
953 MessageLoop::current()->RunAllPending();
954 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
955 EXPECT_TRUE(change_observer()->HasNoChange());
957 // Dir doesn't exist.
958 FilePath
nonexisting_dir_path(FilePath(
959 FILE_PATH_LITERAL("nonexistingdir")));
960 operation()->CreateDirectory(URLForPath(nonexisting_dir_path
), false, false,
961 RecordStatusCallback());
962 MessageLoop::current()->RunAllPending();
963 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
964 EXPECT_TRUE(DirectoryExists(nonexisting_dir_path
));
965 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
968 TEST_F(LocalFileSystemOperationTest
, TestCreateDirSuccessExclusive
) {
969 // Dir doesn't exist.
970 FilePath
nonexisting_dir_path(FilePath(
971 FILE_PATH_LITERAL("nonexistingdir")));
973 operation()->CreateDirectory(URLForPath(nonexisting_dir_path
), true, false,
974 RecordStatusCallback());
975 MessageLoop::current()->RunAllPending();
976 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
977 EXPECT_TRUE(DirectoryExists(nonexisting_dir_path
));
978 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
979 EXPECT_TRUE(change_observer()->HasNoChange());
982 TEST_F(LocalFileSystemOperationTest
, TestExistsAndMetadataFailure
) {
983 FilePath
nonexisting_dir_path(FilePath(
984 FILE_PATH_LITERAL("nonexistingdir")));
985 operation()->GetMetadata(URLForPath(nonexisting_dir_path
),
986 RecordMetadataCallback());
987 MessageLoop::current()->RunAllPending();
988 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
990 operation()->FileExists(URLForPath(nonexisting_dir_path
),
991 RecordStatusCallback());
992 MessageLoop::current()->RunAllPending();
993 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
995 file_util::EnsureEndsWithSeparator(&nonexisting_dir_path
);
996 operation()->DirectoryExists(URLForPath(nonexisting_dir_path
),
997 RecordStatusCallback());
998 MessageLoop::current()->RunAllPending();
999 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
1000 EXPECT_TRUE(change_observer()->HasNoChange());
1003 TEST_F(LocalFileSystemOperationTest
, TestExistsAndMetadataSuccess
) {
1004 FilePath
dir_path(CreateUniqueDir());
1005 int read_access
= 0;
1007 operation()->DirectoryExists(URLForPath(dir_path
),
1008 RecordStatusCallback());
1009 MessageLoop::current()->RunAllPending();
1010 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1013 operation()->GetMetadata(URLForPath(dir_path
), RecordMetadataCallback());
1014 MessageLoop::current()->RunAllPending();
1015 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1016 EXPECT_TRUE(info().is_directory
);
1017 EXPECT_EQ(FilePath(), path());
1020 FilePath
file_path(CreateUniqueFileInDir(dir_path
));
1021 operation()->FileExists(URLForPath(file_path
), RecordStatusCallback());
1022 MessageLoop::current()->RunAllPending();
1023 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1026 operation()->GetMetadata(URLForPath(file_path
), RecordMetadataCallback());
1027 MessageLoop::current()->RunAllPending();
1028 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1029 EXPECT_FALSE(info().is_directory
);
1030 EXPECT_EQ(PlatformPath(file_path
), path());
1033 EXPECT_EQ(read_access
, quota_manager_proxy()->storage_accessed_count());
1034 EXPECT_TRUE(change_observer()->HasNoChange());
1037 TEST_F(LocalFileSystemOperationTest
, TestTypeMismatchErrors
) {
1038 FilePath
dir_path(CreateUniqueDir());
1039 operation()->FileExists(URLForPath(dir_path
), RecordStatusCallback());
1040 MessageLoop::current()->RunAllPending();
1041 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_FILE
, status());
1043 FilePath
file_path(CreateUniqueFileInDir(dir_path
));
1044 ASSERT_FALSE(file_path
.empty());
1045 operation()->DirectoryExists(URLForPath(file_path
), RecordStatusCallback());
1046 MessageLoop::current()->RunAllPending();
1047 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY
, status());
1050 TEST_F(LocalFileSystemOperationTest
, TestReadDirFailure
) {
1051 // Path doesn't exist
1052 FilePath
nonexisting_dir_path(FilePath(
1053 FILE_PATH_LITERAL("NonExistingDir")));
1054 file_util::EnsureEndsWithSeparator(&nonexisting_dir_path
);
1055 operation()->ReadDirectory(URLForPath(nonexisting_dir_path
),
1056 RecordReadDirectoryCallback());
1057 MessageLoop::current()->RunAllPending();
1058 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
1061 FilePath
dir_path(CreateUniqueDir());
1062 FilePath
file_path(CreateUniqueFileInDir(dir_path
));
1063 operation()->ReadDirectory(URLForPath(file_path
),
1064 RecordReadDirectoryCallback());
1065 MessageLoop::current()->RunAllPending();
1066 // TODO(kkanetkar) crbug.com/54309 to change the error code.
1067 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
1068 EXPECT_TRUE(change_observer()->HasNoChange());
1071 TEST_F(LocalFileSystemOperationTest
, TestReadDirSuccess
) {
1074 // child_dir child_file
1075 // Verify reading parent_dir.
1076 FilePath
parent_dir_path(CreateUniqueDir());
1077 FilePath
child_file_path(CreateUniqueFileInDir(parent_dir_path
));
1078 FilePath
child_dir_path(CreateUniqueDirInDir(parent_dir_path
));
1079 ASSERT_FALSE(child_dir_path
.empty());
1081 operation()->ReadDirectory(URLForPath(parent_dir_path
),
1082 RecordReadDirectoryCallback());
1083 MessageLoop::current()->RunAllPending();
1084 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1085 EXPECT_EQ(2u, entries().size());
1087 for (size_t i
= 0; i
< entries().size(); ++i
) {
1088 if (entries()[i
].is_directory
) {
1089 EXPECT_EQ(VirtualPath::BaseName(child_dir_path
).value(),
1092 EXPECT_EQ(VirtualPath::BaseName(child_file_path
).value(),
1096 EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
1097 EXPECT_TRUE(change_observer()->HasNoChange());
1100 TEST_F(LocalFileSystemOperationTest
, TestRemoveFailure
) {
1101 // Path doesn't exist.
1102 FilePath
nonexisting_path(FilePath(
1103 FILE_PATH_LITERAL("NonExistingDir")));
1104 file_util::EnsureEndsWithSeparator(&nonexisting_path
);
1106 operation()->Remove(URLForPath(nonexisting_path
), false /* recursive */,
1107 RecordStatusCallback());
1108 MessageLoop::current()->RunAllPending();
1109 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND
, status());
1111 // It's an error to try to remove a non-empty directory if recursive flag
1115 // child_dir child_file
1116 // Verify deleting parent_dir.
1117 FilePath
parent_dir_path(CreateUniqueDir());
1118 FilePath
child_file_path(CreateUniqueFileInDir(parent_dir_path
));
1119 FilePath
child_dir_path(CreateUniqueDirInDir(parent_dir_path
));
1120 ASSERT_FALSE(child_dir_path
.empty());
1122 operation()->Remove(URLForPath(parent_dir_path
), false /* recursive */,
1123 RecordStatusCallback());
1124 MessageLoop::current()->RunAllPending();
1125 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY
,
1127 EXPECT_TRUE(change_observer()->HasNoChange());
1130 TEST_F(LocalFileSystemOperationTest
, TestRemoveSuccess
) {
1131 FilePath
empty_dir_path(CreateUniqueDir());
1132 EXPECT_TRUE(DirectoryExists(empty_dir_path
));
1134 operation()->Remove(URLForPath(empty_dir_path
), false /* recursive */,
1135 RecordStatusCallback());
1136 MessageLoop::current()->RunAllPending();
1137 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1138 EXPECT_FALSE(DirectoryExists(empty_dir_path
));
1140 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
1141 EXPECT_TRUE(change_observer()->HasNoChange());
1143 // Removing a non-empty directory with recursive flag == true should be ok.
1146 // child_dir child_file
1147 // Verify deleting parent_dir.
1148 FilePath
parent_dir_path(CreateUniqueDir());
1149 FilePath
child_file_path(CreateUniqueFileInDir(parent_dir_path
));
1150 FilePath
child_dir_path(CreateUniqueDirInDir(parent_dir_path
));
1151 ASSERT_FALSE(child_dir_path
.empty());
1153 operation()->Remove(URLForPath(parent_dir_path
), true /* recursive */,
1154 RecordStatusCallback());
1155 MessageLoop::current()->RunAllPending();
1156 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1157 EXPECT_FALSE(DirectoryExists(parent_dir_path
));
1159 // Remove is not a 'read' access.
1160 EXPECT_EQ(0, quota_manager_proxy()->storage_accessed_count());
1162 EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count());
1163 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
1164 EXPECT_TRUE(change_observer()->HasNoChange());
1167 TEST_F(LocalFileSystemOperationTest
, TestTruncate
) {
1168 FilePath
dir_path(CreateUniqueDir());
1169 FilePath
file_path(CreateUniqueFileInDir(dir_path
));
1171 char test_data
[] = "test data";
1172 int data_size
= static_cast<int>(sizeof(test_data
));
1173 EXPECT_EQ(data_size
,
1174 file_util::WriteFile(PlatformPath(file_path
),
1175 test_data
, data_size
));
1177 // Check that its length is the size of the data written.
1178 operation()->GetMetadata(URLForPath(file_path
), RecordMetadataCallback());
1179 MessageLoop::current()->RunAllPending();
1180 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1181 EXPECT_FALSE(info().is_directory
);
1182 EXPECT_EQ(data_size
, info().size
);
1184 // Extend the file by truncating it.
1186 operation()->Truncate(URLForPath(file_path
), length
, RecordStatusCallback());
1187 MessageLoop::current()->RunAllPending();
1188 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1190 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1191 EXPECT_TRUE(change_observer()->HasNoChange());
1193 // Check that its length is now 17 and that it's all zeroes after the test
1195 base::PlatformFileInfo info
;
1197 EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path
), &info
));
1198 EXPECT_EQ(length
, info
.size
);
1200 EXPECT_EQ(length
, file_util::ReadFile(PlatformPath(file_path
), data
, length
));
1201 for (int i
= 0; i
< length
; ++i
) {
1202 if (i
< static_cast<int>(sizeof(test_data
)))
1203 EXPECT_EQ(test_data
[i
], data
[i
]);
1205 EXPECT_EQ(0, data
[i
]);
1208 // Shorten the file by truncating it.
1210 operation()->Truncate(URLForPath(file_path
), length
, RecordStatusCallback());
1211 MessageLoop::current()->RunAllPending();
1212 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1214 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1215 EXPECT_TRUE(change_observer()->HasNoChange());
1217 // Check that its length is now 3 and that it contains only bits of test data.
1218 EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path
), &info
));
1219 EXPECT_EQ(length
, info
.size
);
1220 EXPECT_EQ(length
, file_util::ReadFile(PlatformPath(file_path
), data
, length
));
1221 for (int i
= 0; i
< length
; ++i
)
1222 EXPECT_EQ(test_data
[i
], data
[i
]);
1224 // Truncate is not a 'read' access. (Here expected access count is 1
1225 // since we made 1 read access for GetMetadata.)
1226 EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
1229 TEST_F(LocalFileSystemOperationTest
, TestTruncateFailureByQuota
) {
1230 base::PlatformFileInfo info
;
1232 FilePath
dir_path(CreateUniqueDir());
1233 FilePath
file_path(CreateUniqueFileInDir(dir_path
));
1235 GrantQuotaForCurrentUsage();
1238 operation()->Truncate(URLForPath(file_path
), 10, RecordStatusCallback());
1239 MessageLoop::current()->RunAllPending();
1240 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1241 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1242 EXPECT_TRUE(change_observer()->HasNoChange());
1244 EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path
), &info
));
1245 EXPECT_EQ(10, info
.size
);
1247 operation()->Truncate(URLForPath(file_path
), 11, RecordStatusCallback());
1248 MessageLoop::current()->RunAllPending();
1249 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE
, status());
1250 EXPECT_TRUE(change_observer()->HasNoChange());
1252 EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path
), &info
));
1253 EXPECT_EQ(10, info
.size
);
1256 TEST_F(LocalFileSystemOperationTest
, TestTouchFile
) {
1257 FilePath
file_path(CreateUniqueFileInDir(FilePath()));
1258 FilePath platform_path
= PlatformPath(file_path
);
1260 base::PlatformFileInfo info
;
1262 EXPECT_TRUE(file_util::GetFileInfo(platform_path
, &info
));
1263 EXPECT_FALSE(info
.is_directory
);
1264 EXPECT_EQ(0, info
.size
);
1265 const base::Time last_modified
= info
.last_modified
;
1266 const base::Time last_accessed
= info
.last_accessed
;
1268 const base::Time new_modified_time
= base::Time::UnixEpoch();
1269 const base::Time new_accessed_time
= new_modified_time
+
1270 base::TimeDelta::FromHours(77);
1271 ASSERT_NE(last_modified
, new_modified_time
);
1272 ASSERT_NE(last_accessed
, new_accessed_time
);
1274 operation()->TouchFile(
1275 URLForPath(file_path
), new_accessed_time
, new_modified_time
,
1276 RecordStatusCallback());
1277 MessageLoop::current()->RunAllPending();
1278 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1279 EXPECT_TRUE(change_observer()->HasNoChange());
1281 EXPECT_TRUE(file_util::GetFileInfo(platform_path
, &info
));
1282 // We compare as time_t here to lower our resolution, to avoid false
1283 // negatives caused by conversion to the local filesystem's native
1284 // representation and back.
1285 EXPECT_EQ(new_modified_time
.ToTimeT(), info
.last_modified
.ToTimeT());
1286 EXPECT_EQ(new_accessed_time
.ToTimeT(), info
.last_accessed
.ToTimeT());
1289 TEST_F(LocalFileSystemOperationTest
, TestCreateSnapshotFile
) {
1290 FilePath
dir_path(CreateUniqueDir());
1292 // Create a file for the testing.
1293 operation()->DirectoryExists(URLForPath(dir_path
),
1294 RecordStatusCallback());
1295 FilePath
file_path(CreateUniqueFileInDir(dir_path
));
1296 operation()->FileExists(URLForPath(file_path
), RecordStatusCallback());
1297 MessageLoop::current()->RunAllPending();
1298 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1300 // See if we can get a 'snapshot' file info for the file.
1301 // Since LocalFileSystemOperation assumes the file exists in the local
1302 // directory it should just returns the same metadata and platform_path
1303 // as the file itself.
1304 operation()->CreateSnapshotFile(URLForPath(file_path
),
1305 RecordSnapshotFileCallback());
1306 MessageLoop::current()->RunAllPending();
1307 EXPECT_EQ(base::PLATFORM_FILE_OK
, status());
1308 EXPECT_FALSE(info().is_directory
);
1309 EXPECT_EQ(PlatformPath(file_path
), path());
1310 EXPECT_TRUE(change_observer()->HasNoChange());
1312 // The FileSystemOpration implementation does not create a
1313 // shareable file reference.
1314 EXPECT_EQ(NULL
, shareable_file_ref());
1317 } // namespace fileapi