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