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/sandbox_file_system_test_helper.h" 16#include "testing/gtest/include/gtest/gtest.h" 17#include "url/gurl.h" 18#include "webkit/browser/fileapi/async_file_test_helper.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/quota_manager.h" 27#include "webkit/common/blob/shareable_file_reference.h" 28#include "webkit/common/fileapi/file_system_util.h" 29 30using quota::QuotaManager; 31using quota::QuotaManagerProxy; 32using webkit_blob::ShareableFileReference; 33 34namespace fileapi { 35 36namespace { 37 38const int kFileOperationStatusNotSet = 1; 39 40void 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. 49class 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(base::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 296TEST_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 306TEST_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 318TEST_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 332TEST_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 347TEST_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 361TEST_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 372TEST_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 390TEST_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 405TEST_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 425TEST_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 442TEST_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 464TEST_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 474TEST_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 487TEST_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 502TEST_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 518TEST_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 532TEST_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 545TEST_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 568TEST_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 585TEST_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 601TEST_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 622TEST_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 639TEST_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 665TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileSuccess) { 666 base::FilePath src_local_disk_file_path; 667 base::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, base::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 698TEST_F(FileSystemOperationImplTest, TestCopyInForeignFileFailureByQuota) { 699 base::FilePath src_local_disk_file_path; 700 base::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 718TEST_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 727TEST_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 739TEST_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 749TEST_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 758TEST_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 769TEST_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 779TEST_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 789TEST_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 807TEST_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 818TEST_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 836TEST_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 868TEST_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 880TEST_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 895TEST_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 919TEST_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 943TEST_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 956TEST_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 983TEST_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, base::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, base::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 1040TEST_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 1063TEST_F(FileSystemOperationImplTest, TestTouchFile) { 1064 FileSystemURL file(CreateFile("file")); 1065 base::FilePath platform_path = PlatformPath("file"); 1066 1067 base::PlatformFileInfo info; 1068 EXPECT_TRUE(base::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(base::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 1094TEST_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 1120TEST_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 1168TEST_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 1242