Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / content / browser / fileapi / file_system_operation_impl_unittest.cc
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.
4
5 #include "storage/browser/fileapi/file_system_operation_impl.h"
6
7 #include "base/bind.h"
8 #include "base/files/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/fileapi/mock_file_update_observer.h"
17 #include "content/browser/quota/mock_quota_manager.h"
18 #include "content/browser/quota/mock_quota_manager_proxy.h"
19 #include "content/public/test/async_file_test_helper.h"
20 #include "content/public/test/sandbox_file_system_test_helper.h"
21 #include "storage/browser/fileapi/file_system_context.h"
22 #include "storage/browser/fileapi/file_system_file_util.h"
23 #include "storage/browser/fileapi/file_system_operation_context.h"
24 #include "storage/browser/fileapi/file_system_operation_runner.h"
25 #include "storage/browser/fileapi/sandbox_file_system_backend.h"
26 #include "storage/browser/quota/quota_manager.h"
27 #include "storage/browser/quota/quota_manager_proxy.h"
28 #include "storage/common/blob/shareable_file_reference.h"
29 #include "storage/common/fileapi/file_system_util.h"
30 #include "testing/gtest/include/gtest/gtest.h"
31 #include "url/gurl.h"
32
33 using content::AsyncFileTestHelper;
34 using storage::FileSystemOperation;
35 using storage::FileSystemOperationContext;
36 using storage::FileSystemOperationRunner;
37 using storage::FileSystemURL;
38 using storage::QuotaManager;
39 using storage::QuotaManagerProxy;
40 using storage::ShareableFileReference;
41
42 namespace content {
43
44 // Test class for FileSystemOperationImpl.
45 class FileSystemOperationImplTest
46     : public testing::Test {
47  public:
48   FileSystemOperationImplTest() : weak_factory_(this) {}
49
50  protected:
51   void SetUp() override {
52     EXPECT_TRUE(base_.CreateUniqueTempDir());
53     change_observers_ =
54         storage::MockFileChangeObserver::CreateList(&change_observer_);
55     update_observers_ =
56         storage::MockFileUpdateObserver::CreateList(&update_observer_);
57
58     base::FilePath base_dir = base_.path().AppendASCII("filesystem");
59     quota_manager_ =
60         new MockQuotaManager(false /* is_incognito */,
61                                     base_dir,
62                                     base::MessageLoopProxy::current().get(),
63                                     base::MessageLoopProxy::current().get(),
64                                     NULL /* special storage policy */);
65     quota_manager_proxy_ = new MockQuotaManagerProxy(
66         quota_manager(), base::MessageLoopProxy::current().get());
67     sandbox_file_system_.SetUp(base_dir, quota_manager_proxy_.get());
68     sandbox_file_system_.AddFileChangeObserver(&change_observer_);
69     sandbox_file_system_.AddFileUpdateObserver(&update_observer_);
70     update_observer_.Disable();
71   }
72
73   void TearDown() override {
74     // Let the client go away before dropping a ref of the quota manager proxy.
75     quota_manager_proxy()->SimulateQuotaManagerDestroyed();
76     quota_manager_ = NULL;
77     quota_manager_proxy_ = NULL;
78     sandbox_file_system_.TearDown();
79   }
80
81   FileSystemOperationRunner* operation_runner() {
82     return sandbox_file_system_.operation_runner();
83   }
84
85   const base::File::Info& info() const { return info_; }
86   const base::FilePath& path() const { return path_; }
87   const std::vector<storage::DirectoryEntry>& entries() const {
88     return entries_;
89   }
90
91   const ShareableFileReference* shareable_file_ref() const {
92     return shareable_file_ref_.get();
93   }
94
95   MockQuotaManager* quota_manager() {
96     return static_cast<MockQuotaManager*>(quota_manager_.get());
97   }
98
99   MockQuotaManagerProxy* quota_manager_proxy() {
100     return static_cast<MockQuotaManagerProxy*>(
101         quota_manager_proxy_.get());
102   }
103
104   storage::FileSystemFileUtil* file_util() {
105     return sandbox_file_system_.file_util();
106   }
107
108   storage::MockFileChangeObserver* change_observer() {
109     return &change_observer_;
110   }
111
112   scoped_ptr<FileSystemOperationContext> NewContext() {
113     FileSystemOperationContext* context =
114         sandbox_file_system_.NewOperationContext();
115     // Grant enough quota for all test cases.
116     context->set_allowed_bytes_growth(1000000);
117     return make_scoped_ptr(context);
118   }
119
120   FileSystemURL URLForPath(const std::string& path) const {
121     return sandbox_file_system_.CreateURLFromUTF8(path);
122   }
123
124   base::FilePath PlatformPath(const std::string& path) {
125     return sandbox_file_system_.GetLocalPath(
126         base::FilePath::FromUTF8Unsafe(path));
127   }
128
129   bool FileExists(const std::string& path) {
130     return AsyncFileTestHelper::FileExists(
131         sandbox_file_system_.file_system_context(), URLForPath(path),
132         AsyncFileTestHelper::kDontCheckSize);
133   }
134
135   bool DirectoryExists(const std::string& path) {
136     return AsyncFileTestHelper::DirectoryExists(
137         sandbox_file_system_.file_system_context(), URLForPath(path));
138   }
139
140   FileSystemURL CreateFile(const std::string& path) {
141     FileSystemURL url = URLForPath(path);
142     bool created = false;
143     EXPECT_EQ(base::File::FILE_OK,
144               file_util()->EnsureFileExists(NewContext().get(),
145                                             url, &created));
146     EXPECT_TRUE(created);
147     return url;
148   }
149
150   FileSystemURL CreateDirectory(const std::string& path) {
151     FileSystemURL url = URLForPath(path);
152     EXPECT_EQ(base::File::FILE_OK,
153               file_util()->CreateDirectory(NewContext().get(), url,
154                                            false /* exclusive */, true));
155     return url;
156   }
157
158   int64 GetFileSize(const std::string& path) {
159     base::File::Info info;
160     EXPECT_TRUE(base::GetFileInfo(PlatformPath(path), &info));
161     return info.size;
162   }
163
164   // Callbacks for recording test results.
165   FileSystemOperation::StatusCallback RecordStatusCallback(
166       const base::Closure& closure,
167       base::File::Error* status) {
168     return base::Bind(&FileSystemOperationImplTest::DidFinish,
169                       weak_factory_.GetWeakPtr(),
170                       closure,
171                       status);
172   }
173
174   FileSystemOperation::ReadDirectoryCallback RecordReadDirectoryCallback(
175       const base::Closure& closure,
176       base::File::Error* status) {
177     return base::Bind(&FileSystemOperationImplTest::DidReadDirectory,
178                       weak_factory_.GetWeakPtr(),
179                       closure,
180                       status);
181   }
182
183   FileSystemOperation::GetMetadataCallback RecordMetadataCallback(
184       const base::Closure& closure,
185       base::File::Error* status) {
186     return base::Bind(&FileSystemOperationImplTest::DidGetMetadata,
187                       weak_factory_.GetWeakPtr(),
188                       closure,
189                       status);
190   }
191
192   FileSystemOperation::SnapshotFileCallback RecordSnapshotFileCallback(
193       const base::Closure& closure,
194       base::File::Error* status) {
195     return base::Bind(&FileSystemOperationImplTest::DidCreateSnapshotFile,
196                       weak_factory_.GetWeakPtr(),
197                       closure,
198                       status);
199   }
200
201   void DidFinish(const base::Closure& closure,
202                  base::File::Error* status,
203                  base::File::Error actual) {
204     *status = actual;
205     closure.Run();
206   }
207
208   void DidReadDirectory(const base::Closure& closure,
209                         base::File::Error* status,
210                         base::File::Error actual,
211                         const std::vector<storage::DirectoryEntry>& entries,
212                         bool /* has_more */) {
213     entries_ = entries;
214     *status = actual;
215     closure.Run();
216   }
217
218   void DidGetMetadata(const base::Closure& closure,
219                       base::File::Error* status,
220                       base::File::Error actual,
221                       const base::File::Info& info) {
222     info_ = info;
223     *status = actual;
224     closure.Run();
225   }
226
227   void DidCreateSnapshotFile(
228       const base::Closure& closure,
229       base::File::Error* status,
230       base::File::Error actual,
231       const base::File::Info& info,
232       const base::FilePath& platform_path,
233       const scoped_refptr<ShareableFileReference>& shareable_file_ref) {
234     info_ = info;
235     path_ = platform_path;
236     *status = actual;
237     shareable_file_ref_ = shareable_file_ref;
238     closure.Run();
239   }
240
241   int64 GetDataSizeOnDisk() {
242     return sandbox_file_system_.ComputeCurrentOriginUsage() -
243         sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage();
244   }
245
246   void GetUsageAndQuota(int64* usage, int64* quota) {
247     storage::QuotaStatusCode status =
248         AsyncFileTestHelper::GetUsageAndQuota(quota_manager_.get(),
249                                               sandbox_file_system_.origin(),
250                                               sandbox_file_system_.type(),
251                                               usage,
252                                               quota);
253     base::RunLoop().RunUntilIdle();
254     ASSERT_EQ(storage::kQuotaStatusOk, status);
255   }
256
257   int64 ComputePathCost(const FileSystemURL& url) {
258     int64 base_usage;
259     GetUsageAndQuota(&base_usage, NULL);
260
261     AsyncFileTestHelper::CreateFile(
262         sandbox_file_system_.file_system_context(), url);
263     EXPECT_EQ(base::File::FILE_OK, Remove(url, false /* recursive */));
264
265     change_observer()->ResetCount();
266
267     int64 total_usage;
268     GetUsageAndQuota(&total_usage, NULL);
269     return total_usage - base_usage;
270   }
271
272   void GrantQuotaForCurrentUsage() {
273     int64 usage;
274     GetUsageAndQuota(&usage, NULL);
275     quota_manager()->SetQuota(sandbox_file_system_.origin(),
276                               sandbox_file_system_.storage_type(),
277                               usage);
278   }
279
280   int64 GetUsage() {
281     int64 usage = 0;
282     GetUsageAndQuota(&usage, NULL);
283     return usage;
284   }
285
286   void AddQuota(int64 quota_delta) {
287     int64 quota;
288     GetUsageAndQuota(NULL, &quota);
289     quota_manager()->SetQuota(sandbox_file_system_.origin(),
290                               sandbox_file_system_.storage_type(),
291                               quota + quota_delta);
292   }
293
294   base::File::Error Move(
295       const FileSystemURL& src,
296       const FileSystemURL& dest,
297       storage::FileSystemOperation::CopyOrMoveOption option) {
298     base::File::Error status;
299     base::RunLoop run_loop;
300     update_observer_.Enable();
301     operation_runner()->Move(
302         src,
303         dest,
304         option,
305         RecordStatusCallback(run_loop.QuitClosure(), &status));
306     run_loop.Run();
307     update_observer_.Disable();
308     return status;
309   }
310
311   base::File::Error Copy(
312       const FileSystemURL& src,
313       const FileSystemURL& dest,
314       storage::FileSystemOperation::CopyOrMoveOption option) {
315     base::File::Error status;
316     base::RunLoop run_loop;
317     update_observer_.Enable();
318     operation_runner()->Copy(
319         src,
320         dest,
321         option,
322         FileSystemOperationRunner::CopyProgressCallback(),
323         RecordStatusCallback(run_loop.QuitClosure(), &status));
324     run_loop.Run();
325     update_observer_.Disable();
326     return status;
327   }
328
329   base::File::Error CopyInForeignFile(const base::FilePath& src,
330                                       const FileSystemURL& dest) {
331     base::File::Error status;
332     base::RunLoop run_loop;
333     update_observer_.Enable();
334     operation_runner()->CopyInForeignFile(
335         src, dest, RecordStatusCallback(run_loop.QuitClosure(), &status));
336     run_loop.Run();
337     update_observer_.Disable();
338     return status;
339   }
340
341   base::File::Error Truncate(const FileSystemURL& url, int size) {
342     base::File::Error status;
343     base::RunLoop run_loop;
344     update_observer_.Enable();
345     operation_runner()->Truncate(
346         url, size, RecordStatusCallback(run_loop.QuitClosure(), &status));
347     run_loop.Run();
348     update_observer_.Disable();
349     return status;
350   }
351
352   base::File::Error CreateFile(const FileSystemURL& url, bool exclusive) {
353     base::File::Error status;
354     base::RunLoop run_loop;
355     update_observer_.Enable();
356     operation_runner()->CreateFile(
357         url, exclusive, RecordStatusCallback(run_loop.QuitClosure(), &status));
358     run_loop.Run();
359     update_observer_.Disable();
360     return status;
361   }
362
363   base::File::Error Remove(const FileSystemURL& url, bool recursive) {
364     base::File::Error status;
365     base::RunLoop run_loop;
366     update_observer_.Enable();
367     operation_runner()->Remove(
368         url, recursive, RecordStatusCallback(run_loop.QuitClosure(), &status));
369     run_loop.Run();
370     update_observer_.Disable();
371     return status;
372   }
373
374   base::File::Error CreateDirectory(const FileSystemURL& url,
375                                     bool exclusive,
376                                     bool recursive) {
377     base::File::Error status;
378     base::RunLoop run_loop;
379     update_observer_.Enable();
380     operation_runner()->CreateDirectory(
381         url,
382         exclusive,
383         recursive,
384         RecordStatusCallback(run_loop.QuitClosure(), &status));
385     run_loop.Run();
386     update_observer_.Disable();
387     return status;
388   }
389
390   base::File::Error GetMetadata(const FileSystemURL& url) {
391     base::File::Error status;
392     base::RunLoop run_loop;
393     update_observer_.Enable();
394     operation_runner()->GetMetadata(
395         url, RecordMetadataCallback(run_loop.QuitClosure(), &status));
396     run_loop.Run();
397     update_observer_.Disable();
398     return status;
399   }
400
401   base::File::Error ReadDirectory(const FileSystemURL& url) {
402     base::File::Error status;
403     base::RunLoop run_loop;
404     update_observer_.Enable();
405     operation_runner()->ReadDirectory(
406         url, RecordReadDirectoryCallback(run_loop.QuitClosure(), &status));
407     run_loop.Run();
408     update_observer_.Disable();
409     return status;
410   }
411
412   base::File::Error CreateSnapshotFile(const FileSystemURL& url) {
413     base::File::Error status;
414     base::RunLoop run_loop;
415     update_observer_.Enable();
416     operation_runner()->CreateSnapshotFile(
417         url, RecordSnapshotFileCallback(run_loop.QuitClosure(), &status));
418     run_loop.Run();
419     update_observer_.Disable();
420     return status;
421   }
422
423   base::File::Error FileExists(const FileSystemURL& url) {
424     base::File::Error status;
425     base::RunLoop run_loop;
426     update_observer_.Enable();
427     operation_runner()->FileExists(
428         url, RecordStatusCallback(run_loop.QuitClosure(), &status));
429     run_loop.Run();
430     update_observer_.Disable();
431     return status;
432   }
433
434   base::File::Error DirectoryExists(const FileSystemURL& url) {
435     base::File::Error status;
436     base::RunLoop run_loop;
437     update_observer_.Enable();
438     operation_runner()->DirectoryExists(
439         url, RecordStatusCallback(run_loop.QuitClosure(), &status));
440     run_loop.Run();
441     update_observer_.Disable();
442     return status;
443   }
444
445   base::File::Error TouchFile(const FileSystemURL& url,
446                               const base::Time& last_access_time,
447                               const base::Time& last_modified_time) {
448     base::File::Error status;
449     base::RunLoop run_loop;
450     update_observer_.Enable();
451     operation_runner()->TouchFile(
452         url,
453         last_access_time,
454         last_modified_time,
455         RecordStatusCallback(run_loop.QuitClosure(), &status));
456     run_loop.Run();
457     update_observer_.Disable();
458     return status;
459   }
460
461  private:
462   base::MessageLoopForIO message_loop_;
463   scoped_refptr<QuotaManager> quota_manager_;
464   scoped_refptr<QuotaManagerProxy> quota_manager_proxy_;
465
466   // Common temp base for nondestructive uses.
467   base::ScopedTempDir base_;
468
469   SandboxFileSystemTestHelper sandbox_file_system_;
470
471   // For post-operation status.
472   base::File::Info info_;
473   base::FilePath path_;
474   std::vector<storage::DirectoryEntry> entries_;
475   scoped_refptr<ShareableFileReference> shareable_file_ref_;
476
477   storage::MockFileChangeObserver change_observer_;
478   storage::ChangeObserverList change_observers_;
479   storage::MockFileUpdateObserver update_observer_;
480   storage::UpdateObserverList update_observers_;
481
482   base::WeakPtrFactory<FileSystemOperationImplTest> weak_factory_;
483
484   DISALLOW_COPY_AND_ASSIGN(FileSystemOperationImplTest);
485 };
486
487 TEST_F(FileSystemOperationImplTest, TestMoveFailureSrcDoesntExist) {
488   change_observer()->ResetCount();
489   EXPECT_EQ(
490       base::File::FILE_ERROR_NOT_FOUND,
491       Move(URLForPath("a"), URLForPath("b"), FileSystemOperation::OPTION_NONE));
492   EXPECT_TRUE(change_observer()->HasNoChange());
493 }
494
495 TEST_F(FileSystemOperationImplTest, TestMoveFailureContainsPath) {
496   FileSystemURL src_dir(CreateDirectory("src"));
497   FileSystemURL dest_dir(CreateDirectory("src/dest"));
498
499   EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
500             Move(src_dir, dest_dir, FileSystemOperation::OPTION_NONE));
501   EXPECT_TRUE(change_observer()->HasNoChange());
502 }
503
504 TEST_F(FileSystemOperationImplTest, TestMoveFailureSrcDirExistsDestFile) {
505   // Src exists and is dir. Dest is a file.
506   FileSystemURL src_dir(CreateDirectory("src"));
507   FileSystemURL dest_dir(CreateDirectory("dest"));
508   FileSystemURL dest_file(CreateFile("dest/file"));
509
510   EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
511             Move(src_dir, dest_file, FileSystemOperation::OPTION_NONE));
512   EXPECT_TRUE(change_observer()->HasNoChange());
513 }
514
515 TEST_F(FileSystemOperationImplTest,
516        TestMoveFailureSrcFileExistsDestNonEmptyDir) {
517   // Src exists and is a directory. Dest is a non-empty directory.
518   FileSystemURL src_dir(CreateDirectory("src"));
519   FileSystemURL dest_dir(CreateDirectory("dest"));
520   FileSystemURL dest_file(CreateFile("dest/file"));
521
522   EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY,
523             Move(src_dir, dest_dir, FileSystemOperation::OPTION_NONE));
524   EXPECT_TRUE(change_observer()->HasNoChange());
525 }
526
527 TEST_F(FileSystemOperationImplTest, TestMoveFailureSrcFileExistsDestDir) {
528   // Src exists and is a file. Dest is a directory.
529   FileSystemURL src_dir(CreateDirectory("src"));
530   FileSystemURL src_file(CreateFile("src/file"));
531   FileSystemURL dest_dir(CreateDirectory("dest"));
532
533   EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
534             Move(src_file, dest_dir, FileSystemOperation::OPTION_NONE));
535   EXPECT_TRUE(change_observer()->HasNoChange());
536 }
537
538 TEST_F(FileSystemOperationImplTest, TestMoveFailureDestParentDoesntExist) {
539   // Dest. parent path does not exist.
540   FileSystemURL src_dir(CreateDirectory("src"));
541   EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
542             Move(src_dir,
543                  URLForPath("nonexistent/deset"),
544                  FileSystemOperation::OPTION_NONE));
545   EXPECT_TRUE(change_observer()->HasNoChange());
546 }
547
548 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSrcFileAndOverwrite) {
549   FileSystemURL src_file(CreateFile("src"));
550   FileSystemURL dest_file(CreateFile("dest"));
551
552   EXPECT_EQ(base::File::FILE_OK,
553             Move(src_file, dest_file, FileSystemOperation::OPTION_NONE));
554   EXPECT_TRUE(FileExists("dest"));
555
556   EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
557   EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
558   EXPECT_TRUE(change_observer()->HasNoChange());
559
560   EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count());
561 }
562
563 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSrcFileAndNew) {
564   FileSystemURL src_file(CreateFile("src"));
565
566   EXPECT_EQ(
567       base::File::FILE_OK,
568       Move(src_file, URLForPath("new"), FileSystemOperation::OPTION_NONE));
569   EXPECT_TRUE(FileExists("new"));
570
571   EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
572   EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
573   EXPECT_TRUE(change_observer()->HasNoChange());
574 }
575
576 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSrcDirAndOverwrite) {
577   FileSystemURL src_dir(CreateDirectory("src"));
578   FileSystemURL dest_dir(CreateDirectory("dest"));
579
580   EXPECT_EQ(base::File::FILE_OK,
581             Move(src_dir, dest_dir, FileSystemOperation::OPTION_NONE));
582   EXPECT_FALSE(DirectoryExists("src"));
583
584   EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
585   EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count());
586   EXPECT_TRUE(change_observer()->HasNoChange());
587
588   // Make sure we've overwritten but not moved the source under the |dest_dir|.
589   EXPECT_TRUE(DirectoryExists("dest"));
590   EXPECT_FALSE(DirectoryExists("dest/src"));
591 }
592
593 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSrcDirAndNew) {
594   FileSystemURL src_dir(CreateDirectory("src"));
595   FileSystemURL dest_dir(CreateDirectory("dest"));
596
597   EXPECT_EQ(
598       base::File::FILE_OK,
599       Move(src_dir, URLForPath("dest/new"), FileSystemOperation::OPTION_NONE));
600   EXPECT_FALSE(DirectoryExists("src"));
601   EXPECT_TRUE(DirectoryExists("dest/new"));
602
603   EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
604   EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
605   EXPECT_TRUE(change_observer()->HasNoChange());
606 }
607
608 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSrcDirRecursive) {
609   FileSystemURL src_dir(CreateDirectory("src"));
610   CreateDirectory("src/dir");
611   CreateFile("src/dir/sub");
612
613   FileSystemURL dest_dir(CreateDirectory("dest"));
614
615   EXPECT_EQ(base::File::FILE_OK,
616             Move(src_dir, dest_dir, FileSystemOperation::OPTION_NONE));
617   EXPECT_TRUE(DirectoryExists("dest/dir"));
618   EXPECT_TRUE(FileExists("dest/dir/sub"));
619
620   EXPECT_EQ(3, change_observer()->get_and_reset_remove_directory_count());
621   EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
622   EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count());
623   EXPECT_EQ(1, change_observer()->get_and_reset_create_file_from_count());
624   EXPECT_TRUE(change_observer()->HasNoChange());
625 }
626
627 TEST_F(FileSystemOperationImplTest, TestMoveSuccessSamePath) {
628   FileSystemURL src_dir(CreateDirectory("src"));
629   CreateDirectory("src/dir");
630   CreateFile("src/dir/sub");
631
632   EXPECT_EQ(base::File::FILE_OK,
633             Move(src_dir, src_dir, FileSystemOperation::OPTION_NONE));
634   EXPECT_TRUE(DirectoryExists("src/dir"));
635   EXPECT_TRUE(FileExists("src/dir/sub"));
636
637   EXPECT_EQ(0, change_observer()->get_and_reset_remove_directory_count());
638   EXPECT_EQ(0, change_observer()->get_and_reset_create_directory_count());
639   EXPECT_EQ(0, change_observer()->get_and_reset_remove_file_count());
640   EXPECT_EQ(0, change_observer()->get_and_reset_create_file_from_count());
641   EXPECT_TRUE(change_observer()->HasNoChange());
642 }
643
644 TEST_F(FileSystemOperationImplTest, TestCopyFailureSrcDoesntExist) {
645   EXPECT_EQ(
646       base::File::FILE_ERROR_NOT_FOUND,
647       Copy(URLForPath("a"), URLForPath("b"), FileSystemOperation::OPTION_NONE));
648   EXPECT_TRUE(change_observer()->HasNoChange());
649 }
650
651 TEST_F(FileSystemOperationImplTest, TestCopyFailureContainsPath) {
652   FileSystemURL src_dir(CreateDirectory("src"));
653   FileSystemURL dest_dir(CreateDirectory("src/dir"));
654
655   EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
656             Copy(src_dir, dest_dir, FileSystemOperation::OPTION_NONE));
657   EXPECT_TRUE(change_observer()->HasNoChange());
658 }
659
660 TEST_F(FileSystemOperationImplTest, TestCopyFailureSrcDirExistsDestFile) {
661   // Src exists and is dir. Dest is a file.
662   FileSystemURL src_dir(CreateDirectory("src"));
663   FileSystemURL dest_dir(CreateDirectory("dest"));
664   FileSystemURL dest_file(CreateFile("dest/file"));
665
666   EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
667             Copy(src_dir, dest_file, FileSystemOperation::OPTION_NONE));
668   EXPECT_TRUE(change_observer()->HasNoChange());
669 }
670
671 TEST_F(FileSystemOperationImplTest,
672        TestCopyFailureSrcFileExistsDestNonEmptyDir) {
673   // Src exists and is a directory. Dest is a non-empty directory.
674   FileSystemURL src_dir(CreateDirectory("src"));
675   FileSystemURL dest_dir(CreateDirectory("dest"));
676   FileSystemURL dest_file(CreateFile("dest/file"));
677
678   EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY,
679             Copy(src_dir, dest_dir, FileSystemOperation::OPTION_NONE));
680   EXPECT_TRUE(change_observer()->HasNoChange());
681 }
682
683 TEST_F(FileSystemOperationImplTest, TestCopyFailureSrcFileExistsDestDir) {
684   // Src exists and is a file. Dest is a directory.
685   FileSystemURL src_file(CreateFile("src"));
686   FileSystemURL dest_dir(CreateDirectory("dest"));
687
688   EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
689             Copy(src_file, dest_dir, FileSystemOperation::OPTION_NONE));
690   EXPECT_TRUE(change_observer()->HasNoChange());
691 }
692
693 TEST_F(FileSystemOperationImplTest, TestCopyFailureDestParentDoesntExist) {
694   // Dest. parent path does not exist.
695   FileSystemURL src_dir(CreateDirectory("src"));
696
697   EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
698             Copy(src_dir,
699                  URLForPath("nonexistent/dest"),
700                  FileSystemOperation::OPTION_NONE));
701   EXPECT_TRUE(change_observer()->HasNoChange());
702 }
703
704 TEST_F(FileSystemOperationImplTest, TestCopyFailureByQuota) {
705   FileSystemURL src_dir(CreateDirectory("src"));
706   FileSystemURL src_file(CreateFile("src/file"));
707   FileSystemURL dest_dir(CreateDirectory("dest"));
708   EXPECT_EQ(base::File::FILE_OK, Truncate(src_file, 6));
709   EXPECT_EQ(6, GetFileSize("src/file"));
710
711   FileSystemURL dest_file(URLForPath("dest/file"));
712   int64 dest_path_cost = ComputePathCost(dest_file);
713   GrantQuotaForCurrentUsage();
714   AddQuota(6 + dest_path_cost - 1);
715
716   EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE,
717             Copy(src_file, dest_file, FileSystemOperation::OPTION_NONE));
718   EXPECT_FALSE(FileExists("dest/file"));
719 }
720
721 TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcFileAndOverwrite) {
722   FileSystemURL src_file(CreateFile("src"));
723   FileSystemURL dest_file(CreateFile("dest"));
724
725   EXPECT_EQ(base::File::FILE_OK,
726             Copy(src_file, dest_file, FileSystemOperation::OPTION_NONE));
727
728   EXPECT_TRUE(FileExists("dest"));
729   EXPECT_EQ(4, quota_manager_proxy()->notify_storage_accessed_count());
730   EXPECT_EQ(2, change_observer()->get_and_reset_modify_file_count());
731
732   EXPECT_TRUE(change_observer()->HasNoChange());
733 }
734
735 TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcFileAndNew) {
736   FileSystemURL src_file(CreateFile("src"));
737
738   EXPECT_EQ(
739       base::File::FILE_OK,
740       Copy(src_file, URLForPath("new"), FileSystemOperation::OPTION_NONE));
741   EXPECT_TRUE(FileExists("new"));
742   EXPECT_EQ(4, quota_manager_proxy()->notify_storage_accessed_count());
743
744   EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
745   EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
746   EXPECT_TRUE(change_observer()->HasNoChange());
747 }
748
749 TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcDirAndOverwrite) {
750   FileSystemURL src_dir(CreateDirectory("src"));
751   FileSystemURL dest_dir(CreateDirectory("dest"));
752
753   EXPECT_EQ(base::File::FILE_OK,
754             Copy(src_dir, dest_dir, FileSystemOperation::OPTION_NONE));
755
756   // Make sure we've overwritten but not copied the source under the |dest_dir|.
757   EXPECT_TRUE(DirectoryExists("dest"));
758   EXPECT_FALSE(DirectoryExists("dest/src"));
759   EXPECT_GE(quota_manager_proxy()->notify_storage_accessed_count(), 3);
760
761   EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
762   EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
763   EXPECT_TRUE(change_observer()->HasNoChange());
764 }
765
766 TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcDirAndNew) {
767   FileSystemURL src_dir(CreateDirectory("src"));
768   FileSystemURL dest_dir_new(URLForPath("dest"));
769
770   EXPECT_EQ(base::File::FILE_OK,
771             Copy(src_dir, dest_dir_new, FileSystemOperation::OPTION_NONE));
772   EXPECT_TRUE(DirectoryExists("dest"));
773   EXPECT_GE(quota_manager_proxy()->notify_storage_accessed_count(), 2);
774
775   EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
776   EXPECT_TRUE(change_observer()->HasNoChange());
777 }
778
779 TEST_F(FileSystemOperationImplTest, TestCopySuccessSrcDirRecursive) {
780   FileSystemURL src_dir(CreateDirectory("src"));
781   CreateDirectory("src/dir");
782   CreateFile("src/dir/sub");
783
784   FileSystemURL dest_dir(CreateDirectory("dest"));
785
786   EXPECT_EQ(base::File::FILE_OK,
787             Copy(src_dir, dest_dir, FileSystemOperation::OPTION_NONE));
788
789   EXPECT_TRUE(DirectoryExists("dest/dir"));
790   EXPECT_TRUE(FileExists("dest/dir/sub"));
791
792   // For recursive copy we may record multiple read access.
793   EXPECT_GE(quota_manager_proxy()->notify_storage_accessed_count(), 1);
794
795   EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count());
796   EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
797   EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
798   EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
799   EXPECT_TRUE(change_observer()->HasNoChange());
800 }
801
802 TEST_F(FileSystemOperationImplTest, TestCopySuccessSamePath) {
803   FileSystemURL src_dir(CreateDirectory("src"));
804   CreateDirectory("src/dir");
805   CreateFile("src/dir/sub");
806
807   EXPECT_EQ(base::File::FILE_OK,
808             Copy(src_dir, src_dir, FileSystemOperation::OPTION_NONE));
809
810   EXPECT_TRUE(DirectoryExists("src/dir"));
811   EXPECT_TRUE(FileExists("src/dir/sub"));
812
813   EXPECT_EQ(0, change_observer()->get_and_reset_create_directory_count());
814   EXPECT_EQ(0, change_observer()->get_and_reset_remove_file_count());
815   EXPECT_EQ(0, change_observer()->get_and_reset_create_file_from_count());
816   EXPECT_TRUE(change_observer()->HasNoChange());
817 }
818
819 TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileSuccess) {
820   base::FilePath src_local_disk_file_path;
821   base::CreateTemporaryFile(&src_local_disk_file_path);
822   const char test_data[] = "foo";
823   int data_size = arraysize(test_data);
824   base::WriteFile(src_local_disk_file_path, test_data, data_size);
825
826   FileSystemURL dest_dir(CreateDirectory("dest"));
827
828   int64 before_usage;
829   GetUsageAndQuota(&before_usage, NULL);
830
831   // Check that the file copied and corresponding usage increased.
832   EXPECT_EQ(
833       base::File::FILE_OK,
834       CopyInForeignFile(src_local_disk_file_path, URLForPath("dest/file")));
835
836   EXPECT_EQ(1, change_observer()->create_file_count());
837   EXPECT_TRUE(FileExists("dest/file"));
838   int64 after_usage;
839   GetUsageAndQuota(&after_usage, NULL);
840   EXPECT_GT(after_usage, before_usage);
841
842   // Compare contents of src and copied file.
843   char buffer[100];
844   EXPECT_EQ(data_size, base::ReadFile(PlatformPath("dest/file"),
845                                       buffer, data_size));
846   for (int i = 0; i < data_size; ++i)
847     EXPECT_EQ(test_data[i], buffer[i]);
848 }
849
850 TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileFailureByQuota) {
851   base::FilePath src_local_disk_file_path;
852   base::CreateTemporaryFile(&src_local_disk_file_path);
853   const char test_data[] = "foo";
854   base::WriteFile(src_local_disk_file_path, test_data, arraysize(test_data));
855
856   FileSystemURL dest_dir(CreateDirectory("dest"));
857
858   GrantQuotaForCurrentUsage();
859   EXPECT_EQ(
860       base::File::FILE_ERROR_NO_SPACE,
861       CopyInForeignFile(src_local_disk_file_path, URLForPath("dest/file")));
862
863   EXPECT_FALSE(FileExists("dest/file"));
864   EXPECT_EQ(0, change_observer()->create_file_count());
865 }
866
867 TEST_F(FileSystemOperationImplTest, TestCreateFileFailure) {
868   // Already existing file and exclusive true.
869   FileSystemURL file(CreateFile("file"));
870   EXPECT_EQ(base::File::FILE_ERROR_EXISTS, CreateFile(file, true));
871   EXPECT_TRUE(change_observer()->HasNoChange());
872 }
873
874 TEST_F(FileSystemOperationImplTest, TestCreateFileSuccessFileExists) {
875   // Already existing file and exclusive false.
876   FileSystemURL file(CreateFile("file"));
877   EXPECT_EQ(base::File::FILE_OK, CreateFile(file, false));
878   EXPECT_TRUE(FileExists("file"));
879
880   // The file was already there; did nothing.
881   EXPECT_TRUE(change_observer()->HasNoChange());
882 }
883
884 TEST_F(FileSystemOperationImplTest, TestCreateFileSuccessExclusive) {
885   // File doesn't exist but exclusive is true.
886   EXPECT_EQ(base::File::FILE_OK, CreateFile(URLForPath("new"), true));
887   EXPECT_TRUE(FileExists("new"));
888   EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
889 }
890
891 TEST_F(FileSystemOperationImplTest, TestCreateFileSuccessFileDoesntExist) {
892   // Non existing file.
893   EXPECT_EQ(base::File::FILE_OK, CreateFile(URLForPath("nonexistent"), false));
894   EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count());
895 }
896
897 TEST_F(FileSystemOperationImplTest,
898        TestCreateDirFailureDestParentDoesntExist) {
899   // Dest. parent path does not exist.
900   EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
901             CreateDirectory(URLForPath("nonexistent/dir"), false, false));
902   EXPECT_TRUE(change_observer()->HasNoChange());
903 }
904
905 TEST_F(FileSystemOperationImplTest, TestCreateDirFailureDirExists) {
906   // Exclusive and dir existing at path.
907   FileSystemURL dir(CreateDirectory("dir"));
908   EXPECT_EQ(base::File::FILE_ERROR_EXISTS, CreateDirectory(dir, true, false));
909   EXPECT_TRUE(change_observer()->HasNoChange());
910 }
911
912 TEST_F(FileSystemOperationImplTest, TestCreateDirFailureFileExists) {
913   // Exclusive true and file existing at path.
914   FileSystemURL file(CreateFile("file"));
915   EXPECT_EQ(base::File::FILE_ERROR_EXISTS, CreateDirectory(file, true, false));
916   EXPECT_TRUE(change_observer()->HasNoChange());
917 }
918
919 TEST_F(FileSystemOperationImplTest, TestCreateDirSuccess) {
920   // Dir exists and exclusive is false.
921   FileSystemURL dir(CreateDirectory("dir"));
922   EXPECT_EQ(base::File::FILE_OK, CreateDirectory(dir, false, false));
923   EXPECT_TRUE(change_observer()->HasNoChange());
924
925   // Dir doesn't exist.
926   EXPECT_EQ(base::File::FILE_OK,
927             CreateDirectory(URLForPath("new"), false, false));
928   EXPECT_TRUE(DirectoryExists("new"));
929   EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
930 }
931
932 TEST_F(FileSystemOperationImplTest, TestCreateDirSuccessExclusive) {
933   // Dir doesn't exist.
934   EXPECT_EQ(base::File::FILE_OK,
935             CreateDirectory(URLForPath("new"), true, false));
936   EXPECT_TRUE(DirectoryExists("new"));
937   EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count());
938   EXPECT_TRUE(change_observer()->HasNoChange());
939 }
940
941 TEST_F(FileSystemOperationImplTest, TestExistsAndMetadataFailure) {
942   EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
943             GetMetadata(URLForPath("nonexistent")));
944
945   EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
946             FileExists(URLForPath("nonexistent")));
947
948   EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
949             DirectoryExists(URLForPath("nonexistent")));
950   EXPECT_TRUE(change_observer()->HasNoChange());
951 }
952
953 TEST_F(FileSystemOperationImplTest, TestExistsAndMetadataSuccess) {
954   FileSystemURL dir(CreateDirectory("dir"));
955   FileSystemURL file(CreateFile("dir/file"));
956   int read_access = 0;
957
958   EXPECT_EQ(base::File::FILE_OK, DirectoryExists(dir));
959   ++read_access;
960
961   EXPECT_EQ(base::File::FILE_OK, GetMetadata(dir));
962   EXPECT_TRUE(info().is_directory);
963   ++read_access;
964
965   EXPECT_EQ(base::File::FILE_OK, FileExists(file));
966   ++read_access;
967
968   EXPECT_EQ(base::File::FILE_OK, GetMetadata(file));
969   EXPECT_FALSE(info().is_directory);
970   ++read_access;
971
972   EXPECT_EQ(read_access,
973             quota_manager_proxy()->notify_storage_accessed_count());
974   EXPECT_TRUE(change_observer()->HasNoChange());
975 }
976
977 TEST_F(FileSystemOperationImplTest, TestTypeMismatchErrors) {
978   FileSystemURL dir(CreateDirectory("dir"));
979   EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE, FileExists(dir));
980
981   FileSystemURL file(CreateFile("file"));
982   EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY, DirectoryExists(file));
983 }
984
985 TEST_F(FileSystemOperationImplTest, TestReadDirFailure) {
986   // Path doesn't exist
987   EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
988             ReadDirectory(URLForPath("nonexistent")));
989
990   // File exists.
991   FileSystemURL file(CreateFile("file"));
992   EXPECT_EQ(base::File::FILE_ERROR_NOT_A_DIRECTORY, ReadDirectory(file));
993   EXPECT_TRUE(change_observer()->HasNoChange());
994 }
995
996 TEST_F(FileSystemOperationImplTest, TestReadDirSuccess) {
997   //      parent_dir
998   //       |       |
999   //  child_dir  child_file
1000   // Verify reading parent_dir.
1001   FileSystemURL parent_dir(CreateDirectory("dir"));
1002   FileSystemURL child_dir(CreateDirectory("dir/child_dir"));
1003   FileSystemURL child_file(CreateFile("dir/child_file"));
1004
1005   EXPECT_EQ(base::File::FILE_OK, ReadDirectory(parent_dir));
1006   EXPECT_EQ(2u, entries().size());
1007
1008   for (size_t i = 0; i < entries().size(); ++i) {
1009     if (entries()[i].is_directory)
1010       EXPECT_EQ(FILE_PATH_LITERAL("child_dir"), entries()[i].name);
1011     else
1012       EXPECT_EQ(FILE_PATH_LITERAL("child_file"), entries()[i].name);
1013   }
1014   EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count());
1015   EXPECT_TRUE(change_observer()->HasNoChange());
1016 }
1017
1018 TEST_F(FileSystemOperationImplTest, TestRemoveFailure) {
1019   // Path doesn't exist.
1020   EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
1021             Remove(URLForPath("nonexistent"), false /* recursive */));
1022
1023   // It's an error to try to remove a non-empty directory if recursive flag
1024   // is false.
1025   //      parent_dir
1026   //       |       |
1027   //  child_dir  child_file
1028   // Verify deleting parent_dir.
1029   FileSystemURL parent_dir(CreateDirectory("dir"));
1030   FileSystemURL child_dir(CreateDirectory("dir/child_dir"));
1031   FileSystemURL child_file(CreateFile("dir/child_file"));
1032
1033   EXPECT_EQ(base::File::FILE_ERROR_NOT_EMPTY,
1034             Remove(parent_dir, false /* recursive */));
1035   EXPECT_TRUE(change_observer()->HasNoChange());
1036 }
1037
1038 TEST_F(FileSystemOperationImplTest, TestRemoveSuccess) {
1039   FileSystemURL empty_dir(CreateDirectory("empty_dir"));
1040   EXPECT_TRUE(DirectoryExists("empty_dir"));
1041   EXPECT_EQ(base::File::FILE_OK, Remove(empty_dir, false /* recursive */));
1042   EXPECT_FALSE(DirectoryExists("empty_dir"));
1043
1044   EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count());
1045   EXPECT_TRUE(change_observer()->HasNoChange());
1046 }
1047
1048 TEST_F(FileSystemOperationImplTest, TestRemoveSuccessRecursive) {
1049   // Removing a non-empty directory with recursive flag == true should be ok.
1050   //      parent_dir
1051   //       |       |
1052   //  child_dir  child_files
1053   //       |
1054   //  child_files
1055   //
1056   // Verify deleting parent_dir.
1057   FileSystemURL parent_dir(CreateDirectory("dir"));
1058   for (int i = 0; i < 8; ++i)
1059     CreateFile(base::StringPrintf("dir/file-%d", i));
1060   FileSystemURL child_dir(CreateDirectory("dir/child_dir"));
1061   for (int i = 0; i < 8; ++i)
1062     CreateFile(base::StringPrintf("dir/child_dir/file-%d", i));
1063
1064   EXPECT_EQ(base::File::FILE_OK, Remove(parent_dir, true /* recursive */));
1065   EXPECT_FALSE(DirectoryExists("parent_dir"));
1066
1067   EXPECT_EQ(2, change_observer()->get_and_reset_remove_directory_count());
1068   EXPECT_EQ(16, change_observer()->get_and_reset_remove_file_count());
1069   EXPECT_TRUE(change_observer()->HasNoChange());
1070 }
1071
1072 TEST_F(FileSystemOperationImplTest, TestTruncate) {
1073   FileSystemURL file(CreateFile("file"));
1074   base::FilePath platform_path = PlatformPath("file");
1075
1076   char test_data[] = "test data";
1077   int data_size = static_cast<int>(sizeof(test_data));
1078   EXPECT_EQ(data_size,
1079             base::WriteFile(platform_path, test_data, data_size));
1080
1081   // Check that its length is the size of the data written.
1082   EXPECT_EQ(base::File::FILE_OK, GetMetadata(file));
1083   EXPECT_FALSE(info().is_directory);
1084   EXPECT_EQ(data_size, info().size);
1085
1086   // Extend the file by truncating it.
1087   int length = 17;
1088   EXPECT_EQ(base::File::FILE_OK, Truncate(file, length));
1089
1090   EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1091   EXPECT_TRUE(change_observer()->HasNoChange());
1092
1093   // Check that its length is now 17 and that it's all zeroes after the test
1094   // data.
1095   EXPECT_EQ(length, GetFileSize("file"));
1096   char data[100];
1097   EXPECT_EQ(length, base::ReadFile(platform_path, data, length));
1098   for (int i = 0; i < length; ++i) {
1099     if (i < static_cast<int>(sizeof(test_data)))
1100       EXPECT_EQ(test_data[i], data[i]);
1101     else
1102       EXPECT_EQ(0, data[i]);
1103   }
1104
1105   // Shorten the file by truncating it.
1106   length = 3;
1107   EXPECT_EQ(base::File::FILE_OK, Truncate(file, length));
1108
1109   EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1110   EXPECT_TRUE(change_observer()->HasNoChange());
1111
1112   // Check that its length is now 3 and that it contains only bits of test data.
1113   EXPECT_EQ(length, GetFileSize("file"));
1114   EXPECT_EQ(length, base::ReadFile(platform_path, data, length));
1115   for (int i = 0; i < length; ++i)
1116     EXPECT_EQ(test_data[i], data[i]);
1117
1118   // Truncate is not a 'read' access.  (Here expected access count is 1
1119   // since we made 1 read access for GetMetadata.)
1120   EXPECT_EQ(1, quota_manager_proxy()->notify_storage_accessed_count());
1121 }
1122
1123 TEST_F(FileSystemOperationImplTest, TestTruncateFailureByQuota) {
1124   FileSystemURL dir(CreateDirectory("dir"));
1125   FileSystemURL file(CreateFile("dir/file"));
1126
1127   GrantQuotaForCurrentUsage();
1128   AddQuota(10);
1129
1130   EXPECT_EQ(base::File::FILE_OK, Truncate(file, 10));
1131   EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count());
1132   EXPECT_TRUE(change_observer()->HasNoChange());
1133
1134   EXPECT_EQ(10, GetFileSize("dir/file"));
1135
1136   EXPECT_EQ(base::File::FILE_ERROR_NO_SPACE, Truncate(file, 11));
1137   EXPECT_TRUE(change_observer()->HasNoChange());
1138
1139   EXPECT_EQ(10, GetFileSize("dir/file"));
1140 }
1141
1142 TEST_F(FileSystemOperationImplTest, TestTouchFile) {
1143   FileSystemURL file(CreateFile("file"));
1144   base::FilePath platform_path = PlatformPath("file");
1145
1146   base::File::Info info;
1147   EXPECT_TRUE(base::GetFileInfo(platform_path, &info));
1148   EXPECT_FALSE(info.is_directory);
1149   EXPECT_EQ(0, info.size);
1150   const base::Time last_modified = info.last_modified;
1151   const base::Time last_accessed = info.last_accessed;
1152
1153   const base::Time new_modified_time = base::Time::UnixEpoch();
1154   const base::Time new_accessed_time = new_modified_time +
1155       base::TimeDelta::FromHours(77);
1156   ASSERT_NE(last_modified, new_modified_time);
1157   ASSERT_NE(last_accessed, new_accessed_time);
1158
1159   EXPECT_EQ(base::File::FILE_OK,
1160             TouchFile(file, new_accessed_time, new_modified_time));
1161   EXPECT_TRUE(change_observer()->HasNoChange());
1162
1163   EXPECT_TRUE(base::GetFileInfo(platform_path, &info));
1164   // We compare as time_t here to lower our resolution, to avoid false
1165   // negatives caused by conversion to the local filesystem's native
1166   // representation and back.
1167   EXPECT_EQ(new_modified_time.ToTimeT(), info.last_modified.ToTimeT());
1168   EXPECT_EQ(new_accessed_time.ToTimeT(), info.last_accessed.ToTimeT());
1169 }
1170
1171 TEST_F(FileSystemOperationImplTest, TestCreateSnapshotFile) {
1172   FileSystemURL dir(CreateDirectory("dir"));
1173
1174   // Create a file for the testing.
1175   EXPECT_EQ(base::File::FILE_OK, DirectoryExists(dir));
1176   FileSystemURL file(CreateFile("dir/file"));
1177   EXPECT_EQ(base::File::FILE_OK, FileExists(file));
1178
1179   // See if we can get a 'snapshot' file info for the file.
1180   // Since FileSystemOperationImpl assumes the file exists in the local
1181   // directory it should just returns the same metadata and platform_path
1182   // as the file itself.
1183   EXPECT_EQ(base::File::FILE_OK, CreateSnapshotFile(file));
1184   EXPECT_FALSE(info().is_directory);
1185   EXPECT_EQ(PlatformPath("dir/file"), path());
1186   EXPECT_TRUE(change_observer()->HasNoChange());
1187
1188   // The FileSystemOpration implementation does not create a
1189   // shareable file reference.
1190   EXPECT_EQ(NULL, shareable_file_ref());
1191 }
1192
1193 TEST_F(FileSystemOperationImplTest,
1194        TestMoveSuccessSrcDirRecursiveWithQuota) {
1195   FileSystemURL src(CreateDirectory("src"));
1196   int src_path_cost = GetUsage();
1197
1198   FileSystemURL dest(CreateDirectory("dest"));
1199   FileSystemURL child_file1(CreateFile("src/file1"));
1200   FileSystemURL child_file2(CreateFile("src/file2"));
1201   FileSystemURL child_dir(CreateDirectory("src/dir"));
1202   FileSystemURL grandchild_file1(CreateFile("src/dir/file1"));
1203   FileSystemURL grandchild_file2(CreateFile("src/dir/file2"));
1204
1205   int total_path_cost = GetUsage();
1206   EXPECT_EQ(0, GetDataSizeOnDisk());
1207
1208   EXPECT_EQ(base::File::FILE_OK, Truncate(child_file1, 5000));
1209   EXPECT_EQ(base::File::FILE_OK, Truncate(child_file2, 400));
1210   EXPECT_EQ(base::File::FILE_OK, Truncate(grandchild_file1, 30));
1211   EXPECT_EQ(base::File::FILE_OK, Truncate(grandchild_file2, 2));
1212
1213   const int64 all_file_size = 5000 + 400 + 30 + 2;
1214   EXPECT_EQ(all_file_size, GetDataSizeOnDisk());
1215   EXPECT_EQ(all_file_size + total_path_cost, GetUsage());
1216
1217   EXPECT_EQ(base::File::FILE_OK,
1218             Move(src, dest, FileSystemOperation::OPTION_NONE));
1219
1220   EXPECT_FALSE(DirectoryExists("src/dir"));
1221   EXPECT_FALSE(FileExists("src/dir/file2"));
1222   EXPECT_TRUE(DirectoryExists("dest/dir"));
1223   EXPECT_TRUE(FileExists("dest/dir/file2"));
1224
1225   EXPECT_EQ(all_file_size, GetDataSizeOnDisk());
1226   EXPECT_EQ(all_file_size + total_path_cost - src_path_cost,
1227             GetUsage());
1228 }
1229
1230 TEST_F(FileSystemOperationImplTest,
1231        TestCopySuccessSrcDirRecursiveWithQuota) {
1232   FileSystemURL src(CreateDirectory("src"));
1233   FileSystemURL dest1(CreateDirectory("dest1"));
1234   FileSystemURL dest2(CreateDirectory("dest2"));
1235
1236   int64 usage = GetUsage();
1237   FileSystemURL child_file1(CreateFile("src/file1"));
1238   FileSystemURL child_file2(CreateFile("src/file2"));
1239   FileSystemURL child_dir(CreateDirectory("src/dir"));
1240   int64 child_path_cost = GetUsage() - usage;
1241   usage += child_path_cost;
1242
1243   FileSystemURL grandchild_file1(CreateFile("src/dir/file1"));
1244   FileSystemURL grandchild_file2(CreateFile("src/dir/file2"));
1245   int64 total_path_cost = GetUsage();
1246   int64 grandchild_path_cost = total_path_cost - usage;
1247
1248   EXPECT_EQ(0, GetDataSizeOnDisk());
1249
1250   EXPECT_EQ(base::File::FILE_OK, Truncate(child_file1, 8000));
1251   EXPECT_EQ(base::File::FILE_OK, Truncate(child_file2, 700));
1252   EXPECT_EQ(base::File::FILE_OK, Truncate(grandchild_file1, 60));
1253   EXPECT_EQ(base::File::FILE_OK, Truncate(grandchild_file2, 5));
1254
1255   const int64 child_file_size = 8000 + 700;
1256   const int64 grandchild_file_size = 60 + 5;
1257   const int64 all_file_size = child_file_size + grandchild_file_size;
1258   int64 expected_usage = all_file_size + total_path_cost;
1259
1260   usage = GetUsage();
1261   EXPECT_EQ(all_file_size, GetDataSizeOnDisk());
1262   EXPECT_EQ(expected_usage, usage);
1263
1264   EXPECT_EQ(base::File::FILE_OK,
1265             Copy(src, dest1, FileSystemOperation::OPTION_NONE));
1266
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"));
1272
1273   EXPECT_EQ(2 * all_file_size, GetDataSizeOnDisk());
1274   EXPECT_EQ(expected_usage, GetUsage());
1275
1276   EXPECT_EQ(base::File::FILE_OK,
1277             Copy(child_dir, dest2, FileSystemOperation::OPTION_NONE));
1278
1279   expected_usage += grandchild_file_size + grandchild_path_cost;
1280   usage = GetUsage();
1281   EXPECT_EQ(2 * child_file_size + 3 * grandchild_file_size,
1282             GetDataSizeOnDisk());
1283   EXPECT_EQ(expected_usage, usage);
1284 }
1285
1286 TEST_F(FileSystemOperationImplTest,
1287        TestCopySuccessSrcFileWithDifferentFileSize) {
1288   FileSystemURL src_file(CreateFile("src"));
1289   FileSystemURL dest_file(CreateFile("dest"));
1290
1291   EXPECT_EQ(base::File::FILE_OK, Truncate(dest_file, 6));
1292   EXPECT_EQ(base::File::FILE_OK,
1293             Copy(src_file, dest_file, FileSystemOperation::OPTION_NONE));
1294   EXPECT_EQ(0, GetFileSize("dest"));
1295 }
1296
1297 }  // namespace content