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