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