Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / browser / fileapi / file_system_operation_impl_unittest.cc
blobafbe664aaf2b3233a9ded3ebfd43aab94a848997
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"
7 #include "base/bind.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/browser/quota/mock_quota_manager.h"
17 #include "content/browser/quota/mock_quota_manager_proxy.h"
18 #include "content/public/test/async_file_test_helper.h"
19 #include "content/public/test/sandbox_file_system_test_helper.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "url/gurl.h"
22 #include "webkit/browser/fileapi/file_system_context.h"
23 #include "webkit/browser/fileapi/file_system_file_util.h"
24 #include "webkit/browser/fileapi/file_system_operation_context.h"
25 #include "webkit/browser/fileapi/file_system_operation_runner.h"
26 #include "webkit/browser/fileapi/sandbox_file_system_backend.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 storage::FileSystemOperation;
34 using storage::FileSystemOperationContext;
35 using storage::FileSystemOperationRunner;
36 using storage::FileSystemURL;
37 using storage::QuotaManager;
38 using storage::QuotaManagerProxy;
39 using storage::ShareableFileReference;
41 namespace content {
43 namespace {
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();
53 } // namespace
55 // Test class for FileSystemOperationImpl.
56 class FileSystemOperationImplTest
57 : public testing::Test {
58 public:
59 FileSystemOperationImplTest()
60 : status_(kFileOperationStatusNotSet),
61 weak_factory_(this) {}
63 protected:
64 virtual void SetUp() OVERRIDE {
65 EXPECT_TRUE(base_.CreateUniqueTempDir());
66 change_observers_ =
67 storage::MockFileChangeObserver::CreateList(&change_observer_);
69 base::FilePath base_dir = base_.path().AppendASCII("filesystem");
70 quota_manager_ =
71 new MockQuotaManager(false /* is_incognito */,
72 base_dir,
73 base::MessageLoopProxy::current().get(),
74 base::MessageLoopProxy::current().get(),
75 NULL /* special storage policy */);
76 quota_manager_proxy_ = new 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<storage::DirectoryEntry>& entries() const {
98 return entries_;
101 const ShareableFileReference* shareable_file_ref() const {
102 return shareable_file_ref_.get();
105 MockQuotaManager* quota_manager() {
106 return static_cast<MockQuotaManager*>(quota_manager_.get());
109 MockQuotaManagerProxy* quota_manager_proxy() {
110 return static_cast<MockQuotaManagerProxy*>(
111 quota_manager_proxy_.get());
114 storage::FileSystemFileUtil* file_util() {
115 return sandbox_file_system_.file_util();
118 storage::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(),
155 url, &created));
156 EXPECT_TRUE(created);
157 return url;
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));
165 return url;
168 int64 GetFileSize(const std::string& path) {
169 base::File::Info info;
170 EXPECT_TRUE(base::GetFileInfo(PlatformPath(path), &info));
171 return info.size;
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) {
197 status_ = status;
200 void DidReadDirectory(base::File::Error status,
201 const std::vector<storage::DirectoryEntry>& entries,
202 bool /* has_more */) {
203 entries_ = entries;
204 status_ = status;
207 void DidGetMetadata(base::File::Error status,
208 const base::File::Info& info) {
209 info_ = info;
210 status_ = status;
213 void DidCreateSnapshotFile(
214 base::File::Error status,
215 const base::File::Info& info,
216 const base::FilePath& platform_path,
217 const scoped_refptr<ShareableFileReference>& shareable_file_ref) {
218 info_ = info;
219 path_ = platform_path;
220 status_ = status;
221 shareable_file_ref_ = shareable_file_ref;
224 int64 GetDataSizeOnDisk() {
225 return sandbox_file_system_.ComputeCurrentOriginUsage() -
226 sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage();
229 void GetUsageAndQuota(int64* usage, int64* quota) {
230 storage::QuotaStatusCode status =
231 AsyncFileTestHelper::GetUsageAndQuota(quota_manager_.get(),
232 sandbox_file_system_.origin(),
233 sandbox_file_system_.type(),
234 usage,
235 quota);
236 base::RunLoop().RunUntilIdle();
237 ASSERT_EQ(storage::kQuotaStatusOk, status);
240 int64 ComputePathCost(const FileSystemURL& url) {
241 int64 base_usage;
242 GetUsageAndQuota(&base_usage, NULL);
244 AsyncFileTestHelper::CreateFile(
245 sandbox_file_system_.file_system_context(), url);
246 operation_runner()->Remove(url, false /* recursive */,
247 base::Bind(&AssertFileErrorEq, FROM_HERE,
248 base::File::FILE_OK));
249 base::RunLoop().RunUntilIdle();
250 change_observer()->ResetCount();
252 int64 total_usage;
253 GetUsageAndQuota(&total_usage, NULL);
254 return total_usage - base_usage;
257 void GrantQuotaForCurrentUsage() {
258 int64 usage;
259 GetUsageAndQuota(&usage, NULL);
260 quota_manager()->SetQuota(sandbox_file_system_.origin(),
261 sandbox_file_system_.storage_type(),
262 usage);
265 int64 GetUsage() {
266 int64 usage = 0;
267 GetUsageAndQuota(&usage, NULL);
268 return usage;
271 void AddQuota(int64 quota_delta) {
272 int64 quota;
273 GetUsageAndQuota(NULL, &quota);
274 quota_manager()->SetQuota(sandbox_file_system_.origin(),
275 sandbox_file_system_.storage_type(),
276 quota + quota_delta);
279 private:
280 base::MessageLoop message_loop_;
281 scoped_refptr<QuotaManager> quota_manager_;
282 scoped_refptr<QuotaManagerProxy> quota_manager_proxy_;
284 // Common temp base for nondestructive uses.
285 base::ScopedTempDir base_;
287 SandboxFileSystemTestHelper sandbox_file_system_;
289 // For post-operation status.
290 int status_;
291 base::File::Info info_;
292 base::FilePath path_;
293 std::vector<storage::DirectoryEntry> entries_;
294 scoped_refptr<ShareableFileReference> shareable_file_ref_;
296 storage::MockFileChangeObserver change_observer_;
297 storage::ChangeObserverList change_observers_;
299 base::WeakPtrFactory<FileSystemOperationImplTest> weak_factory_;
301 DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImplTest);
304 TEST_F(FileSystemOperationImplTest, TestMoveFailureSrcDoesntExist) {
305 change_observer()->ResetCount();
306 operation_runner()->Move(URLForPath("a"), URLForPath("b"),
307 FileSystemOperation::OPTION_NONE,
308 RecordStatusCallback());
309 base::RunLoop().RunUntilIdle();
310 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status());
311 EXPECT_TRUE(change_observer()->HasNoChange());
314 TEST_F(FileSystemOperationImplTest, TestMoveFailureContainsPath) {
315 FileSystemURL src_dir(CreateDirectory("src"));
316 FileSystemURL dest_dir(CreateDirectory("src/dest"));
318 operation_runner()->Move(src_dir, dest_dir,
319 FileSystemOperation::OPTION_NONE,
320 RecordStatusCallback());
321 base::RunLoop().RunUntilIdle();
322 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, status());
323 EXPECT_TRUE(change_observer()->HasNoChange());
326 TEST_F(FileSystemOperationImplTest, TestMoveFailureSrcDirExistsDestFile) {
327 // Src exists and is dir. Dest is a file.
328 FileSystemURL src_dir(CreateDirectory("src"));
329 FileSystemURL dest_dir(CreateDirectory("dest"));
330 FileSystemURL dest_file(CreateFile("dest/file"));
332 operation_runner()->Move(src_dir, dest_file,
333 FileSystemOperation::OPTION_NONE,
334 RecordStatusCallback());
335 base::RunLoop().RunUntilIdle();
336 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, status());
337 EXPECT_TRUE(change_observer()->HasNoChange());
340 TEST_F(FileSystemOperationImplTest,
341 TestMoveFailureSrcFileExistsDestNonEmptyDir) {
342 // Src exists and is a directory. Dest is a non-empty directory.
343 FileSystemURL src_dir(CreateDirectory("src"));
344 FileSystemURL dest_dir(CreateDirectory("dest"));
345 FileSystemURL dest_file(CreateFile("dest/file"));
347 operation_runner()->Move(src_dir, dest_dir,
348 FileSystemOperation::OPTION_NONE,
349 RecordStatusCallback());
350 base::RunLoop().RunUntilIdle();
351 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY, status());
352 EXPECT_TRUE(change_observer()->HasNoChange());
355 TEST_F(FileSystemOperationImplTest, TestMoveFailureSrcFileExistsDestDir) {
356 // Src exists and is a file. Dest is a directory.
357 FileSystemURL src_dir(CreateDirectory("src"));
358 FileSystemURL src_file(CreateFile("src/file"));
359 FileSystemURL dest_dir(CreateDirectory("dest"));
361 operation_runner()->Move(src_file, dest_dir,
362 FileSystemOperation::OPTION_NONE,
363 RecordStatusCallback());
364 base::RunLoop().RunUntilIdle();
365 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, status());
366 EXPECT_TRUE(change_observer()->HasNoChange());
369 TEST_F(FileSystemOperationImplTest, TestMoveFailureDestParentDoesntExist) {
370 // Dest. parent path does not exist.
371 FileSystemURL src_dir(CreateDirectory("src"));
372 operation_runner()->Move(src_dir, URLForPath("nonexistent/deset"),
373 FileSystemOperation::OPTION_NONE,
374 RecordStatusCallback());
375 base::RunLoop().RunUntilIdle();
376 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status());
377 EXPECT_TRUE(change_observer()->HasNoChange());
380 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSrcFileAndOverwrite) {
381 FileSystemURL src_file(CreateFile("src"));
382 FileSystemURL dest_file(CreateFile("dest"));
384 operation_runner()->Move(src_file, dest_file,
385 FileSystemOperation::OPTION_NONE,
386 RecordStatusCallback());
387 base::RunLoop().RunUntilIdle();
388 EXPECT_EQ(base::File::FILE_OK, status());
389 EXPECT_TRUE(FileExists("dest"));
391 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
392 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
393 EXPECT_TRUE(change_observer()->HasNoChange());
395 EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count());
398 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSrcFileAndNew) {
399 FileSystemURL src_file(CreateFile("src"));
401 operation_runner()->Move(src_file, URLForPath("new"),
402 FileSystemOperation::OPTION_NONE,
403 RecordStatusCallback());
404 base::RunLoop().RunUntilIdle();
405 EXPECT_EQ(base::File::FILE_OK, status());
406 EXPECT_TRUE(FileExists("new"));
408 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
409 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
410 EXPECT_TRUE(change_observer()->HasNoChange());
413 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSrcDirAndOverwrite) {
414 FileSystemURL src_dir(CreateDirectory("src"));
415 FileSystemURL dest_dir(CreateDirectory("dest"));
417 operation_runner()->Move(src_dir, dest_dir,
418 FileSystemOperation::OPTION_NONE,
419 RecordStatusCallback());
420 base::RunLoop().RunUntilIdle();
421 EXPECT_EQ(base::File::FILE_OK, status());
422 EXPECT_FALSE(DirectoryExists("src"));
424 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
425 EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count());
426 EXPECT_TRUE(change_observer()->HasNoChange());
428 // Make sure we've overwritten but not moved the source under the |dest_dir|.
429 EXPECT_TRUE(DirectoryExists("dest"));
430 EXPECT_FALSE(DirectoryExists("dest/src"));
433 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSrcDirAndNew) {
434 FileSystemURL src_dir(CreateDirectory("src"));
435 FileSystemURL dest_dir(CreateDirectory("dest"));
437 operation_runner()->Move(src_dir, URLForPath("dest/new"),
438 FileSystemOperation::OPTION_NONE,
439 RecordStatusCallback());
440 base::RunLoop().RunUntilIdle();
441 EXPECT_EQ(base::File::FILE_OK, status());
442 EXPECT_FALSE(DirectoryExists("src"));
443 EXPECT_TRUE(DirectoryExists("dest/new"));
445 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
446 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
447 EXPECT_TRUE(change_observer()->HasNoChange());
450 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSrcDirRecursive) {
451 FileSystemURL src_dir(CreateDirectory("src"));
452 CreateDirectory("src/dir");
453 CreateFile("src/dir/sub");
455 FileSystemURL dest_dir(CreateDirectory("dest"));
457 operation_runner()->Move(src_dir, dest_dir,
458 FileSystemOperation::OPTION_NONE,
459 RecordStatusCallback());
460 base::RunLoop().RunUntilIdle();
461 EXPECT_EQ(base::File::FILE_OK, status());
462 EXPECT_TRUE(DirectoryExists("dest/dir"));
463 EXPECT_TRUE(FileExists("dest/dir/sub"));
465 EXPECT_EQ(3, change_observer()->get_and_reset_remove_directory_count());
466 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
467 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
468 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
469 EXPECT_TRUE(change_observer()->HasNoChange());
472 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSamePath) {
473 FileSystemURL src_dir(CreateDirectory("src"));
474 CreateDirectory("src/dir");
475 CreateFile("src/dir/sub");
477 operation_runner()->Move(src_dir, src_dir,
478 FileSystemOperation::OPTION_NONE,
479 RecordStatusCallback());
480 base::RunLoop().RunUntilIdle();
481 EXPECT_EQ(base::File::FILE_OK, status());
482 EXPECT_TRUE(DirectoryExists("src/dir"));
483 EXPECT_TRUE(FileExists("src/dir/sub"));
485 EXPECT_EQ(0, change_observer()->get_and_reset_remove_directory_count());
486 EXPECT_EQ(0, change_observer()->get_and_reset_create_directory_count());
487 EXPECT_EQ(0, change_observer()->get_and_reset_remove_file_count());
488 EXPECT_EQ(0, change_observer()->get_and_reset_create_file_from_count());
489 EXPECT_TRUE(change_observer()->HasNoChange());
492 TEST_F(FileSystemOperationImplTest, TestCopyFailureSrcDoesntExist) {
493 operation_runner()->Copy(URLForPath("a"), URLForPath("b"),
494 FileSystemOperation::OPTION_NONE,
495 FileSystemOperationRunner::CopyProgressCallback(),
496 RecordStatusCallback());
497 base::RunLoop().RunUntilIdle();
498 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status());
499 EXPECT_TRUE(change_observer()->HasNoChange());
502 TEST_F(FileSystemOperationImplTest, TestCopyFailureContainsPath) {
503 FileSystemURL src_dir(CreateDirectory("src"));
504 FileSystemURL dest_dir(CreateDirectory("src/dir"));
506 operation_runner()->Copy(src_dir, dest_dir,
507 FileSystemOperation::OPTION_NONE,
508 FileSystemOperationRunner::CopyProgressCallback(),
509 RecordStatusCallback());
510 base::RunLoop().RunUntilIdle();
511 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, status());
512 EXPECT_TRUE(change_observer()->HasNoChange());
515 TEST_F(FileSystemOperationImplTest, TestCopyFailureSrcDirExistsDestFile) {
516 // Src exists and is dir. Dest is a file.
517 FileSystemURL src_dir(CreateDirectory("src"));
518 FileSystemURL dest_dir(CreateDirectory("dest"));
519 FileSystemURL dest_file(CreateFile("dest/file"));
521 operation_runner()->Copy(src_dir, dest_file,
522 FileSystemOperation::OPTION_NONE,
523 FileSystemOperationRunner::CopyProgressCallback(),
524 RecordStatusCallback());
525 base::RunLoop().RunUntilIdle();
526 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, status());
527 EXPECT_TRUE(change_observer()->HasNoChange());
530 TEST_F(FileSystemOperationImplTest,
531 TestCopyFailureSrcFileExistsDestNonEmptyDir) {
532 // Src exists and is a directory. Dest is a non-empty directory.
533 FileSystemURL src_dir(CreateDirectory("src"));
534 FileSystemURL dest_dir(CreateDirectory("dest"));
535 FileSystemURL dest_file(CreateFile("dest/file"));
537 operation_runner()->Copy(src_dir, dest_dir,
538 FileSystemOperation::OPTION_NONE,
539 FileSystemOperationRunner::CopyProgressCallback(),
540 RecordStatusCallback());
541 base::RunLoop().RunUntilIdle();
542 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY, status());
543 EXPECT_TRUE(change_observer()->HasNoChange());
546 TEST_F(FileSystemOperationImplTest, TestCopyFailureSrcFileExistsDestDir) {
547 // Src exists and is a file. Dest is a directory.
548 FileSystemURL src_file(CreateFile("src"));
549 FileSystemURL dest_dir(CreateDirectory("dest"));
551 operation_runner()->Copy(src_file, dest_dir,
552 FileSystemOperation::OPTION_NONE,
553 FileSystemOperationRunner::CopyProgressCallback(),
554 RecordStatusCallback());
555 base::RunLoop().RunUntilIdle();
556 EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION, status());
557 EXPECT_TRUE(change_observer()->HasNoChange());
560 TEST_F(FileSystemOperationImplTest, TestCopyFailureDestParentDoesntExist) {
561 // Dest. parent path does not exist.
562 FileSystemURL src_dir(CreateDirectory("src"));
564 operation_runner()->Copy(src_dir, URLForPath("nonexistent/dest"),
565 FileSystemOperation::OPTION_NONE,
566 FileSystemOperationRunner::CopyProgressCallback(),
567 RecordStatusCallback());
568 base::RunLoop().RunUntilIdle();
569 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status());
570 EXPECT_TRUE(change_observer()->HasNoChange());
573 TEST_F(FileSystemOperationImplTest, TestCopyFailureByQuota) {
574 FileSystemURL src_dir(CreateDirectory("src"));
575 FileSystemURL src_file(CreateFile("src/file"));
576 FileSystemURL dest_dir(CreateDirectory("dest"));
577 operation_runner()->Truncate(src_file, 6, RecordStatusCallback());
578 base::RunLoop().RunUntilIdle();
579 EXPECT_EQ(base::File::FILE_OK, status());
580 EXPECT_EQ(6, GetFileSize("src/file"));
582 FileSystemURL dest_file(URLForPath("dest/file"));
583 int64 dest_path_cost = ComputePathCost(dest_file);
584 GrantQuotaForCurrentUsage();
585 AddQuota(6 + dest_path_cost - 1);
587 operation_runner()->Copy(src_file, dest_file,
588 FileSystemOperation::OPTION_NONE,
589 FileSystemOperationRunner::CopyProgressCallback(),
590 RecordStatusCallback());
591 base::RunLoop().RunUntilIdle();
592 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE, status());
593 EXPECT_FALSE(FileExists("dest/file"));
596 TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcFileAndOverwrite) {
597 FileSystemURL src_file(CreateFile("src"));
598 FileSystemURL dest_file(CreateFile("dest"));
600 operation_runner()->Copy(src_file, dest_file,
601 FileSystemOperation::OPTION_NONE,
602 FileSystemOperationRunner::CopyProgressCallback(),
603 RecordStatusCallback());
604 base::RunLoop().RunUntilIdle();
605 EXPECT_EQ(base::File::FILE_OK, status());
606 EXPECT_TRUE(FileExists("dest"));
607 EXPECT_EQ(2, quota_manager_proxy()->notify_storage_accessed_count());
609 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
610 EXPECT_TRUE(change_observer()->HasNoChange());
613 TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcFileAndNew) {
614 FileSystemURL src_file(CreateFile("src"));
616 operation_runner()->Copy(src_file, URLForPath("new"),
617 FileSystemOperation::OPTION_NONE,
618 FileSystemOperationRunner::CopyProgressCallback(),
619 RecordStatusCallback());
620 base::RunLoop().RunUntilIdle();
621 EXPECT_EQ(base::File::FILE_OK, status());
622 EXPECT_TRUE(FileExists("new"));
623 EXPECT_EQ(2, quota_manager_proxy()->notify_storage_accessed_count());
625 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
626 EXPECT_TRUE(change_observer()->HasNoChange());
629 TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcDirAndOverwrite) {
630 FileSystemURL src_dir(CreateDirectory("src"));
631 FileSystemURL dest_dir(CreateDirectory("dest"));
633 operation_runner()->Copy(src_dir, dest_dir,
634 FileSystemOperation::OPTION_NONE,
635 FileSystemOperationRunner::CopyProgressCallback(),
636 RecordStatusCallback());
637 base::RunLoop().RunUntilIdle();
638 EXPECT_EQ(base::File::FILE_OK, status());
640 // Make sure we've overwritten but not copied the source under the |dest_dir|.
641 EXPECT_TRUE(DirectoryExists("dest"));
642 EXPECT_FALSE(DirectoryExists("dest/src"));
643 EXPECT_GE(quota_manager_proxy()->notify_storage_accessed_count(), 3);
645 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
646 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
647 EXPECT_TRUE(change_observer()->HasNoChange());
650 TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcDirAndNew) {
651 FileSystemURL src_dir(CreateDirectory("src"));
652 FileSystemURL dest_dir_new(URLForPath("dest"));
654 operation_runner()->Copy(src_dir, dest_dir_new,
655 FileSystemOperation::OPTION_NONE,
656 FileSystemOperationRunner::CopyProgressCallback(),
657 RecordStatusCallback());
658 base::RunLoop().RunUntilIdle();
659 EXPECT_EQ(base::File::FILE_OK, status());
660 EXPECT_TRUE(DirectoryExists("dest"));
661 EXPECT_GE(quota_manager_proxy()->notify_storage_accessed_count(), 2);
663 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
664 EXPECT_TRUE(change_observer()->HasNoChange());
667 TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcDirRecursive) {
668 FileSystemURL src_dir(CreateDirectory("src"));
669 CreateDirectory("src/dir");
670 CreateFile("src/dir/sub");
672 FileSystemURL dest_dir(CreateDirectory("dest"));
674 operation_runner()->Copy(src_dir, dest_dir,
675 FileSystemOperation::OPTION_NONE,
676 FileSystemOperationRunner::CopyProgressCallback(),
677 RecordStatusCallback());
678 base::RunLoop().RunUntilIdle();
680 EXPECT_EQ(base::File::FILE_OK, status());
681 EXPECT_TRUE(DirectoryExists("dest/dir"));
682 EXPECT_TRUE(FileExists("dest/dir/sub"));
684 // For recursive copy we may record multiple read access.
685 EXPECT_GE(quota_manager_proxy()->notify_storage_accessed_count(), 1);
687 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
688 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
689 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
690 EXPECT_TRUE(change_observer()->HasNoChange());
693 TEST_F(FileSystemOperationImplTest, TestCopySuccessSamePath) {
694 FileSystemURL src_dir(CreateDirectory("src"));
695 CreateDirectory("src/dir");
696 CreateFile("src/dir/sub");
698 operation_runner()->Copy(src_dir, src_dir,
699 FileSystemOperation::OPTION_NONE,
700 FileSystemOperationRunner::CopyProgressCallback(),
701 RecordStatusCallback());
702 base::RunLoop().RunUntilIdle();
704 EXPECT_EQ(base::File::FILE_OK, status());
705 EXPECT_TRUE(DirectoryExists("src/dir"));
706 EXPECT_TRUE(FileExists("src/dir/sub"));
708 EXPECT_EQ(0, change_observer()->get_and_reset_create_directory_count());
709 EXPECT_EQ(0, change_observer()->get_and_reset_remove_file_count());
710 EXPECT_EQ(0, change_observer()->get_and_reset_create_file_from_count());
711 EXPECT_TRUE(change_observer()->HasNoChange());
714 TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileSuccess) {
715 base::FilePath src_local_disk_file_path;
716 base::CreateTemporaryFile(&src_local_disk_file_path);
717 const char test_data[] = "foo";
718 int data_size = ARRAYSIZE_UNSAFE(test_data);
719 base::WriteFile(src_local_disk_file_path, test_data, data_size);
721 FileSystemURL dest_dir(CreateDirectory("dest"));
723 int64 before_usage;
724 GetUsageAndQuota(&before_usage, NULL);
726 // Check that the file copied and corresponding usage increased.
727 operation_runner()->CopyInForeignFile(src_local_disk_file_path,
728 URLForPath("dest/file"),
729 RecordStatusCallback());
730 base::RunLoop().RunUntilIdle();
732 EXPECT_EQ(1, change_observer()->create_file_count());
733 EXPECT_EQ(base::File::FILE_OK, status());
734 EXPECT_TRUE(FileExists("dest/file"));
735 int64 after_usage;
736 GetUsageAndQuota(&after_usage, NULL);
737 EXPECT_GT(after_usage, before_usage);
739 // Compare contents of src and copied file.
740 char buffer[100];
741 EXPECT_EQ(data_size, base::ReadFile(PlatformPath("dest/file"),
742 buffer, data_size));
743 for (int i = 0; i < data_size; ++i)
744 EXPECT_EQ(test_data[i], buffer[i]);
747 TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileFailureByQuota) {
748 base::FilePath src_local_disk_file_path;
749 base::CreateTemporaryFile(&src_local_disk_file_path);
750 const char test_data[] = "foo";
751 base::WriteFile(src_local_disk_file_path, test_data,
752 ARRAYSIZE_UNSAFE(test_data));
754 FileSystemURL dest_dir(CreateDirectory("dest"));
756 GrantQuotaForCurrentUsage();
757 operation_runner()->CopyInForeignFile(src_local_disk_file_path,
758 URLForPath("dest/file"),
759 RecordStatusCallback());
760 base::RunLoop().RunUntilIdle();
762 EXPECT_FALSE(FileExists("dest/file"));
763 EXPECT_EQ(0, change_observer()->create_file_count());
764 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE, status());
767 TEST_F(FileSystemOperationImplTest, TestCreateFileFailure) {
768 // Already existing file and exclusive true.
769 FileSystemURL file(CreateFile("file"));
770 operation_runner()->CreateFile(file, true, RecordStatusCallback());
771 base::RunLoop().RunUntilIdle();
772 EXPECT_EQ(base::File::FILE_ERROR_EXISTS, status());
773 EXPECT_TRUE(change_observer()->HasNoChange());
776 TEST_F(FileSystemOperationImplTest, TestCreateFileSuccessFileExists) {
777 // Already existing file and exclusive false.
778 FileSystemURL file(CreateFile("file"));
779 operation_runner()->CreateFile(file, false, RecordStatusCallback());
780 base::RunLoop().RunUntilIdle();
781 EXPECT_EQ(base::File::FILE_OK, status());
782 EXPECT_TRUE(FileExists("file"));
784 // The file was already there; did nothing.
785 EXPECT_TRUE(change_observer()->HasNoChange());
788 TEST_F(FileSystemOperationImplTest, TestCreateFileSuccessExclusive) {
789 // File doesn't exist but exclusive is true.
790 operation_runner()->CreateFile(URLForPath("new"), true,
791 RecordStatusCallback());
792 base::RunLoop().RunUntilIdle();
793 EXPECT_EQ(base::File::FILE_OK, status());
794 EXPECT_TRUE(FileExists("new"));
795 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
798 TEST_F(FileSystemOperationImplTest, TestCreateFileSuccessFileDoesntExist) {
799 // Non existing file.
800 operation_runner()->CreateFile(URLForPath("nonexistent"), false,
801 RecordStatusCallback());
802 base::RunLoop().RunUntilIdle();
803 EXPECT_EQ(base::File::FILE_OK, status());
804 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
807 TEST_F(FileSystemOperationImplTest,
808 TestCreateDirFailureDestParentDoesntExist) {
809 // Dest. parent path does not exist.
810 operation_runner()->CreateDirectory(
811 URLForPath("nonexistent/dir"), false, false,
812 RecordStatusCallback());
813 base::RunLoop().RunUntilIdle();
814 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status());
815 EXPECT_TRUE(change_observer()->HasNoChange());
818 TEST_F(FileSystemOperationImplTest, TestCreateDirFailureDirExists) {
819 // Exclusive and dir existing at path.
820 FileSystemURL dir(CreateDirectory("dir"));
821 operation_runner()->CreateDirectory(dir, true, false,
822 RecordStatusCallback());
823 base::RunLoop().RunUntilIdle();
824 EXPECT_EQ(base::File::FILE_ERROR_EXISTS, status());
825 EXPECT_TRUE(change_observer()->HasNoChange());
828 TEST_F(FileSystemOperationImplTest, TestCreateDirFailureFileExists) {
829 // Exclusive true and file existing at path.
830 FileSystemURL file(CreateFile("file"));
831 operation_runner()->CreateDirectory(file, true, false,
832 RecordStatusCallback());
833 base::RunLoop().RunUntilIdle();
834 EXPECT_EQ(base::File::FILE_ERROR_EXISTS, status());
835 EXPECT_TRUE(change_observer()->HasNoChange());
838 TEST_F(FileSystemOperationImplTest, TestCreateDirSuccess) {
839 // Dir exists and exclusive is false.
840 FileSystemURL dir(CreateDirectory("dir"));
841 operation_runner()->CreateDirectory(dir, false, false,
842 RecordStatusCallback());
843 base::RunLoop().RunUntilIdle();
844 EXPECT_EQ(base::File::FILE_OK, status());
845 EXPECT_TRUE(change_observer()->HasNoChange());
847 // Dir doesn't exist.
848 operation_runner()->CreateDirectory(URLForPath("new"), false, false,
849 RecordStatusCallback());
850 base::RunLoop().RunUntilIdle();
851 EXPECT_EQ(base::File::FILE_OK, status());
852 EXPECT_TRUE(DirectoryExists("new"));
853 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
856 TEST_F(FileSystemOperationImplTest, TestCreateDirSuccessExclusive) {
857 // Dir doesn't exist.
858 operation_runner()->CreateDirectory(URLForPath("new"), true, false,
859 RecordStatusCallback());
860 base::RunLoop().RunUntilIdle();
861 EXPECT_EQ(base::File::FILE_OK, status());
862 EXPECT_TRUE(DirectoryExists("new"));
863 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
864 EXPECT_TRUE(change_observer()->HasNoChange());
867 TEST_F(FileSystemOperationImplTest, TestExistsAndMetadataFailure) {
868 operation_runner()->GetMetadata(URLForPath("nonexistent"),
869 RecordMetadataCallback());
870 base::RunLoop().RunUntilIdle();
871 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status());
873 operation_runner()->FileExists(URLForPath("nonexistent"),
874 RecordStatusCallback());
875 base::RunLoop().RunUntilIdle();
876 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status());
878 operation_runner()->DirectoryExists(URLForPath("nonexistent"),
879 RecordStatusCallback());
880 base::RunLoop().RunUntilIdle();
881 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status());
882 EXPECT_TRUE(change_observer()->HasNoChange());
885 TEST_F(FileSystemOperationImplTest, TestExistsAndMetadataSuccess) {
886 FileSystemURL dir(CreateDirectory("dir"));
887 FileSystemURL file(CreateFile("dir/file"));
888 int read_access = 0;
890 operation_runner()->DirectoryExists(dir, RecordStatusCallback());
891 base::RunLoop().RunUntilIdle();
892 EXPECT_EQ(base::File::FILE_OK, status());
893 ++read_access;
895 operation_runner()->GetMetadata(dir, RecordMetadataCallback());
896 base::RunLoop().RunUntilIdle();
897 EXPECT_EQ(base::File::FILE_OK, status());
898 EXPECT_TRUE(info().is_directory);
899 ++read_access;
901 operation_runner()->FileExists(file, RecordStatusCallback());
902 base::RunLoop().RunUntilIdle();
903 EXPECT_EQ(base::File::FILE_OK, status());
904 ++read_access;
906 operation_runner()->GetMetadata(file, RecordMetadataCallback());
907 base::RunLoop().RunUntilIdle();
908 EXPECT_EQ(base::File::FILE_OK, status());
909 EXPECT_FALSE(info().is_directory);
910 ++read_access;
912 EXPECT_EQ(read_access,
913 quota_manager_proxy()->notify_storage_accessed_count());
914 EXPECT_TRUE(change_observer()->HasNoChange());
917 TEST_F(FileSystemOperationImplTest, TestTypeMismatchErrors) {
918 FileSystemURL dir(CreateDirectory("dir"));
919 operation_runner()->FileExists(dir, RecordStatusCallback());
920 base::RunLoop().RunUntilIdle();
921 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE, status());
923 FileSystemURL file(CreateFile("file"));
924 operation_runner()->DirectoryExists(file, RecordStatusCallback());
925 base::RunLoop().RunUntilIdle();
926 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY, status());
929 TEST_F(FileSystemOperationImplTest, TestReadDirFailure) {
930 // Path doesn't exist
931 operation_runner()->ReadDirectory(URLForPath("nonexistent"),
932 RecordReadDirectoryCallback());
933 base::RunLoop().RunUntilIdle();
934 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status());
936 // File exists.
937 FileSystemURL file(CreateFile("file"));
938 operation_runner()->ReadDirectory(file, RecordReadDirectoryCallback());
939 base::RunLoop().RunUntilIdle();
940 EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY, status());
941 EXPECT_TRUE(change_observer()->HasNoChange());
944 TEST_F(FileSystemOperationImplTest, TestReadDirSuccess) {
945 // parent_dir
946 // | |
947 // child_dir child_file
948 // Verify reading parent_dir.
949 FileSystemURL parent_dir(CreateDirectory("dir"));
950 FileSystemURL child_dir(CreateDirectory("dir/child_dir"));
951 FileSystemURL child_file(CreateFile("dir/child_file"));
953 operation_runner()->ReadDirectory(parent_dir, RecordReadDirectoryCallback());
954 base::RunLoop().RunUntilIdle();
955 EXPECT_EQ(base::File::FILE_OK, status());
956 EXPECT_EQ(2u, entries().size());
958 for (size_t i = 0; i < entries().size(); ++i) {
959 if (entries()[i].is_directory)
960 EXPECT_EQ(FILE_PATH_LITERAL("child_dir"), entries()[i].name);
961 else
962 EXPECT_EQ(FILE_PATH_LITERAL("child_file"), entries()[i].name);
964 EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count());
965 EXPECT_TRUE(change_observer()->HasNoChange());
968 TEST_F(FileSystemOperationImplTest, TestRemoveFailure) {
969 // Path doesn't exist.
970 operation_runner()->Remove(URLForPath("nonexistent"), false /* recursive */,
971 RecordStatusCallback());
972 base::RunLoop().RunUntilIdle();
973 EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND, status());
975 // It's an error to try to remove a non-empty directory if recursive flag
976 // is false.
977 // parent_dir
978 // | |
979 // child_dir child_file
980 // Verify deleting parent_dir.
981 FileSystemURL parent_dir(CreateDirectory("dir"));
982 FileSystemURL child_dir(CreateDirectory("dir/child_dir"));
983 FileSystemURL child_file(CreateFile("dir/child_file"));
985 operation_runner()->Remove(parent_dir, false /* recursive */,
986 RecordStatusCallback());
987 base::RunLoop().RunUntilIdle();
988 EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY, status());
989 EXPECT_TRUE(change_observer()->HasNoChange());
992 TEST_F(FileSystemOperationImplTest, TestRemoveSuccess) {
993 FileSystemURL empty_dir(CreateDirectory("empty_dir"));
994 EXPECT_TRUE(DirectoryExists("empty_dir"));
995 operation_runner()->Remove(empty_dir, false /* recursive */,
996 RecordStatusCallback());
997 base::RunLoop().RunUntilIdle();
998 EXPECT_EQ(base::File::FILE_OK, status());
999 EXPECT_FALSE(DirectoryExists("empty_dir"));
1001 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
1002 EXPECT_TRUE(change_observer()->HasNoChange());
1005 TEST_F(FileSystemOperationImplTest, TestRemoveSuccessRecursive) {
1006 // Removing a non-empty directory with recursive flag == true should be ok.
1007 // parent_dir
1008 // | |
1009 // child_dir child_files
1010 // |
1011 // child_files
1013 // Verify deleting parent_dir.
1014 FileSystemURL parent_dir(CreateDirectory("dir"));
1015 for (int i = 0; i < 8; ++i)
1016 CreateFile(base::StringPrintf("dir/file-%d", i));
1017 FileSystemURL child_dir(CreateDirectory("dir/child_dir"));
1018 for (int i = 0; i < 8; ++i)
1019 CreateFile(base::StringPrintf("dir/child_dir/file-%d", i));
1021 operation_runner()->Remove(parent_dir, true /* recursive */,
1022 RecordStatusCallback());
1023 base::RunLoop().RunUntilIdle();
1024 EXPECT_EQ(base::File::FILE_OK, status());
1025 EXPECT_FALSE(DirectoryExists("parent_dir"));
1027 EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count());
1028 EXPECT_EQ(16, change_observer()->get_and_reset_remove_file_count());
1029 EXPECT_TRUE(change_observer()->HasNoChange());
1032 TEST_F(FileSystemOperationImplTest, TestTruncate) {
1033 FileSystemURL file(CreateFile("file"));
1034 base::FilePath platform_path = PlatformPath("file");
1036 char test_data[] = "test data";
1037 int data_size = static_cast<int>(sizeof(test_data));
1038 EXPECT_EQ(data_size,
1039 base::WriteFile(platform_path, test_data, data_size));
1041 // Check that its length is the size of the data written.
1042 operation_runner()->GetMetadata(file, RecordMetadataCallback());
1043 base::RunLoop().RunUntilIdle();
1044 EXPECT_EQ(base::File::FILE_OK, status());
1045 EXPECT_FALSE(info().is_directory);
1046 EXPECT_EQ(data_size, info().size);
1048 // Extend the file by truncating it.
1049 int length = 17;
1050 operation_runner()->Truncate(file, length, RecordStatusCallback());
1051 base::RunLoop().RunUntilIdle();
1052 EXPECT_EQ(base::File::FILE_OK, status());
1054 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1055 EXPECT_TRUE(change_observer()->HasNoChange());
1057 // Check that its length is now 17 and that it's all zeroes after the test
1058 // data.
1059 EXPECT_EQ(length, GetFileSize("file"));
1060 char data[100];
1061 EXPECT_EQ(length, base::ReadFile(platform_path, data, length));
1062 for (int i = 0; i < length; ++i) {
1063 if (i < static_cast<int>(sizeof(test_data)))
1064 EXPECT_EQ(test_data[i], data[i]);
1065 else
1066 EXPECT_EQ(0, data[i]);
1069 // Shorten the file by truncating it.
1070 length = 3;
1071 operation_runner()->Truncate(file, length, RecordStatusCallback());
1072 base::RunLoop().RunUntilIdle();
1073 EXPECT_EQ(base::File::FILE_OK, status());
1075 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1076 EXPECT_TRUE(change_observer()->HasNoChange());
1078 // Check that its length is now 3 and that it contains only bits of test data.
1079 EXPECT_EQ(length, GetFileSize("file"));
1080 EXPECT_EQ(length, base::ReadFile(platform_path, data, length));
1081 for (int i = 0; i < length; ++i)
1082 EXPECT_EQ(test_data[i], data[i]);
1084 // Truncate is not a 'read' access. (Here expected access count is 1
1085 // since we made 1 read access for GetMetadata.)
1086 EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count());
1089 TEST_F(FileSystemOperationImplTest, TestTruncateFailureByQuota) {
1090 FileSystemURL dir(CreateDirectory("dir"));
1091 FileSystemURL file(CreateFile("dir/file"));
1093 GrantQuotaForCurrentUsage();
1094 AddQuota(10);
1096 operation_runner()->Truncate(file, 10, RecordStatusCallback());
1097 base::RunLoop().RunUntilIdle();
1098 EXPECT_EQ(base::File::FILE_OK, status());
1099 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1100 EXPECT_TRUE(change_observer()->HasNoChange());
1102 EXPECT_EQ(10, GetFileSize("dir/file"));
1104 operation_runner()->Truncate(file, 11, RecordStatusCallback());
1105 base::RunLoop().RunUntilIdle();
1106 EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE, status());
1107 EXPECT_TRUE(change_observer()->HasNoChange());
1109 EXPECT_EQ(10, GetFileSize("dir/file"));
1112 TEST_F(FileSystemOperationImplTest, TestTouchFile) {
1113 FileSystemURL file(CreateFile("file"));
1114 base::FilePath platform_path = PlatformPath("file");
1116 base::File::Info info;
1117 EXPECT_TRUE(base::GetFileInfo(platform_path, &info));
1118 EXPECT_FALSE(info.is_directory);
1119 EXPECT_EQ(0, info.size);
1120 const base::Time last_modified = info.last_modified;
1121 const base::Time last_accessed = info.last_accessed;
1123 const base::Time new_modified_time = base::Time::UnixEpoch();
1124 const base::Time new_accessed_time = new_modified_time +
1125 base::TimeDelta::FromHours(77);
1126 ASSERT_NE(last_modified, new_modified_time);
1127 ASSERT_NE(last_accessed, new_accessed_time);
1129 operation_runner()->TouchFile(file, new_accessed_time, new_modified_time,
1130 RecordStatusCallback());
1131 base::RunLoop().RunUntilIdle();
1132 EXPECT_EQ(base::File::FILE_OK, status());
1133 EXPECT_TRUE(change_observer()->HasNoChange());
1135 EXPECT_TRUE(base::GetFileInfo(platform_path, &info));
1136 // We compare as time_t here to lower our resolution, to avoid false
1137 // negatives caused by conversion to the local filesystem's native
1138 // representation and back.
1139 EXPECT_EQ(new_modified_time.ToTimeT(), info.last_modified.ToTimeT());
1140 EXPECT_EQ(new_accessed_time.ToTimeT(), info.last_accessed.ToTimeT());
1143 TEST_F(FileSystemOperationImplTest, TestCreateSnapshotFile) {
1144 FileSystemURL dir(CreateDirectory("dir"));
1146 // Create a file for the testing.
1147 operation_runner()->DirectoryExists(dir, RecordStatusCallback());
1148 FileSystemURL file(CreateFile("dir/file"));
1149 operation_runner()->FileExists(file, RecordStatusCallback());
1150 base::RunLoop().RunUntilIdle();
1151 EXPECT_EQ(base::File::FILE_OK, status());
1153 // See if we can get a 'snapshot' file info for the file.
1154 // Since FileSystemOperationImpl assumes the file exists in the local
1155 // directory it should just returns the same metadata and platform_path
1156 // as the file itself.
1157 operation_runner()->CreateSnapshotFile(file, RecordSnapshotFileCallback());
1158 base::RunLoop().RunUntilIdle();
1159 EXPECT_EQ(base::File::FILE_OK, status());
1160 EXPECT_FALSE(info().is_directory);
1161 EXPECT_EQ(PlatformPath("dir/file"), path());
1162 EXPECT_TRUE(change_observer()->HasNoChange());
1164 // The FileSystemOpration implementation does not create a
1165 // shareable file reference.
1166 EXPECT_EQ(NULL, shareable_file_ref());
1169 TEST_F(FileSystemOperationImplTest,
1170 TestMoveSuccessSrcDirRecursiveWithQuota) {
1171 FileSystemURL src(CreateDirectory("src"));
1172 int src_path_cost = GetUsage();
1174 FileSystemURL dest(CreateDirectory("dest"));
1175 FileSystemURL child_file1(CreateFile("src/file1"));
1176 FileSystemURL child_file2(CreateFile("src/file2"));
1177 FileSystemURL child_dir(CreateDirectory("src/dir"));
1178 FileSystemURL grandchild_file1(CreateFile("src/dir/file1"));
1179 FileSystemURL grandchild_file2(CreateFile("src/dir/file2"));
1181 int total_path_cost = GetUsage();
1182 EXPECT_EQ(0, GetDataSizeOnDisk());
1184 operation_runner()->Truncate(
1185 child_file1, 5000,
1186 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1187 operation_runner()->Truncate(
1188 child_file2, 400,
1189 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1190 operation_runner()->Truncate(
1191 grandchild_file1, 30,
1192 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1193 operation_runner()->Truncate(
1194 grandchild_file2, 2,
1195 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1196 base::RunLoop().RunUntilIdle();
1198 const int64 all_file_size = 5000 + 400 + 30 + 2;
1199 EXPECT_EQ(all_file_size, GetDataSizeOnDisk());
1200 EXPECT_EQ(all_file_size + total_path_cost, GetUsage());
1202 operation_runner()->Move(
1203 src, dest, FileSystemOperation::OPTION_NONE,
1204 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1205 base::RunLoop().RunUntilIdle();
1207 EXPECT_FALSE(DirectoryExists("src/dir"));
1208 EXPECT_FALSE(FileExists("src/dir/file2"));
1209 EXPECT_TRUE(DirectoryExists("dest/dir"));
1210 EXPECT_TRUE(FileExists("dest/dir/file2"));
1212 EXPECT_EQ(all_file_size, GetDataSizeOnDisk());
1213 EXPECT_EQ(all_file_size + total_path_cost - src_path_cost,
1214 GetUsage());
1217 TEST_F(FileSystemOperationImplTest,
1218 TestCopySuccessSrcDirRecursiveWithQuota) {
1219 FileSystemURL src(CreateDirectory("src"));
1220 FileSystemURL dest1(CreateDirectory("dest1"));
1221 FileSystemURL dest2(CreateDirectory("dest2"));
1223 int64 usage = GetUsage();
1224 FileSystemURL child_file1(CreateFile("src/file1"));
1225 FileSystemURL child_file2(CreateFile("src/file2"));
1226 FileSystemURL child_dir(CreateDirectory("src/dir"));
1227 int64 child_path_cost = GetUsage() - usage;
1228 usage += child_path_cost;
1230 FileSystemURL grandchild_file1(CreateFile("src/dir/file1"));
1231 FileSystemURL grandchild_file2(CreateFile("src/dir/file2"));
1232 int64 total_path_cost = GetUsage();
1233 int64 grandchild_path_cost = total_path_cost - usage;
1235 EXPECT_EQ(0, GetDataSizeOnDisk());
1237 operation_runner()->Truncate(
1238 child_file1, 8000,
1239 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1240 operation_runner()->Truncate(
1241 child_file2, 700,
1242 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1243 operation_runner()->Truncate(
1244 grandchild_file1, 60,
1245 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1246 operation_runner()->Truncate(
1247 grandchild_file2, 5,
1248 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1249 base::RunLoop().RunUntilIdle();
1251 const int64 child_file_size = 8000 + 700;
1252 const int64 grandchild_file_size = 60 + 5;
1253 const int64 all_file_size = child_file_size + grandchild_file_size;
1254 int64 expected_usage = all_file_size + total_path_cost;
1256 usage = GetUsage();
1257 EXPECT_EQ(all_file_size, GetDataSizeOnDisk());
1258 EXPECT_EQ(expected_usage, usage);
1260 // Copy src to dest1.
1261 operation_runner()->Copy(
1262 src, dest1, FileSystemOperation::OPTION_NONE,
1263 FileSystemOperationRunner::CopyProgressCallback(),
1264 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1265 base::RunLoop().RunUntilIdle();
1267 expected_usage += all_file_size + child_path_cost + grandchild_path_cost;
1268 EXPECT_TRUE(DirectoryExists("src/dir"));
1269 EXPECT_TRUE(FileExists("src/dir/file2"));
1270 EXPECT_TRUE(DirectoryExists("dest1/dir"));
1271 EXPECT_TRUE(FileExists("dest1/dir/file2"));
1273 EXPECT_EQ(2 * all_file_size, GetDataSizeOnDisk());
1274 EXPECT_EQ(expected_usage, GetUsage());
1276 // Copy src/dir to dest2.
1277 operation_runner()->Copy(
1278 child_dir, dest2, FileSystemOperation::OPTION_NONE,
1279 FileSystemOperationRunner::CopyProgressCallback(),
1280 base::Bind(&AssertFileErrorEq, FROM_HERE, base::File::FILE_OK));
1281 base::RunLoop().RunUntilIdle();
1283 expected_usage += grandchild_file_size + grandchild_path_cost;
1284 usage = GetUsage();
1285 EXPECT_EQ(2 * child_file_size + 3 * grandchild_file_size,
1286 GetDataSizeOnDisk());
1287 EXPECT_EQ(expected_usage, usage);
1290 } // namespace content