obfuscated_file_util_unittest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright (c) 2012 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 <set> 6#include <string> 7#include <vector> 8 9#include "base/bind.h" 10#include "base/file_util.h" 11#include "base/files/file_path.h" 12#include "base/files/scoped_temp_dir.h" 13#include "base/memory/scoped_ptr.h" 14#include "base/message_loop.h" 15#include "base/platform_file.h" 16#include "testing/gtest/include/gtest/gtest.h" 17#include "webkit/browser/fileapi/async_file_test_helper.h" 18#include "webkit/browser/fileapi/external_mount_points.h" 19#include "webkit/browser/fileapi/file_system_context.h" 20#include "webkit/browser/fileapi/file_system_mount_point_provider.h" 21#include "webkit/browser/fileapi/file_system_operation_context.h" 22#include "webkit/browser/fileapi/file_system_task_runners.h" 23#include "webkit/browser/fileapi/file_system_usage_cache.h" 24#include "webkit/browser/fileapi/mock_file_change_observer.h" 25#include "webkit/browser/fileapi/mock_file_system_context.h" 26#include "webkit/browser/fileapi/obfuscated_file_util.h" 27#include "webkit/browser/fileapi/sandbox_directory_database.h" 28#include "webkit/browser/fileapi/sandbox_file_system_test_helper.h" 29#include "webkit/browser/fileapi/sandbox_origin_database.h" 30#include "webkit/browser/fileapi/test_file_set.h" 31#include "webkit/browser/quota/mock_special_storage_policy.h" 32#include "webkit/browser/quota/quota_manager.h" 33#include "webkit/common/quota/quota_types.h" 34 35namespace fileapi { 36 37namespace { 38 39bool FileExists(const base::FilePath& path) { 40 return file_util::PathExists(path) && !file_util::DirectoryExists(path); 41} 42 43int64 GetSize(const base::FilePath& path) { 44 int64 size; 45 EXPECT_TRUE(file_util::GetFileSize(path, &size)); 46 return size; 47} 48 49// After a move, the dest exists and the source doesn't. 50// After a copy, both source and dest exist. 51struct CopyMoveTestCaseRecord { 52 bool is_copy_not_move; 53 const char source_path[64]; 54 const char dest_path[64]; 55 bool cause_overwrite; 56}; 57 58const CopyMoveTestCaseRecord kCopyMoveTestCases[] = { 59 // This is the combinatoric set of: 60 // rename vs. same-name 61 // different directory vs. same directory 62 // overwrite vs. no-overwrite 63 // copy vs. move 64 // We can never be called with source and destination paths identical, so 65 // those cases are omitted. 66 {true, "dir0/file0", "dir0/file1", false}, 67 {false, "dir0/file0", "dir0/file1", false}, 68 {true, "dir0/file0", "dir0/file1", true}, 69 {false, "dir0/file0", "dir0/file1", true}, 70 71 {true, "dir0/file0", "dir1/file0", false}, 72 {false, "dir0/file0", "dir1/file0", false}, 73 {true, "dir0/file0", "dir1/file0", true}, 74 {false, "dir0/file0", "dir1/file0", true}, 75 {true, "dir0/file0", "dir1/file1", false}, 76 {false, "dir0/file0", "dir1/file1", false}, 77 {true, "dir0/file0", "dir1/file1", true}, 78 {false, "dir0/file0", "dir1/file1", true}, 79}; 80 81struct OriginEnumerationTestRecord { 82 std::string origin_url; 83 bool has_temporary; 84 bool has_persistent; 85}; 86 87const OriginEnumerationTestRecord kOriginEnumerationTestRecords[] = { 88 {"http://example.com", false, true}, 89 {"http://example1.com", true, false}, 90 {"https://example1.com", true, true}, 91 {"file://", false, true}, 92 {"http://example.com:8000", false, true}, 93}; 94 95FileSystemURL FileSystemURLAppend( 96 const FileSystemURL& url, const base::FilePath::StringType& child) { 97 return FileSystemURL::CreateForTest( 98 url.origin(), url.mount_type(), url.virtual_path().Append(child)); 99} 100 101FileSystemURL FileSystemURLAppendUTF8( 102 const FileSystemURL& url, const std::string& child) { 103 return FileSystemURL::CreateForTest( 104 url.origin(), 105 url.mount_type(), 106 url.virtual_path().Append(base::FilePath::FromUTF8Unsafe(child))); 107} 108 109FileSystemURL FileSystemURLDirName(const FileSystemURL& url) { 110 return FileSystemURL::CreateForTest( 111 url.origin(), url.mount_type(), VirtualPath::DirName(url.virtual_path())); 112} 113 114} // namespace (anonymous) 115 116// TODO(ericu): The vast majority of this and the other FSFU subclass tests 117// could theoretically be shared. It would basically be a FSFU interface 118// compliance test, and only the subclass-specific bits that look into the 119// implementation would need to be written per-subclass. 120class ObfuscatedFileUtilTest : public testing::Test { 121 public: 122 ObfuscatedFileUtilTest() 123 : origin_(GURL("http://www.example.com")), 124 type_(kFileSystemTypeTemporary), 125 weak_factory_(this), 126 sandbox_file_system_(origin_, type_), 127 quota_status_(quota::kQuotaStatusUnknown), 128 usage_(-1) { 129 } 130 131 virtual void SetUp() { 132 ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); 133 134 storage_policy_ = new quota::MockSpecialStoragePolicy(); 135 136 quota_manager_ = 137 new quota::QuotaManager(false /* is_incognito */, 138 data_dir_.path(), 139 base::MessageLoopProxy::current().get(), 140 base::MessageLoopProxy::current().get(), 141 storage_policy_.get()); 142 143 // Every time we create a new sandbox_file_system helper, 144 // it creates another context, which creates another path manager, 145 // another sandbox_mount_point_provider, and 146 // another OFU. We need to pass in the context to skip all that. 147 file_system_context_ = CreateFileSystemContextForTesting( 148 quota_manager_->proxy(), 149 data_dir_.path()); 150 151 sandbox_file_system_.SetUp(file_system_context_.get()); 152 153 change_observers_ = MockFileChangeObserver::CreateList(&change_observer_); 154 } 155 156 virtual void TearDown() { 157 quota_manager_ = NULL; 158 sandbox_file_system_.TearDown(); 159 } 160 161 scoped_ptr<FileSystemOperationContext> LimitedContext( 162 int64 allowed_bytes_growth) { 163 scoped_ptr<FileSystemOperationContext> context( 164 sandbox_file_system_.NewOperationContext()); 165 context->set_allowed_bytes_growth(allowed_bytes_growth); 166 return context.Pass(); 167 } 168 169 scoped_ptr<FileSystemOperationContext> UnlimitedContext() { 170 return LimitedContext(kint64max); 171 } 172 173 FileSystemOperationContext* NewContext( 174 SandboxFileSystemTestHelper* file_system) { 175 change_observer()->ResetCount(); 176 FileSystemOperationContext* context; 177 if (file_system) 178 context = file_system->NewOperationContext(); 179 else 180 context = sandbox_file_system_.NewOperationContext(); 181 // Setting allowed_bytes_growth big enough for all tests. 182 context->set_allowed_bytes_growth(1024 * 1024); 183 context->set_change_observers(change_observers()); 184 return context; 185 } 186 187 const ChangeObserverList& change_observers() const { 188 return change_observers_; 189 } 190 191 MockFileChangeObserver* change_observer() { 192 return &change_observer_; 193 } 194 195 // This can only be used after SetUp has run and created file_system_context_ 196 // and obfuscated_file_util_. 197 // Use this for tests which need to run in multiple origins; we need a test 198 // helper per origin. 199 SandboxFileSystemTestHelper* NewFileSystem( 200 const GURL& origin, fileapi::FileSystemType type) { 201 SandboxFileSystemTestHelper* file_system = 202 new SandboxFileSystemTestHelper(origin, type); 203 204 file_system->SetUp(file_system_context_.get()); 205 return file_system; 206 } 207 208 ObfuscatedFileUtil* ofu() { 209 return static_cast<ObfuscatedFileUtil*>(sandbox_file_system_.file_util()); 210 } 211 212 const base::FilePath& test_directory() const { 213 return data_dir_.path(); 214 } 215 216 const GURL& origin() const { 217 return origin_; 218 } 219 220 fileapi::FileSystemType type() const { 221 return type_; 222 } 223 224 int64 ComputeTotalFileSize() { 225 return sandbox_file_system_.ComputeCurrentOriginUsage() - 226 sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage(); 227 } 228 229 void GetUsageFromQuotaManager() { 230 int64 quota = -1; 231 quota_status_ = 232 AsyncFileTestHelper::GetUsageAndQuota(quota_manager_.get(), 233 origin(), 234 sandbox_file_system_.type(), 235 &usage_, 236 "a); 237 EXPECT_EQ(quota::kQuotaStatusOk, quota_status_); 238 } 239 240 void RevokeUsageCache() { 241 quota_manager_->ResetUsageTracker(sandbox_file_system_.storage_type()); 242 usage_cache()->Delete(sandbox_file_system_.GetUsageCachePath()); 243 } 244 245 int64 SizeByQuotaUtil() { 246 return sandbox_file_system_.GetCachedOriginUsage(); 247 } 248 249 int64 SizeInUsageFile() { 250 base::MessageLoop::current()->RunUntilIdle(); 251 int64 usage = 0; 252 return usage_cache()->GetUsage( 253 sandbox_file_system_.GetUsageCachePath(), &usage) ? usage : -1; 254 } 255 256 bool PathExists(const FileSystemURL& url) { 257 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 258 base::PlatformFileInfo file_info; 259 base::FilePath platform_path; 260 base::PlatformFileError error = ofu()->GetFileInfo( 261 context.get(), url, &file_info, &platform_path); 262 return error == base::PLATFORM_FILE_OK; 263 } 264 265 bool DirectoryExists(const FileSystemURL& url) { 266 return AsyncFileTestHelper::DirectoryExists(file_system_context(), url); 267 } 268 269 int64 usage() const { return usage_; } 270 FileSystemUsageCache* usage_cache() { 271 return sandbox_file_system_.usage_cache(); 272 } 273 274 FileSystemURL CreateURLFromUTF8(const std::string& path) { 275 return sandbox_file_system_.CreateURLFromUTF8(path); 276 } 277 278 int64 PathCost(const FileSystemURL& url) { 279 return ObfuscatedFileUtil::ComputeFilePathCost(url.path()); 280 } 281 282 FileSystemURL CreateURL(const base::FilePath& path) { 283 return sandbox_file_system_.CreateURL(path); 284 } 285 286 void CheckFileAndCloseHandle( 287 const FileSystemURL& url, base::PlatformFile file_handle) { 288 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 289 base::FilePath local_path; 290 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetLocalFilePath( 291 context.get(), url, &local_path)); 292 293 base::PlatformFileInfo file_info0; 294 base::FilePath data_path; 295 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo( 296 context.get(), url, &file_info0, &data_path)); 297 EXPECT_EQ(data_path, local_path); 298 EXPECT_TRUE(FileExists(data_path)); 299 EXPECT_EQ(0, GetSize(data_path)); 300 301 const char data[] = "test data"; 302 const int length = arraysize(data) - 1; 303 304 if (base::kInvalidPlatformFileValue == file_handle) { 305 bool created = true; 306 base::PlatformFileError error; 307 file_handle = base::CreatePlatformFile( 308 data_path, 309 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE, 310 &created, 311 &error); 312 ASSERT_NE(base::kInvalidPlatformFileValue, file_handle); 313 ASSERT_EQ(base::PLATFORM_FILE_OK, error); 314 EXPECT_FALSE(created); 315 } 316 ASSERT_EQ(length, base::WritePlatformFile(file_handle, 0, data, length)); 317 EXPECT_TRUE(base::ClosePlatformFile(file_handle)); 318 319 base::PlatformFileInfo file_info1; 320 EXPECT_EQ(length, GetSize(data_path)); 321 context.reset(NewContext(NULL)); 322 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo( 323 context.get(), url, &file_info1, &data_path)); 324 EXPECT_EQ(data_path, local_path); 325 326 EXPECT_FALSE(file_info0.is_directory); 327 EXPECT_FALSE(file_info1.is_directory); 328 EXPECT_FALSE(file_info0.is_symbolic_link); 329 EXPECT_FALSE(file_info1.is_symbolic_link); 330 EXPECT_EQ(0, file_info0.size); 331 EXPECT_EQ(length, file_info1.size); 332 EXPECT_LE(file_info0.last_modified, file_info1.last_modified); 333 334 context.reset(NewContext(NULL)); 335 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->Truncate( 336 context.get(), url, length * 2)); 337 EXPECT_EQ(length * 2, GetSize(data_path)); 338 339 context.reset(NewContext(NULL)); 340 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->Truncate( 341 context.get(), url, 0)); 342 EXPECT_EQ(0, GetSize(data_path)); 343 } 344 345 void ValidateTestDirectory( 346 const FileSystemURL& root_url, 347 const std::set<base::FilePath::StringType>& files, 348 const std::set<base::FilePath::StringType>& directories) { 349 scoped_ptr<FileSystemOperationContext> context; 350 std::set<base::FilePath::StringType>::const_iterator iter; 351 for (iter = files.begin(); iter != files.end(); ++iter) { 352 bool created = true; 353 context.reset(NewContext(NULL)); 354 ASSERT_EQ(base::PLATFORM_FILE_OK, 355 ofu()->EnsureFileExists( 356 context.get(), FileSystemURLAppend(root_url, *iter), 357 &created)); 358 ASSERT_FALSE(created); 359 } 360 for (iter = directories.begin(); iter != directories.end(); ++iter) { 361 context.reset(NewContext(NULL)); 362 EXPECT_TRUE(DirectoryExists( 363 FileSystemURLAppend(root_url, *iter))); 364 } 365 } 366 367 class UsageVerifyHelper { 368 public: 369 UsageVerifyHelper(scoped_ptr<FileSystemOperationContext> context, 370 SandboxFileSystemTestHelper* file_system, 371 int64 expected_usage) 372 : context_(context.Pass()), 373 sandbox_file_system_(file_system), 374 expected_usage_(expected_usage) {} 375 376 ~UsageVerifyHelper() { 377 base::MessageLoop::current()->RunUntilIdle(); 378 Check(); 379 } 380 381 FileSystemOperationContext* context() { 382 return context_.get(); 383 } 384 385 private: 386 void Check() { 387 ASSERT_EQ(expected_usage_, 388 sandbox_file_system_->GetCachedOriginUsage()); 389 } 390 391 scoped_ptr<FileSystemOperationContext> context_; 392 SandboxFileSystemTestHelper* sandbox_file_system_; 393 int64 expected_usage_; 394 }; 395 396 scoped_ptr<UsageVerifyHelper> AllowUsageIncrease(int64 requested_growth) { 397 int64 usage = sandbox_file_system_.GetCachedOriginUsage(); 398 return scoped_ptr<UsageVerifyHelper>(new UsageVerifyHelper( 399 LimitedContext(requested_growth), 400 &sandbox_file_system_, usage + requested_growth)); 401 } 402 403 scoped_ptr<UsageVerifyHelper> DisallowUsageIncrease(int64 requested_growth) { 404 int64 usage = sandbox_file_system_.GetCachedOriginUsage(); 405 return scoped_ptr<UsageVerifyHelper>(new UsageVerifyHelper( 406 LimitedContext(requested_growth - 1), &sandbox_file_system_, usage)); 407 } 408 409 void FillTestDirectory( 410 const FileSystemURL& root_url, 411 std::set<base::FilePath::StringType>* files, 412 std::set<base::FilePath::StringType>* directories) { 413 scoped_ptr<FileSystemOperationContext> context; 414 std::vector<DirectoryEntry> entries; 415 EXPECT_EQ(base::PLATFORM_FILE_OK, 416 AsyncFileTestHelper::ReadDirectory( 417 file_system_context(), root_url, &entries)); 418 EXPECT_EQ(0UL, entries.size()); 419 420 files->clear(); 421 files->insert(FILE_PATH_LITERAL("first")); 422 files->insert(FILE_PATH_LITERAL("second")); 423 files->insert(FILE_PATH_LITERAL("third")); 424 directories->clear(); 425 directories->insert(FILE_PATH_LITERAL("fourth")); 426 directories->insert(FILE_PATH_LITERAL("fifth")); 427 directories->insert(FILE_PATH_LITERAL("sixth")); 428 std::set<base::FilePath::StringType>::iterator iter; 429 for (iter = files->begin(); iter != files->end(); ++iter) { 430 bool created = false; 431 context.reset(NewContext(NULL)); 432 ASSERT_EQ(base::PLATFORM_FILE_OK, 433 ofu()->EnsureFileExists( 434 context.get(), 435 FileSystemURLAppend(root_url, *iter), 436 &created)); 437 ASSERT_TRUE(created); 438 } 439 for (iter = directories->begin(); iter != directories->end(); ++iter) { 440 bool exclusive = true; 441 bool recursive = false; 442 context.reset(NewContext(NULL)); 443 EXPECT_EQ(base::PLATFORM_FILE_OK, 444 ofu()->CreateDirectory( 445 context.get(), 446 FileSystemURLAppend(root_url, *iter), 447 exclusive, recursive)); 448 } 449 ValidateTestDirectory(root_url, *files, *directories); 450 } 451 452 void TestReadDirectoryHelper(const FileSystemURL& root_url) { 453 std::set<base::FilePath::StringType> files; 454 std::set<base::FilePath::StringType> directories; 455 FillTestDirectory(root_url, &files, &directories); 456 457 scoped_ptr<FileSystemOperationContext> context; 458 std::vector<DirectoryEntry> entries; 459 context.reset(NewContext(NULL)); 460 EXPECT_EQ(base::PLATFORM_FILE_OK, 461 AsyncFileTestHelper::ReadDirectory( 462 file_system_context(), root_url, &entries)); 463 std::vector<DirectoryEntry>::iterator entry_iter; 464 EXPECT_EQ(files.size() + directories.size(), entries.size()); 465 EXPECT_TRUE(change_observer()->HasNoChange()); 466 for (entry_iter = entries.begin(); entry_iter != entries.end(); 467 ++entry_iter) { 468 const DirectoryEntry& entry = *entry_iter; 469 std::set<base::FilePath::StringType>::iterator iter = 470 files.find(entry.name); 471 if (iter != files.end()) { 472 EXPECT_FALSE(entry.is_directory); 473 files.erase(iter); 474 continue; 475 } 476 iter = directories.find(entry.name); 477 EXPECT_FALSE(directories.end() == iter); 478 EXPECT_TRUE(entry.is_directory); 479 directories.erase(iter); 480 } 481 } 482 483 void TestTouchHelper(const FileSystemURL& url, bool is_file) { 484 base::Time last_access_time = base::Time::Now(); 485 base::Time last_modified_time = base::Time::Now(); 486 487 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 488 EXPECT_EQ(base::PLATFORM_FILE_OK, 489 ofu()->Touch( 490 context.get(), url, last_access_time, last_modified_time)); 491 // Currently we fire no change notifications for Touch. 492 EXPECT_TRUE(change_observer()->HasNoChange()); 493 base::FilePath local_path; 494 base::PlatformFileInfo file_info; 495 context.reset(NewContext(NULL)); 496 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo( 497 context.get(), url, &file_info, &local_path)); 498 // We compare as time_t here to lower our resolution, to avoid false 499 // negatives caused by conversion to the local filesystem's native 500 // representation and back. 501 EXPECT_EQ(file_info.last_modified.ToTimeT(), last_modified_time.ToTimeT()); 502 503 context.reset(NewContext(NULL)); 504 last_modified_time += base::TimeDelta::FromHours(1); 505 last_access_time += base::TimeDelta::FromHours(14); 506 EXPECT_EQ(base::PLATFORM_FILE_OK, 507 ofu()->Touch( 508 context.get(), url, last_access_time, last_modified_time)); 509 EXPECT_TRUE(change_observer()->HasNoChange()); 510 context.reset(NewContext(NULL)); 511 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo( 512 context.get(), url, &file_info, &local_path)); 513 EXPECT_EQ(file_info.last_modified.ToTimeT(), last_modified_time.ToTimeT()); 514 if (is_file) // Directories in OFU don't support atime. 515 EXPECT_EQ(file_info.last_accessed.ToTimeT(), last_access_time.ToTimeT()); 516 } 517 518 void TestCopyInForeignFileHelper(bool overwrite) { 519 base::ScopedTempDir source_dir; 520 ASSERT_TRUE(source_dir.CreateUniqueTempDir()); 521 base::FilePath root_file_path = source_dir.path(); 522 base::FilePath src_file_path = root_file_path.AppendASCII("file_name"); 523 FileSystemURL dest_url = CreateURLFromUTF8("new file"); 524 int64 src_file_length = 87; 525 526 base::PlatformFileError error_code; 527 bool created = false; 528 int file_flags = base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE; 529 base::PlatformFile file_handle = 530 base::CreatePlatformFile( 531 src_file_path, file_flags, &created, &error_code); 532 EXPECT_TRUE(created); 533 ASSERT_EQ(base::PLATFORM_FILE_OK, error_code); 534 ASSERT_NE(base::kInvalidPlatformFileValue, file_handle); 535 ASSERT_TRUE(base::TruncatePlatformFile(file_handle, src_file_length)); 536 EXPECT_TRUE(base::ClosePlatformFile(file_handle)); 537 538 scoped_ptr<FileSystemOperationContext> context; 539 540 if (overwrite) { 541 context.reset(NewContext(NULL)); 542 EXPECT_EQ(base::PLATFORM_FILE_OK, 543 ofu()->EnsureFileExists(context.get(), dest_url, &created)); 544 EXPECT_TRUE(created); 545 546 // We must have observed one (and only one) create_file_count. 547 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count()); 548 EXPECT_TRUE(change_observer()->HasNoChange()); 549 } 550 551 const int64 path_cost = 552 ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()); 553 if (!overwrite) { 554 // Verify that file creation requires sufficient quota for the path. 555 context.reset(NewContext(NULL)); 556 context->set_allowed_bytes_growth(path_cost + src_file_length - 1); 557 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, 558 ofu()->CopyInForeignFile(context.get(), 559 src_file_path, dest_url)); 560 } 561 562 context.reset(NewContext(NULL)); 563 context->set_allowed_bytes_growth(path_cost + src_file_length); 564 EXPECT_EQ(base::PLATFORM_FILE_OK, 565 ofu()->CopyInForeignFile(context.get(), 566 src_file_path, dest_url)); 567 568 EXPECT_TRUE(PathExists(dest_url)); 569 EXPECT_FALSE(DirectoryExists(dest_url)); 570 571 context.reset(NewContext(NULL)); 572 base::PlatformFileInfo file_info; 573 base::FilePath data_path; 574 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo( 575 context.get(), dest_url, &file_info, &data_path)); 576 EXPECT_NE(data_path, src_file_path); 577 EXPECT_TRUE(FileExists(data_path)); 578 EXPECT_EQ(src_file_length, GetSize(data_path)); 579 580 EXPECT_EQ(base::PLATFORM_FILE_OK, 581 ofu()->DeleteFile(context.get(), dest_url)); 582 } 583 584 void ClearTimestamp(const FileSystemURL& url) { 585 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 586 EXPECT_EQ(base::PLATFORM_FILE_OK, 587 ofu()->Touch(context.get(), url, base::Time(), base::Time())); 588 EXPECT_EQ(base::Time(), GetModifiedTime(url)); 589 } 590 591 base::Time GetModifiedTime(const FileSystemURL& url) { 592 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 593 base::FilePath data_path; 594 base::PlatformFileInfo file_info; 595 context.reset(NewContext(NULL)); 596 EXPECT_EQ(base::PLATFORM_FILE_OK, 597 ofu()->GetFileInfo(context.get(), url, &file_info, &data_path)); 598 EXPECT_TRUE(change_observer()->HasNoChange()); 599 return file_info.last_modified; 600 } 601 602 void TestDirectoryTimestampHelper(const FileSystemURL& base_dir, 603 bool copy, 604 bool overwrite) { 605 scoped_ptr<FileSystemOperationContext> context; 606 const FileSystemURL src_dir_url( 607 FileSystemURLAppendUTF8(base_dir, "foo_dir")); 608 const FileSystemURL dest_dir_url( 609 FileSystemURLAppendUTF8(base_dir, "bar_dir")); 610 611 const FileSystemURL src_file_url( 612 FileSystemURLAppendUTF8(src_dir_url, "hoge")); 613 const FileSystemURL dest_file_url( 614 FileSystemURLAppendUTF8(dest_dir_url, "fuga")); 615 616 context.reset(NewContext(NULL)); 617 EXPECT_EQ(base::PLATFORM_FILE_OK, 618 ofu()->CreateDirectory(context.get(), src_dir_url, true, true)); 619 context.reset(NewContext(NULL)); 620 EXPECT_EQ(base::PLATFORM_FILE_OK, 621 ofu()->CreateDirectory(context.get(), dest_dir_url, true, true)); 622 623 bool created = false; 624 context.reset(NewContext(NULL)); 625 EXPECT_EQ(base::PLATFORM_FILE_OK, 626 ofu()->EnsureFileExists(context.get(), src_file_url, &created)); 627 if (overwrite) { 628 context.reset(NewContext(NULL)); 629 EXPECT_EQ(base::PLATFORM_FILE_OK, 630 ofu()->EnsureFileExists(context.get(), 631 dest_file_url, &created)); 632 } 633 634 ClearTimestamp(src_dir_url); 635 ClearTimestamp(dest_dir_url); 636 context.reset(NewContext(NULL)); 637 EXPECT_EQ(base::PLATFORM_FILE_OK, 638 ofu()->CopyOrMoveFile(context.get(), 639 src_file_url, dest_file_url, 640 copy)); 641 if (copy) 642 EXPECT_EQ(base::Time(), GetModifiedTime(src_dir_url)); 643 else 644 EXPECT_NE(base::Time(), GetModifiedTime(src_dir_url)); 645 EXPECT_NE(base::Time(), GetModifiedTime(dest_dir_url)); 646 } 647 648 int64 ComputeCurrentUsage() { 649 return sandbox_file_system_.ComputeCurrentOriginUsage() - 650 sandbox_file_system_.ComputeCurrentDirectoryDatabaseUsage(); 651 } 652 653 FileSystemContext* file_system_context() { 654 return sandbox_file_system_.file_system_context(); 655 } 656 657 const base::FilePath& data_dir_path() const { 658 return data_dir_.path(); 659 } 660 661 protected: 662 base::ScopedTempDir data_dir_; 663 base::MessageLoop message_loop_; 664 scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy_; 665 scoped_refptr<quota::QuotaManager> quota_manager_; 666 scoped_refptr<FileSystemContext> file_system_context_; 667 GURL origin_; 668 fileapi::FileSystemType type_; 669 base::WeakPtrFactory<ObfuscatedFileUtilTest> weak_factory_; 670 SandboxFileSystemTestHelper sandbox_file_system_; 671 quota::QuotaStatusCode quota_status_; 672 int64 usage_; 673 MockFileChangeObserver change_observer_; 674 ChangeObserverList change_observers_; 675 676 DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtilTest); 677}; 678 679TEST_F(ObfuscatedFileUtilTest, TestCreateAndDeleteFile) { 680 base::PlatformFile file_handle = base::kInvalidPlatformFileValue; 681 bool created; 682 FileSystemURL url = CreateURLFromUTF8("fake/file"); 683 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 684 int file_flags = base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE; 685 686 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 687 ofu()->CreateOrOpen( 688 context.get(), url, file_flags, &file_handle, 689 &created)); 690 691 context.reset(NewContext(NULL)); 692 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 693 ofu()->DeleteFile(context.get(), url)); 694 695 url = CreateURLFromUTF8("test file"); 696 697 EXPECT_TRUE(change_observer()->HasNoChange()); 698 699 // Verify that file creation requires sufficient quota for the path. 700 context.reset(NewContext(NULL)); 701 context->set_allowed_bytes_growth( 702 ObfuscatedFileUtil::ComputeFilePathCost(url.path()) - 1); 703 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, 704 ofu()->CreateOrOpen( 705 context.get(), url, file_flags, &file_handle, &created)); 706 707 context.reset(NewContext(NULL)); 708 context->set_allowed_bytes_growth( 709 ObfuscatedFileUtil::ComputeFilePathCost(url.path())); 710 ASSERT_EQ(base::PLATFORM_FILE_OK, 711 ofu()->CreateOrOpen( 712 context.get(), url, file_flags, &file_handle, &created)); 713 ASSERT_TRUE(created); 714 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count()); 715 EXPECT_NE(base::kInvalidPlatformFileValue, file_handle); 716 717 CheckFileAndCloseHandle(url, file_handle); 718 719 context.reset(NewContext(NULL)); 720 base::FilePath local_path; 721 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetLocalFilePath( 722 context.get(), url, &local_path)); 723 EXPECT_TRUE(file_util::PathExists(local_path)); 724 725 // Verify that deleting a file isn't stopped by zero quota, and that it frees 726 // up quote from its path. 727 context.reset(NewContext(NULL)); 728 context->set_allowed_bytes_growth(0); 729 EXPECT_EQ(base::PLATFORM_FILE_OK, 730 ofu()->DeleteFile(context.get(), url)); 731 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count()); 732 EXPECT_FALSE(file_util::PathExists(local_path)); 733 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url.path()), 734 context->allowed_bytes_growth()); 735 736 context.reset(NewContext(NULL)); 737 bool exclusive = true; 738 bool recursive = true; 739 FileSystemURL directory_url = CreateURLFromUTF8( 740 "series/of/directories"); 741 url = FileSystemURLAppendUTF8(directory_url, "file name"); 742 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 743 context.get(), directory_url, exclusive, recursive)); 744 // The oepration created 3 directories recursively. 745 EXPECT_EQ(3, change_observer()->get_and_reset_create_directory_count()); 746 747 context.reset(NewContext(NULL)); 748 file_handle = base::kInvalidPlatformFileValue; 749 ASSERT_EQ(base::PLATFORM_FILE_OK, 750 ofu()->CreateOrOpen( 751 context.get(), url, file_flags, &file_handle, &created)); 752 ASSERT_TRUE(created); 753 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count()); 754 EXPECT_NE(base::kInvalidPlatformFileValue, file_handle); 755 756 CheckFileAndCloseHandle(url, file_handle); 757 758 context.reset(NewContext(NULL)); 759 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetLocalFilePath( 760 context.get(), url, &local_path)); 761 EXPECT_TRUE(file_util::PathExists(local_path)); 762 763 context.reset(NewContext(NULL)); 764 EXPECT_EQ(base::PLATFORM_FILE_OK, 765 ofu()->DeleteFile(context.get(), url)); 766 EXPECT_EQ(1, change_observer()->get_and_reset_remove_file_count()); 767 EXPECT_FALSE(file_util::PathExists(local_path)); 768 769 // Make sure we have no unexpected changes. 770 EXPECT_TRUE(change_observer()->HasNoChange()); 771} 772 773TEST_F(ObfuscatedFileUtilTest, TestTruncate) { 774 bool created = false; 775 FileSystemURL url = CreateURLFromUTF8("file"); 776 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 777 778 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 779 ofu()->Truncate(context.get(), url, 4)); 780 781 context.reset(NewContext(NULL)); 782 ASSERT_EQ(base::PLATFORM_FILE_OK, 783 ofu()->EnsureFileExists(context.get(), url, &created)); 784 ASSERT_TRUE(created); 785 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count()); 786 787 context.reset(NewContext(NULL)); 788 base::FilePath local_path; 789 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetLocalFilePath( 790 context.get(), url, &local_path)); 791 EXPECT_EQ(0, GetSize(local_path)); 792 793 context.reset(NewContext(NULL)); 794 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->Truncate( 795 context.get(), url, 10)); 796 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); 797 EXPECT_EQ(10, GetSize(local_path)); 798 799 context.reset(NewContext(NULL)); 800 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->Truncate( 801 context.get(), url, 1)); 802 EXPECT_EQ(1, GetSize(local_path)); 803 EXPECT_EQ(1, change_observer()->get_and_reset_modify_file_count()); 804 805 EXPECT_FALSE(DirectoryExists(url)); 806 EXPECT_TRUE(PathExists(url)); 807 808 // Make sure we have no unexpected changes. 809 EXPECT_TRUE(change_observer()->HasNoChange()); 810} 811 812TEST_F(ObfuscatedFileUtilTest, TestQuotaOnTruncation) { 813 bool created = false; 814 FileSystemURL url = CreateURLFromUTF8("file"); 815 816 ASSERT_EQ(base::PLATFORM_FILE_OK, 817 ofu()->EnsureFileExists( 818 AllowUsageIncrease(PathCost(url))->context(), 819 url, &created)); 820 ASSERT_TRUE(created); 821 ASSERT_EQ(0, ComputeTotalFileSize()); 822 823 ASSERT_EQ(base::PLATFORM_FILE_OK, 824 ofu()->Truncate( 825 AllowUsageIncrease(1020)->context(), 826 url, 1020)); 827 ASSERT_EQ(1020, ComputeTotalFileSize()); 828 829 ASSERT_EQ(base::PLATFORM_FILE_OK, 830 ofu()->Truncate( 831 AllowUsageIncrease(-1020)->context(), 832 url, 0)); 833 ASSERT_EQ(0, ComputeTotalFileSize()); 834 835 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, 836 ofu()->Truncate( 837 DisallowUsageIncrease(1021)->context(), 838 url, 1021)); 839 ASSERT_EQ(0, ComputeTotalFileSize()); 840 841 EXPECT_EQ(base::PLATFORM_FILE_OK, 842 ofu()->Truncate( 843 AllowUsageIncrease(1020)->context(), 844 url, 1020)); 845 ASSERT_EQ(1020, ComputeTotalFileSize()); 846 847 EXPECT_EQ(base::PLATFORM_FILE_OK, 848 ofu()->Truncate( 849 AllowUsageIncrease(0)->context(), 850 url, 1020)); 851 ASSERT_EQ(1020, ComputeTotalFileSize()); 852 853 // quota exceeded 854 { 855 scoped_ptr<UsageVerifyHelper> helper = AllowUsageIncrease(-1); 856 helper->context()->set_allowed_bytes_growth( 857 helper->context()->allowed_bytes_growth() - 1); 858 EXPECT_EQ(base::PLATFORM_FILE_OK, 859 ofu()->Truncate(helper->context(), url, 1019)); 860 ASSERT_EQ(1019, ComputeTotalFileSize()); 861 } 862 863 // Delete backing file to make following truncation fail. 864 base::FilePath local_path; 865 ASSERT_EQ(base::PLATFORM_FILE_OK, 866 ofu()->GetLocalFilePath( 867 UnlimitedContext().get(), 868 url, &local_path)); 869 ASSERT_FALSE(local_path.empty()); 870 ASSERT_TRUE(base::Delete(local_path, false)); 871 872 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 873 ofu()->Truncate( 874 LimitedContext(1234).get(), 875 url, 1234)); 876 ASSERT_EQ(0, ComputeTotalFileSize()); 877} 878 879TEST_F(ObfuscatedFileUtilTest, TestEnsureFileExists) { 880 FileSystemURL url = CreateURLFromUTF8("fake/file"); 881 bool created = false; 882 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 883 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 884 ofu()->EnsureFileExists( 885 context.get(), url, &created)); 886 EXPECT_TRUE(change_observer()->HasNoChange()); 887 888 // Verify that file creation requires sufficient quota for the path. 889 context.reset(NewContext(NULL)); 890 url = CreateURLFromUTF8("test file"); 891 created = false; 892 context->set_allowed_bytes_growth( 893 ObfuscatedFileUtil::ComputeFilePathCost(url.path()) - 1); 894 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, 895 ofu()->EnsureFileExists(context.get(), url, &created)); 896 ASSERT_FALSE(created); 897 EXPECT_TRUE(change_observer()->HasNoChange()); 898 899 context.reset(NewContext(NULL)); 900 context->set_allowed_bytes_growth( 901 ObfuscatedFileUtil::ComputeFilePathCost(url.path())); 902 ASSERT_EQ(base::PLATFORM_FILE_OK, 903 ofu()->EnsureFileExists(context.get(), url, &created)); 904 ASSERT_TRUE(created); 905 EXPECT_EQ(1, change_observer()->get_and_reset_create_file_count()); 906 907 CheckFileAndCloseHandle(url, base::kInvalidPlatformFileValue); 908 909 context.reset(NewContext(NULL)); 910 ASSERT_EQ(base::PLATFORM_FILE_OK, 911 ofu()->EnsureFileExists(context.get(), url, &created)); 912 ASSERT_FALSE(created); 913 EXPECT_TRUE(change_observer()->HasNoChange()); 914 915 // Also test in a subdirectory. 916 url = CreateURLFromUTF8("path/to/file.txt"); 917 context.reset(NewContext(NULL)); 918 bool exclusive = true; 919 bool recursive = true; 920 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 921 context.get(), 922 FileSystemURLDirName(url), 923 exclusive, recursive)); 924 // 2 directories: path/ and path/to. 925 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count()); 926 927 context.reset(NewContext(NULL)); 928 ASSERT_EQ(base::PLATFORM_FILE_OK, 929 ofu()->EnsureFileExists(context.get(), url, &created)); 930 ASSERT_TRUE(created); 931 EXPECT_FALSE(DirectoryExists(url)); 932 EXPECT_TRUE(PathExists(url)); 933 EXPECT_TRUE(change_observer()->HasNoChange()); 934} 935 936TEST_F(ObfuscatedFileUtilTest, TestDirectoryOps) { 937 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 938 939 bool exclusive = false; 940 bool recursive = false; 941 FileSystemURL url = CreateURLFromUTF8("foo/bar"); 942 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, ofu()->CreateDirectory( 943 context.get(), url, exclusive, recursive)); 944 945 context.reset(NewContext(NULL)); 946 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 947 ofu()->DeleteDirectory(context.get(), url)); 948 949 FileSystemURL root = CreateURLFromUTF8(std::string()); 950 EXPECT_FALSE(DirectoryExists(url)); 951 EXPECT_FALSE(PathExists(url)); 952 context.reset(NewContext(NULL)); 953 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context.get(), root)); 954 955 context.reset(NewContext(NULL)); 956 exclusive = false; 957 recursive = true; 958 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 959 context.get(), url, exclusive, recursive)); 960 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count()); 961 962 EXPECT_TRUE(DirectoryExists(url)); 963 EXPECT_TRUE(PathExists(url)); 964 965 context.reset(NewContext(NULL)); 966 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context.get(), root)); 967 EXPECT_TRUE(DirectoryExists(FileSystemURLDirName(url))); 968 969 context.reset(NewContext(NULL)); 970 EXPECT_FALSE(ofu()->IsDirectoryEmpty(context.get(), 971 FileSystemURLDirName(url))); 972 973 // Can't remove a non-empty directory. 974 context.reset(NewContext(NULL)); 975 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, 976 ofu()->DeleteDirectory(context.get(), 977 FileSystemURLDirName(url))); 978 EXPECT_TRUE(change_observer()->HasNoChange()); 979 980 base::PlatformFileInfo file_info; 981 base::FilePath local_path; 982 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo( 983 context.get(), url, &file_info, &local_path)); 984 EXPECT_TRUE(local_path.empty()); 985 EXPECT_TRUE(file_info.is_directory); 986 EXPECT_FALSE(file_info.is_symbolic_link); 987 988 // Same create again should succeed, since exclusive is false. 989 context.reset(NewContext(NULL)); 990 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 991 context.get(), url, exclusive, recursive)); 992 EXPECT_TRUE(change_observer()->HasNoChange()); 993 994 exclusive = true; 995 recursive = true; 996 context.reset(NewContext(NULL)); 997 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofu()->CreateDirectory( 998 context.get(), url, exclusive, recursive)); 999 EXPECT_TRUE(change_observer()->HasNoChange()); 1000 1001 // Verify that deleting a directory isn't stopped by zero quota, and that it 1002 // frees up quota from its path. 1003 context.reset(NewContext(NULL)); 1004 context->set_allowed_bytes_growth(0); 1005 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->DeleteDirectory(context.get(), url)); 1006 EXPECT_EQ(1, change_observer()->get_and_reset_remove_directory_count()); 1007 EXPECT_EQ(ObfuscatedFileUtil::ComputeFilePathCost(url.path()), 1008 context->allowed_bytes_growth()); 1009 1010 url = CreateURLFromUTF8("foo/bop"); 1011 1012 EXPECT_FALSE(DirectoryExists(url)); 1013 EXPECT_FALSE(PathExists(url)); 1014 1015 context.reset(NewContext(NULL)); 1016 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context.get(), url)); 1017 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, ofu()->GetFileInfo( 1018 context.get(), url, &file_info, &local_path)); 1019 1020 // Verify that file creation requires sufficient quota for the path. 1021 exclusive = true; 1022 recursive = false; 1023 context.reset(NewContext(NULL)); 1024 context->set_allowed_bytes_growth( 1025 ObfuscatedFileUtil::ComputeFilePathCost(url.path()) - 1); 1026 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, ofu()->CreateDirectory( 1027 context.get(), url, exclusive, recursive)); 1028 EXPECT_TRUE(change_observer()->HasNoChange()); 1029 1030 context.reset(NewContext(NULL)); 1031 context->set_allowed_bytes_growth( 1032 ObfuscatedFileUtil::ComputeFilePathCost(url.path())); 1033 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 1034 context.get(), url, exclusive, recursive)); 1035 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); 1036 1037 EXPECT_TRUE(DirectoryExists(url)); 1038 EXPECT_TRUE(PathExists(url)); 1039 1040 exclusive = true; 1041 recursive = false; 1042 context.reset(NewContext(NULL)); 1043 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofu()->CreateDirectory( 1044 context.get(), url, exclusive, recursive)); 1045 EXPECT_TRUE(change_observer()->HasNoChange()); 1046 1047 exclusive = true; 1048 recursive = false; 1049 url = CreateURLFromUTF8("foo"); 1050 context.reset(NewContext(NULL)); 1051 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofu()->CreateDirectory( 1052 context.get(), url, exclusive, recursive)); 1053 EXPECT_TRUE(change_observer()->HasNoChange()); 1054 1055 url = CreateURLFromUTF8("blah"); 1056 1057 EXPECT_FALSE(DirectoryExists(url)); 1058 EXPECT_FALSE(PathExists(url)); 1059 1060 exclusive = true; 1061 recursive = false; 1062 context.reset(NewContext(NULL)); 1063 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 1064 context.get(), url, exclusive, recursive)); 1065 EXPECT_EQ(1, change_observer()->get_and_reset_create_directory_count()); 1066 1067 EXPECT_TRUE(DirectoryExists(url)); 1068 EXPECT_TRUE(PathExists(url)); 1069 1070 exclusive = true; 1071 recursive = false; 1072 context.reset(NewContext(NULL)); 1073 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, ofu()->CreateDirectory( 1074 context.get(), url, exclusive, recursive)); 1075 EXPECT_TRUE(change_observer()->HasNoChange()); 1076} 1077 1078TEST_F(ObfuscatedFileUtilTest, TestReadDirectory) { 1079 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1080 bool exclusive = true; 1081 bool recursive = true; 1082 FileSystemURL url = CreateURLFromUTF8("directory/to/use"); 1083 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 1084 context.get(), url, exclusive, recursive)); 1085 TestReadDirectoryHelper(url); 1086} 1087 1088TEST_F(ObfuscatedFileUtilTest, TestReadRootWithSlash) { 1089 TestReadDirectoryHelper(CreateURLFromUTF8(std::string())); 1090} 1091 1092TEST_F(ObfuscatedFileUtilTest, TestReadRootWithEmptyString) { 1093 TestReadDirectoryHelper(CreateURLFromUTF8("/")); 1094} 1095 1096TEST_F(ObfuscatedFileUtilTest, TestReadDirectoryOnFile) { 1097 FileSystemURL url = CreateURLFromUTF8("file"); 1098 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1099 1100 bool created = false; 1101 ASSERT_EQ(base::PLATFORM_FILE_OK, 1102 ofu()->EnsureFileExists(context.get(), url, &created)); 1103 ASSERT_TRUE(created); 1104 1105 std::vector<DirectoryEntry> entries; 1106 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY, 1107 AsyncFileTestHelper::ReadDirectory( 1108 file_system_context(), url, &entries)); 1109 1110 EXPECT_TRUE(ofu()->IsDirectoryEmpty(context.get(), url)); 1111} 1112 1113TEST_F(ObfuscatedFileUtilTest, TestTouch) { 1114 FileSystemURL url = CreateURLFromUTF8("file"); 1115 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1116 1117 base::Time last_access_time = base::Time::Now(); 1118 base::Time last_modified_time = base::Time::Now(); 1119 1120 // It's not there yet. 1121 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 1122 ofu()->Touch( 1123 context.get(), url, last_access_time, last_modified_time)); 1124 1125 // OK, now create it. 1126 context.reset(NewContext(NULL)); 1127 bool created = false; 1128 ASSERT_EQ(base::PLATFORM_FILE_OK, 1129 ofu()->EnsureFileExists(context.get(), url, &created)); 1130 ASSERT_TRUE(created); 1131 TestTouchHelper(url, true); 1132 1133 // Now test a directory: 1134 context.reset(NewContext(NULL)); 1135 bool exclusive = true; 1136 bool recursive = false; 1137 url = CreateURLFromUTF8("dir"); 1138 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory(context.get(), 1139 url, exclusive, recursive)); 1140 TestTouchHelper(url, false); 1141} 1142 1143TEST_F(ObfuscatedFileUtilTest, TestPathQuotas) { 1144 FileSystemURL url = CreateURLFromUTF8("fake/file"); 1145 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1146 1147 url = CreateURLFromUTF8("file name"); 1148 context->set_allowed_bytes_growth(5); 1149 bool created = false; 1150 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, 1151 ofu()->EnsureFileExists(context.get(), url, &created)); 1152 EXPECT_FALSE(created); 1153 context->set_allowed_bytes_growth(1024); 1154 EXPECT_EQ(base::PLATFORM_FILE_OK, 1155 ofu()->EnsureFileExists(context.get(), url, &created)); 1156 EXPECT_TRUE(created); 1157 int64 path_cost = ObfuscatedFileUtil::ComputeFilePathCost(url.path()); 1158 EXPECT_EQ(1024 - path_cost, context->allowed_bytes_growth()); 1159 1160 context->set_allowed_bytes_growth(1024); 1161 bool exclusive = true; 1162 bool recursive = true; 1163 url = CreateURLFromUTF8("directory/to/use"); 1164 std::vector<base::FilePath::StringType> components; 1165 url.path().GetComponents(&components); 1166 path_cost = 0; 1167 typedef std::vector<base::FilePath::StringType>::iterator iterator; 1168 for (iterator iter = components.begin(); 1169 iter != components.end(); ++iter) { 1170 path_cost += ObfuscatedFileUtil::ComputeFilePathCost( 1171 base::FilePath(*iter)); 1172 } 1173 context.reset(NewContext(NULL)); 1174 context->set_allowed_bytes_growth(1024); 1175 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 1176 context.get(), url, exclusive, recursive)); 1177 EXPECT_EQ(1024 - path_cost, context->allowed_bytes_growth()); 1178} 1179 1180TEST_F(ObfuscatedFileUtilTest, TestCopyOrMoveFileNotFound) { 1181 FileSystemURL source_url = CreateURLFromUTF8("path0.txt"); 1182 FileSystemURL dest_url = CreateURLFromUTF8("path1.txt"); 1183 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1184 1185 bool is_copy_not_move = false; 1186 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 1187 ofu()->CopyOrMoveFile(context.get(), source_url, dest_url, 1188 is_copy_not_move)); 1189 EXPECT_TRUE(change_observer()->HasNoChange()); 1190 context.reset(NewContext(NULL)); 1191 is_copy_not_move = true; 1192 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 1193 ofu()->CopyOrMoveFile(context.get(), source_url, dest_url, 1194 is_copy_not_move)); 1195 EXPECT_TRUE(change_observer()->HasNoChange()); 1196 source_url = CreateURLFromUTF8("dir/dir/file"); 1197 bool exclusive = true; 1198 bool recursive = true; 1199 context.reset(NewContext(NULL)); 1200 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 1201 context.get(), 1202 FileSystemURLDirName(source_url), 1203 exclusive, recursive)); 1204 EXPECT_EQ(2, change_observer()->get_and_reset_create_directory_count()); 1205 is_copy_not_move = false; 1206 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 1207 ofu()->CopyOrMoveFile(context.get(), source_url, dest_url, 1208 is_copy_not_move)); 1209 EXPECT_TRUE(change_observer()->HasNoChange()); 1210 context.reset(NewContext(NULL)); 1211 is_copy_not_move = true; 1212 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 1213 ofu()->CopyOrMoveFile(context.get(), source_url, dest_url, 1214 is_copy_not_move)); 1215 EXPECT_TRUE(change_observer()->HasNoChange()); 1216} 1217 1218TEST_F(ObfuscatedFileUtilTest, TestCopyOrMoveFileSuccess) { 1219 const int64 kSourceLength = 5; 1220 const int64 kDestLength = 50; 1221 1222 for (size_t i = 0; i < arraysize(kCopyMoveTestCases); ++i) { 1223 SCOPED_TRACE(testing::Message() << "kCopyMoveTestCase " << i); 1224 const CopyMoveTestCaseRecord& test_case = kCopyMoveTestCases[i]; 1225 SCOPED_TRACE(testing::Message() << "\t is_copy_not_move " << 1226 test_case.is_copy_not_move); 1227 SCOPED_TRACE(testing::Message() << "\t source_path " << 1228 test_case.source_path); 1229 SCOPED_TRACE(testing::Message() << "\t dest_path " << 1230 test_case.dest_path); 1231 SCOPED_TRACE(testing::Message() << "\t cause_overwrite " << 1232 test_case.cause_overwrite); 1233 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1234 1235 bool exclusive = false; 1236 bool recursive = true; 1237 FileSystemURL source_url = CreateURLFromUTF8(test_case.source_path); 1238 FileSystemURL dest_url = CreateURLFromUTF8(test_case.dest_path); 1239 1240 context.reset(NewContext(NULL)); 1241 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 1242 context.get(), 1243 FileSystemURLDirName(source_url), 1244 exclusive, recursive)); 1245 context.reset(NewContext(NULL)); 1246 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 1247 context.get(), 1248 FileSystemURLDirName(dest_url), 1249 exclusive, recursive)); 1250 1251 bool created = false; 1252 context.reset(NewContext(NULL)); 1253 ASSERT_EQ(base::PLATFORM_FILE_OK, 1254 ofu()->EnsureFileExists(context.get(), source_url, &created)); 1255 ASSERT_TRUE(created); 1256 context.reset(NewContext(NULL)); 1257 ASSERT_EQ(base::PLATFORM_FILE_OK, 1258 ofu()->Truncate(context.get(), source_url, kSourceLength)); 1259 1260 if (test_case.cause_overwrite) { 1261 context.reset(NewContext(NULL)); 1262 created = false; 1263 ASSERT_EQ(base::PLATFORM_FILE_OK, 1264 ofu()->EnsureFileExists(context.get(), dest_url, &created)); 1265 ASSERT_TRUE(created); 1266 context.reset(NewContext(NULL)); 1267 ASSERT_EQ(base::PLATFORM_FILE_OK, 1268 ofu()->Truncate(context.get(), dest_url, kDestLength)); 1269 } 1270 1271 context.reset(NewContext(NULL)); 1272 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->CopyOrMoveFile(context.get(), 1273 source_url, dest_url, test_case.is_copy_not_move)); 1274 1275 if (test_case.is_copy_not_move) { 1276 base::PlatformFileInfo file_info; 1277 base::FilePath local_path; 1278 context.reset(NewContext(NULL)); 1279 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo( 1280 context.get(), source_url, &file_info, &local_path)); 1281 EXPECT_EQ(kSourceLength, file_info.size); 1282 EXPECT_EQ(base::PLATFORM_FILE_OK, 1283 ofu()->DeleteFile(context.get(), source_url)); 1284 } else { 1285 base::PlatformFileInfo file_info; 1286 base::FilePath local_path; 1287 context.reset(NewContext(NULL)); 1288 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, ofu()->GetFileInfo( 1289 context.get(), source_url, &file_info, &local_path)); 1290 } 1291 base::PlatformFileInfo file_info; 1292 base::FilePath local_path; 1293 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->GetFileInfo( 1294 context.get(), dest_url, &file_info, &local_path)); 1295 EXPECT_EQ(kSourceLength, file_info.size); 1296 1297 EXPECT_EQ(base::PLATFORM_FILE_OK, 1298 ofu()->DeleteFile(context.get(), dest_url)); 1299 } 1300} 1301 1302TEST_F(ObfuscatedFileUtilTest, TestCopyPathQuotas) { 1303 FileSystemURL src_url = CreateURLFromUTF8("src path"); 1304 FileSystemURL dest_url = CreateURLFromUTF8("destination path"); 1305 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1306 bool created = false; 1307 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->EnsureFileExists( 1308 context.get(), src_url, &created)); 1309 1310 bool is_copy = true; 1311 // Copy, no overwrite. 1312 context->set_allowed_bytes_growth( 1313 ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()) - 1); 1314 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, 1315 ofu()->CopyOrMoveFile(context.get(), src_url, dest_url, is_copy)); 1316 context.reset(NewContext(NULL)); 1317 context->set_allowed_bytes_growth( 1318 ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path())); 1319 EXPECT_EQ(base::PLATFORM_FILE_OK, 1320 ofu()->CopyOrMoveFile(context.get(), src_url, dest_url, is_copy)); 1321 1322 // Copy, with overwrite. 1323 context.reset(NewContext(NULL)); 1324 context->set_allowed_bytes_growth(0); 1325 EXPECT_EQ(base::PLATFORM_FILE_OK, 1326 ofu()->CopyOrMoveFile(context.get(), src_url, dest_url, is_copy)); 1327} 1328 1329TEST_F(ObfuscatedFileUtilTest, TestMovePathQuotasWithRename) { 1330 FileSystemURL src_url = CreateURLFromUTF8("src path"); 1331 FileSystemURL dest_url = CreateURLFromUTF8("destination path"); 1332 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1333 bool created = false; 1334 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->EnsureFileExists( 1335 context.get(), src_url, &created)); 1336 1337 bool is_copy = false; 1338 // Move, rename, no overwrite. 1339 context.reset(NewContext(NULL)); 1340 context->set_allowed_bytes_growth( 1341 ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()) - 1342 ObfuscatedFileUtil::ComputeFilePathCost(src_url.path()) - 1); 1343 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, 1344 ofu()->CopyOrMoveFile(context.get(), src_url, dest_url, is_copy)); 1345 context.reset(NewContext(NULL)); 1346 context->set_allowed_bytes_growth( 1347 ObfuscatedFileUtil::ComputeFilePathCost(dest_url.path()) - 1348 ObfuscatedFileUtil::ComputeFilePathCost(src_url.path())); 1349 EXPECT_EQ(base::PLATFORM_FILE_OK, 1350 ofu()->CopyOrMoveFile(context.get(), src_url, dest_url, is_copy)); 1351 1352 context.reset(NewContext(NULL)); 1353 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->EnsureFileExists( 1354 context.get(), src_url, &created)); 1355 1356 // Move, rename, with overwrite. 1357 context.reset(NewContext(NULL)); 1358 context->set_allowed_bytes_growth(0); 1359 EXPECT_EQ(base::PLATFORM_FILE_OK, 1360 ofu()->CopyOrMoveFile(context.get(), src_url, dest_url, is_copy)); 1361} 1362 1363TEST_F(ObfuscatedFileUtilTest, TestMovePathQuotasWithoutRename) { 1364 FileSystemURL src_url = CreateURLFromUTF8("src path"); 1365 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1366 bool created = false; 1367 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->EnsureFileExists( 1368 context.get(), src_url, &created)); 1369 1370 bool exclusive = true; 1371 bool recursive = false; 1372 FileSystemURL dir_url = CreateURLFromUTF8("directory path"); 1373 context.reset(NewContext(NULL)); 1374 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 1375 context.get(), dir_url, exclusive, recursive)); 1376 1377 FileSystemURL dest_url = FileSystemURLAppend( 1378 dir_url, src_url.path().value()); 1379 1380 bool is_copy = false; 1381 int64 allowed_bytes_growth = -1000; // Over quota, this should still work. 1382 // Move, no rename, no overwrite. 1383 context.reset(NewContext(NULL)); 1384 context->set_allowed_bytes_growth(allowed_bytes_growth); 1385 EXPECT_EQ(base::PLATFORM_FILE_OK, 1386 ofu()->CopyOrMoveFile(context.get(), src_url, dest_url, is_copy)); 1387 EXPECT_EQ(allowed_bytes_growth, context->allowed_bytes_growth()); 1388 1389 // Move, no rename, with overwrite. 1390 context.reset(NewContext(NULL)); 1391 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->EnsureFileExists( 1392 context.get(), src_url, &created)); 1393 context.reset(NewContext(NULL)); 1394 context->set_allowed_bytes_growth(allowed_bytes_growth); 1395 EXPECT_EQ(base::PLATFORM_FILE_OK, 1396 ofu()->CopyOrMoveFile(context.get(), src_url, dest_url, is_copy)); 1397 EXPECT_EQ( 1398 allowed_bytes_growth + 1399 ObfuscatedFileUtil::ComputeFilePathCost(src_url.path()), 1400 context->allowed_bytes_growth()); 1401} 1402 1403TEST_F(ObfuscatedFileUtilTest, TestCopyInForeignFile) { 1404 TestCopyInForeignFileHelper(false /* overwrite */); 1405 TestCopyInForeignFileHelper(true /* overwrite */); 1406} 1407 1408TEST_F(ObfuscatedFileUtilTest, TestEnumerator) { 1409 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1410 FileSystemURL src_url = CreateURLFromUTF8("source dir"); 1411 bool exclusive = true; 1412 bool recursive = false; 1413 ASSERT_EQ(base::PLATFORM_FILE_OK, ofu()->CreateDirectory( 1414 context.get(), src_url, exclusive, recursive)); 1415 1416 std::set<base::FilePath::StringType> files; 1417 std::set<base::FilePath::StringType> directories; 1418 FillTestDirectory(src_url, &files, &directories); 1419 1420 FileSystemURL dest_url = CreateURLFromUTF8("destination dir"); 1421 1422 EXPECT_FALSE(DirectoryExists(dest_url)); 1423 ASSERT_EQ(base::PLATFORM_FILE_OK, 1424 AsyncFileTestHelper::Copy( 1425 file_system_context(), src_url, dest_url)); 1426 1427 ValidateTestDirectory(dest_url, files, directories); 1428 EXPECT_TRUE(DirectoryExists(src_url)); 1429 EXPECT_TRUE(DirectoryExists(dest_url)); 1430 recursive = true; 1431 ASSERT_EQ(base::PLATFORM_FILE_OK, 1432 AsyncFileTestHelper::Remove( 1433 file_system_context(), dest_url, recursive)); 1434 EXPECT_FALSE(DirectoryExists(dest_url)); 1435} 1436 1437TEST_F(ObfuscatedFileUtilTest, TestOriginEnumerator) { 1438 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> 1439 enumerator(ofu()->CreateOriginEnumerator()); 1440 // The test helper starts out with a single filesystem. 1441 EXPECT_TRUE(enumerator.get()); 1442 EXPECT_EQ(origin(), enumerator->Next()); 1443 ASSERT_TRUE(type() == kFileSystemTypeTemporary); 1444 EXPECT_TRUE(enumerator->HasFileSystemType(kFileSystemTypeTemporary)); 1445 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypePersistent)); 1446 EXPECT_EQ(GURL(), enumerator->Next()); 1447 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypeTemporary)); 1448 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypePersistent)); 1449 1450 std::set<GURL> origins_expected; 1451 origins_expected.insert(origin()); 1452 1453 for (size_t i = 0; i < arraysize(kOriginEnumerationTestRecords); ++i) { 1454 SCOPED_TRACE(testing::Message() << 1455 "Validating kOriginEnumerationTestRecords " << i); 1456 const OriginEnumerationTestRecord& record = 1457 kOriginEnumerationTestRecords[i]; 1458 GURL origin_url(record.origin_url); 1459 origins_expected.insert(origin_url); 1460 if (record.has_temporary) { 1461 scoped_ptr<SandboxFileSystemTestHelper> file_system( 1462 NewFileSystem(origin_url, kFileSystemTypeTemporary)); 1463 scoped_ptr<FileSystemOperationContext> context( 1464 NewContext(file_system.get())); 1465 bool created = false; 1466 ASSERT_EQ(base::PLATFORM_FILE_OK, 1467 ofu()->EnsureFileExists( 1468 context.get(), 1469 file_system->CreateURLFromUTF8("file"), 1470 &created)); 1471 EXPECT_TRUE(created); 1472 } 1473 if (record.has_persistent) { 1474 scoped_ptr<SandboxFileSystemTestHelper> file_system( 1475 NewFileSystem(origin_url, kFileSystemTypePersistent)); 1476 scoped_ptr<FileSystemOperationContext> context( 1477 NewContext(file_system.get())); 1478 bool created = false; 1479 ASSERT_EQ(base::PLATFORM_FILE_OK, 1480 ofu()->EnsureFileExists( 1481 context.get(), 1482 file_system->CreateURLFromUTF8("file"), 1483 &created)); 1484 EXPECT_TRUE(created); 1485 } 1486 } 1487 enumerator.reset(ofu()->CreateOriginEnumerator()); 1488 EXPECT_TRUE(enumerator.get()); 1489 std::set<GURL> origins_found; 1490 GURL origin_url; 1491 while (!(origin_url = enumerator->Next()).is_empty()) { 1492 origins_found.insert(origin_url); 1493 SCOPED_TRACE(testing::Message() << "Handling " << origin_url.spec()); 1494 bool found = false; 1495 for (size_t i = 0; !found && i < arraysize(kOriginEnumerationTestRecords); 1496 ++i) { 1497 const OriginEnumerationTestRecord& record = 1498 kOriginEnumerationTestRecords[i]; 1499 if (GURL(record.origin_url) != origin_url) 1500 continue; 1501 found = true; 1502 EXPECT_EQ(record.has_temporary, 1503 enumerator->HasFileSystemType(kFileSystemTypeTemporary)); 1504 EXPECT_EQ(record.has_persistent, 1505 enumerator->HasFileSystemType(kFileSystemTypePersistent)); 1506 } 1507 // Deal with the default filesystem created by the test helper. 1508 if (!found && origin_url == origin()) { 1509 ASSERT_TRUE(type() == kFileSystemTypeTemporary); 1510 EXPECT_EQ(true, 1511 enumerator->HasFileSystemType(kFileSystemTypeTemporary)); 1512 EXPECT_FALSE(enumerator->HasFileSystemType(kFileSystemTypePersistent)); 1513 found = true; 1514 } 1515 EXPECT_TRUE(found); 1516 } 1517 1518 std::set<GURL> diff; 1519 std::set_symmetric_difference(origins_expected.begin(), 1520 origins_expected.end(), origins_found.begin(), origins_found.end(), 1521 inserter(diff, diff.begin())); 1522 EXPECT_TRUE(diff.empty()); 1523} 1524 1525TEST_F(ObfuscatedFileUtilTest, TestRevokeUsageCache) { 1526 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1527 1528 int64 expected_quota = 0; 1529 1530 for (size_t i = 0; i < test::kRegularTestCaseSize; ++i) { 1531 SCOPED_TRACE(testing::Message() << "Creating kRegularTestCase " << i); 1532 const test::TestCaseRecord& test_case = test::kRegularTestCases[i]; 1533 base::FilePath file_path(test_case.path); 1534 expected_quota += ObfuscatedFileUtil::ComputeFilePathCost(file_path); 1535 if (test_case.is_directory) { 1536 bool exclusive = true; 1537 bool recursive = false; 1538 ASSERT_EQ(base::PLATFORM_FILE_OK, 1539 ofu()->CreateDirectory(context.get(), CreateURL(file_path), 1540 exclusive, recursive)); 1541 } else { 1542 bool created = false; 1543 ASSERT_EQ(base::PLATFORM_FILE_OK, 1544 ofu()->EnsureFileExists(context.get(), CreateURL(file_path), 1545 &created)); 1546 ASSERT_TRUE(created); 1547 ASSERT_EQ(base::PLATFORM_FILE_OK, 1548 ofu()->Truncate(context.get(), 1549 CreateURL(file_path), 1550 test_case.data_file_size)); 1551 expected_quota += test_case.data_file_size; 1552 } 1553 } 1554 1555 // Usually raw size in usage cache and the usage returned by QuotaUtil 1556 // should be same. 1557 EXPECT_EQ(expected_quota, SizeInUsageFile()); 1558 EXPECT_EQ(expected_quota, SizeByQuotaUtil()); 1559 1560 RevokeUsageCache(); 1561 EXPECT_EQ(-1, SizeInUsageFile()); 1562 EXPECT_EQ(expected_quota, SizeByQuotaUtil()); 1563 1564 // This should reconstruct the cache. 1565 GetUsageFromQuotaManager(); 1566 EXPECT_EQ(expected_quota, SizeInUsageFile()); 1567 EXPECT_EQ(expected_quota, SizeByQuotaUtil()); 1568 EXPECT_EQ(expected_quota, usage()); 1569} 1570 1571TEST_F(ObfuscatedFileUtilTest, TestInconsistency) { 1572 const FileSystemURL kPath1 = CreateURLFromUTF8("hoge"); 1573 const FileSystemURL kPath2 = CreateURLFromUTF8("fuga"); 1574 1575 scoped_ptr<FileSystemOperationContext> context; 1576 base::PlatformFile file; 1577 base::PlatformFileInfo file_info; 1578 base::FilePath data_path; 1579 bool created = false; 1580 1581 // Create a non-empty file. 1582 context.reset(NewContext(NULL)); 1583 EXPECT_EQ(base::PLATFORM_FILE_OK, 1584 ofu()->EnsureFileExists(context.get(), kPath1, &created)); 1585 EXPECT_TRUE(created); 1586 context.reset(NewContext(NULL)); 1587 EXPECT_EQ(base::PLATFORM_FILE_OK, 1588 ofu()->Truncate(context.get(), kPath1, 10)); 1589 context.reset(NewContext(NULL)); 1590 EXPECT_EQ(base::PLATFORM_FILE_OK, 1591 ofu()->GetFileInfo( 1592 context.get(), kPath1, &file_info, &data_path)); 1593 EXPECT_EQ(10, file_info.size); 1594 1595 // Destroy database to make inconsistency between database and filesystem. 1596 ofu()->DestroyDirectoryDatabase(origin(), type()); 1597 1598 // Try to get file info of broken file. 1599 EXPECT_FALSE(PathExists(kPath1)); 1600 context.reset(NewContext(NULL)); 1601 EXPECT_EQ(base::PLATFORM_FILE_OK, 1602 ofu()->EnsureFileExists(context.get(), kPath1, &created)); 1603 EXPECT_TRUE(created); 1604 context.reset(NewContext(NULL)); 1605 EXPECT_EQ(base::PLATFORM_FILE_OK, 1606 ofu()->GetFileInfo( 1607 context.get(), kPath1, &file_info, &data_path)); 1608 EXPECT_EQ(0, file_info.size); 1609 1610 // Make another broken file to |kPath2|. 1611 context.reset(NewContext(NULL)); 1612 EXPECT_EQ(base::PLATFORM_FILE_OK, 1613 ofu()->EnsureFileExists(context.get(), kPath2, &created)); 1614 EXPECT_TRUE(created); 1615 1616 // Destroy again. 1617 ofu()->DestroyDirectoryDatabase(origin(), type()); 1618 1619 // Repair broken |kPath1|. 1620 context.reset(NewContext(NULL)); 1621 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 1622 ofu()->Touch(context.get(), kPath1, base::Time::Now(), 1623 base::Time::Now())); 1624 EXPECT_EQ(base::PLATFORM_FILE_OK, 1625 ofu()->EnsureFileExists(context.get(), kPath1, &created)); 1626 EXPECT_TRUE(created); 1627 1628 // Copy from sound |kPath1| to broken |kPath2|. 1629 context.reset(NewContext(NULL)); 1630 EXPECT_EQ(base::PLATFORM_FILE_OK, 1631 ofu()->CopyOrMoveFile(context.get(), kPath1, kPath2, 1632 true /* copy */)); 1633 1634 ofu()->DestroyDirectoryDatabase(origin(), type()); 1635 context.reset(NewContext(NULL)); 1636 EXPECT_EQ(base::PLATFORM_FILE_OK, 1637 ofu()->CreateOrOpen( 1638 context.get(), kPath1, 1639 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_CREATE, 1640 &file, &created)); 1641 EXPECT_TRUE(created); 1642 EXPECT_TRUE(base::GetPlatformFileInfo(file, &file_info)); 1643 EXPECT_EQ(0, file_info.size); 1644 EXPECT_TRUE(base::ClosePlatformFile(file)); 1645} 1646 1647TEST_F(ObfuscatedFileUtilTest, TestIncompleteDirectoryReading) { 1648 const FileSystemURL kPath[] = { 1649 CreateURLFromUTF8("foo"), 1650 CreateURLFromUTF8("bar"), 1651 CreateURLFromUTF8("baz") 1652 }; 1653 const FileSystemURL empty_path = CreateURL(base::FilePath()); 1654 scoped_ptr<FileSystemOperationContext> context; 1655 1656 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kPath); ++i) { 1657 bool created = false; 1658 context.reset(NewContext(NULL)); 1659 EXPECT_EQ(base::PLATFORM_FILE_OK, 1660 ofu()->EnsureFileExists(context.get(), kPath[i], &created)); 1661 EXPECT_TRUE(created); 1662 } 1663 1664 std::vector<DirectoryEntry> entries; 1665 EXPECT_EQ(base::PLATFORM_FILE_OK, 1666 AsyncFileTestHelper::ReadDirectory( 1667 file_system_context(), empty_path, &entries)); 1668 EXPECT_EQ(3u, entries.size()); 1669 1670 base::FilePath local_path; 1671 EXPECT_EQ(base::PLATFORM_FILE_OK, 1672 ofu()->GetLocalFilePath(context.get(), kPath[0], &local_path)); 1673 EXPECT_TRUE(base::Delete(local_path, false)); 1674 1675 entries.clear(); 1676 EXPECT_EQ(base::PLATFORM_FILE_OK, 1677 AsyncFileTestHelper::ReadDirectory( 1678 file_system_context(), empty_path, &entries)); 1679 EXPECT_EQ(ARRAYSIZE_UNSAFE(kPath) - 1, entries.size()); 1680} 1681 1682TEST_F(ObfuscatedFileUtilTest, TestDirectoryTimestampForCreation) { 1683 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1684 const FileSystemURL dir_url = CreateURLFromUTF8("foo_dir"); 1685 1686 // Create working directory. 1687 EXPECT_EQ(base::PLATFORM_FILE_OK, 1688 ofu()->CreateDirectory(context.get(), dir_url, false, false)); 1689 1690 // EnsureFileExists, create case. 1691 FileSystemURL url(FileSystemURLAppendUTF8( 1692 dir_url, "EnsureFileExists_file")); 1693 bool created = false; 1694 ClearTimestamp(dir_url); 1695 context.reset(NewContext(NULL)); 1696 EXPECT_EQ(base::PLATFORM_FILE_OK, 1697 ofu()->EnsureFileExists(context.get(), url, &created)); 1698 EXPECT_TRUE(created); 1699 EXPECT_NE(base::Time(), GetModifiedTime(dir_url)); 1700 1701 // non create case. 1702 created = true; 1703 ClearTimestamp(dir_url); 1704 context.reset(NewContext(NULL)); 1705 EXPECT_EQ(base::PLATFORM_FILE_OK, 1706 ofu()->EnsureFileExists(context.get(), url, &created)); 1707 EXPECT_FALSE(created); 1708 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url)); 1709 1710 // fail case. 1711 url = FileSystemURLAppendUTF8(dir_url, "EnsureFileExists_dir"); 1712 context.reset(NewContext(NULL)); 1713 EXPECT_EQ(base::PLATFORM_FILE_OK, 1714 ofu()->CreateDirectory(context.get(), url, false, false)); 1715 1716 ClearTimestamp(dir_url); 1717 context.reset(NewContext(NULL)); 1718 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_FILE, 1719 ofu()->EnsureFileExists(context.get(), url, &created)); 1720 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url)); 1721 1722 // CreateOrOpen, create case. 1723 url = FileSystemURLAppendUTF8(dir_url, "CreateOrOpen_file"); 1724 base::PlatformFile file_handle = base::kInvalidPlatformFileValue; 1725 created = false; 1726 ClearTimestamp(dir_url); 1727 context.reset(NewContext(NULL)); 1728 EXPECT_EQ(base::PLATFORM_FILE_OK, 1729 ofu()->CreateOrOpen( 1730 context.get(), url, 1731 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE, 1732 &file_handle, &created)); 1733 EXPECT_NE(base::kInvalidPlatformFileValue, file_handle); 1734 EXPECT_TRUE(created); 1735 EXPECT_TRUE(base::ClosePlatformFile(file_handle)); 1736 EXPECT_NE(base::Time(), GetModifiedTime(dir_url)); 1737 1738 // open case. 1739 file_handle = base::kInvalidPlatformFileValue; 1740 created = true; 1741 ClearTimestamp(dir_url); 1742 context.reset(NewContext(NULL)); 1743 EXPECT_EQ(base::PLATFORM_FILE_OK, 1744 ofu()->CreateOrOpen( 1745 context.get(), url, 1746 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE, 1747 &file_handle, &created)); 1748 EXPECT_NE(base::kInvalidPlatformFileValue, file_handle); 1749 EXPECT_FALSE(created); 1750 EXPECT_TRUE(base::ClosePlatformFile(file_handle)); 1751 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url)); 1752 1753 // fail case 1754 file_handle = base::kInvalidPlatformFileValue; 1755 ClearTimestamp(dir_url); 1756 context.reset(NewContext(NULL)); 1757 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, 1758 ofu()->CreateOrOpen( 1759 context.get(), url, 1760 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE, 1761 &file_handle, &created)); 1762 EXPECT_EQ(base::kInvalidPlatformFileValue, file_handle); 1763 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url)); 1764 1765 // CreateDirectory, create case. 1766 // Creating CreateDirectory_dir and CreateDirectory_dir/subdir. 1767 url = FileSystemURLAppendUTF8(dir_url, "CreateDirectory_dir"); 1768 FileSystemURL subdir_url(FileSystemURLAppendUTF8(url, "subdir")); 1769 ClearTimestamp(dir_url); 1770 context.reset(NewContext(NULL)); 1771 EXPECT_EQ(base::PLATFORM_FILE_OK, 1772 ofu()->CreateDirectory(context.get(), subdir_url, 1773 true /* exclusive */, true /* recursive */)); 1774 EXPECT_NE(base::Time(), GetModifiedTime(dir_url)); 1775 1776 // create subdir case. 1777 // Creating CreateDirectory_dir/subdir2. 1778 subdir_url = FileSystemURLAppendUTF8(url, "subdir2"); 1779 ClearTimestamp(dir_url); 1780 ClearTimestamp(url); 1781 context.reset(NewContext(NULL)); 1782 EXPECT_EQ(base::PLATFORM_FILE_OK, 1783 ofu()->CreateDirectory(context.get(), subdir_url, 1784 true /* exclusive */, true /* recursive */)); 1785 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url)); 1786 EXPECT_NE(base::Time(), GetModifiedTime(url)); 1787 1788 // fail case. 1789 url = FileSystemURLAppendUTF8(dir_url, "CreateDirectory_dir"); 1790 ClearTimestamp(dir_url); 1791 context.reset(NewContext(NULL)); 1792 EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, 1793 ofu()->CreateDirectory(context.get(), url, 1794 true /* exclusive */, true /* recursive */)); 1795 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url)); 1796 1797 // CopyInForeignFile, create case. 1798 url = FileSystemURLAppendUTF8(dir_url, "CopyInForeignFile_file"); 1799 FileSystemURL src_path = FileSystemURLAppendUTF8( 1800 dir_url, "CopyInForeignFile_src_file"); 1801 context.reset(NewContext(NULL)); 1802 EXPECT_EQ(base::PLATFORM_FILE_OK, 1803 ofu()->EnsureFileExists(context.get(), src_path, &created)); 1804 EXPECT_TRUE(created); 1805 base::FilePath src_local_path; 1806 context.reset(NewContext(NULL)); 1807 EXPECT_EQ(base::PLATFORM_FILE_OK, 1808 ofu()->GetLocalFilePath(context.get(), src_path, &src_local_path)); 1809 1810 ClearTimestamp(dir_url); 1811 context.reset(NewContext(NULL)); 1812 EXPECT_EQ(base::PLATFORM_FILE_OK, 1813 ofu()->CopyInForeignFile(context.get(), 1814 src_local_path, 1815 url)); 1816 EXPECT_NE(base::Time(), GetModifiedTime(dir_url)); 1817} 1818 1819TEST_F(ObfuscatedFileUtilTest, TestDirectoryTimestampForDeletion) { 1820 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1821 const FileSystemURL dir_url = CreateURLFromUTF8("foo_dir"); 1822 1823 // Create working directory. 1824 EXPECT_EQ(base::PLATFORM_FILE_OK, 1825 ofu()->CreateDirectory(context.get(), dir_url, false, false)); 1826 1827 // DeleteFile, delete case. 1828 FileSystemURL url = FileSystemURLAppendUTF8( 1829 dir_url, "DeleteFile_file"); 1830 bool created = false; 1831 context.reset(NewContext(NULL)); 1832 EXPECT_EQ(base::PLATFORM_FILE_OK, 1833 ofu()->EnsureFileExists(context.get(), url, &created)); 1834 EXPECT_TRUE(created); 1835 1836 ClearTimestamp(dir_url); 1837 context.reset(NewContext(NULL)); 1838 EXPECT_EQ(base::PLATFORM_FILE_OK, 1839 ofu()->DeleteFile(context.get(), url)); 1840 EXPECT_NE(base::Time(), GetModifiedTime(dir_url)); 1841 1842 // fail case. 1843 ClearTimestamp(dir_url); 1844 context.reset(NewContext(NULL)); 1845 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, 1846 ofu()->DeleteFile(context.get(), url)); 1847 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url)); 1848 1849 // DeleteDirectory, fail case. 1850 url = FileSystemURLAppendUTF8(dir_url, "DeleteDirectory_dir"); 1851 FileSystemURL file_path(FileSystemURLAppendUTF8(url, "pakeratta")); 1852 context.reset(NewContext(NULL)); 1853 EXPECT_EQ(base::PLATFORM_FILE_OK, 1854 ofu()->CreateDirectory(context.get(), url, true, true)); 1855 created = false; 1856 context.reset(NewContext(NULL)); 1857 EXPECT_EQ(base::PLATFORM_FILE_OK, 1858 ofu()->EnsureFileExists(context.get(), file_path, &created)); 1859 EXPECT_TRUE(created); 1860 1861 ClearTimestamp(dir_url); 1862 context.reset(NewContext(NULL)); 1863 EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, 1864 ofu()->DeleteDirectory(context.get(), url)); 1865 EXPECT_EQ(base::Time(), GetModifiedTime(dir_url)); 1866 1867 // delete case. 1868 context.reset(NewContext(NULL)); 1869 EXPECT_EQ(base::PLATFORM_FILE_OK, 1870 ofu()->DeleteFile(context.get(), file_path)); 1871 1872 ClearTimestamp(dir_url); 1873 context.reset(NewContext(NULL)); 1874 EXPECT_EQ(base::PLATFORM_FILE_OK, ofu()->DeleteDirectory(context.get(), url)); 1875 EXPECT_NE(base::Time(), GetModifiedTime(dir_url)); 1876} 1877 1878TEST_F(ObfuscatedFileUtilTest, TestDirectoryTimestampForCopyAndMove) { 1879 TestDirectoryTimestampHelper( 1880 CreateURLFromUTF8("copy overwrite"), true, true); 1881 TestDirectoryTimestampHelper( 1882 CreateURLFromUTF8("copy non-overwrite"), true, false); 1883 TestDirectoryTimestampHelper( 1884 CreateURLFromUTF8("move overwrite"), false, true); 1885 TestDirectoryTimestampHelper( 1886 CreateURLFromUTF8("move non-overwrite"), false, false); 1887} 1888 1889TEST_F(ObfuscatedFileUtilTest, TestFileEnumeratorTimestamp) { 1890 FileSystemURL dir = CreateURLFromUTF8("foo"); 1891 FileSystemURL url1 = FileSystemURLAppendUTF8(dir, "bar"); 1892 FileSystemURL url2 = FileSystemURLAppendUTF8(dir, "baz"); 1893 1894 scoped_ptr<FileSystemOperationContext> context(NewContext(NULL)); 1895 EXPECT_EQ(base::PLATFORM_FILE_OK, 1896 ofu()->CreateDirectory(context.get(), dir, false, false)); 1897 1898 bool created = false; 1899 context.reset(NewContext(NULL)); 1900 EXPECT_EQ(base::PLATFORM_FILE_OK, 1901 ofu()->EnsureFileExists(context.get(), url1, &created)); 1902 EXPECT_TRUE(created); 1903 1904 context.reset(NewContext(NULL)); 1905 EXPECT_EQ(base::PLATFORM_FILE_OK, 1906 ofu()->CreateDirectory(context.get(), url2, false, false)); 1907 1908 base::FilePath file_path; 1909 context.reset(NewContext(NULL)); 1910 EXPECT_EQ(base::PLATFORM_FILE_OK, 1911 ofu()->GetLocalFilePath(context.get(), url1, &file_path)); 1912 EXPECT_FALSE(file_path.empty()); 1913 1914 context.reset(NewContext(NULL)); 1915 EXPECT_EQ(base::PLATFORM_FILE_OK, 1916 ofu()->Touch(context.get(), url1, 1917 base::Time::Now() + base::TimeDelta::FromHours(1), 1918 base::Time())); 1919 1920 context.reset(NewContext(NULL)); 1921 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> file_enum( 1922 ofu()->CreateFileEnumerator(context.get(), dir, false)); 1923 1924 int count = 0; 1925 base::FilePath file_path_each; 1926 while (!(file_path_each = file_enum->Next()).empty()) { 1927 context.reset(NewContext(NULL)); 1928 base::PlatformFileInfo file_info; 1929 base::FilePath file_path; 1930 EXPECT_EQ(base::PLATFORM_FILE_OK, 1931 ofu()->GetFileInfo(context.get(), 1932 FileSystemURL::CreateForTest( 1933 dir.origin(), 1934 dir.mount_type(), 1935 file_path_each), 1936 &file_info, &file_path)); 1937 EXPECT_EQ(file_info.is_directory, file_enum->IsDirectory()); 1938 EXPECT_EQ(file_info.last_modified, file_enum->LastModifiedTime()); 1939 EXPECT_EQ(file_info.size, file_enum->Size()); 1940 ++count; 1941 } 1942 EXPECT_EQ(2, count); 1943} 1944 1945// crbug.com/176470 1946#if defined(OS_WIN) || defined(OS_ANDROID) 1947#define MAYBE_TestQuotaOnCopyFile DISABLED_TestQuotaOnCopyFile 1948#else 1949#define MAYBE_TestQuotaOnCopyFile TestQuotaOnCopyFile 1950#endif 1951TEST_F(ObfuscatedFileUtilTest, MAYBE_TestQuotaOnCopyFile) { 1952 FileSystemURL from_file(CreateURLFromUTF8("fromfile")); 1953 FileSystemURL obstacle_file(CreateURLFromUTF8("obstaclefile")); 1954 FileSystemURL to_file1(CreateURLFromUTF8("tofile1")); 1955 FileSystemURL to_file2(CreateURLFromUTF8("tofile2")); 1956 bool created; 1957 1958 int64 expected_total_file_size = 0; 1959 ASSERT_EQ(base::PLATFORM_FILE_OK, 1960 ofu()->EnsureFileExists( 1961 AllowUsageIncrease(PathCost(from_file))->context(), 1962 from_file, &created)); 1963 ASSERT_TRUE(created); 1964 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 1965 1966 ASSERT_EQ(base::PLATFORM_FILE_OK, 1967 ofu()->EnsureFileExists( 1968 AllowUsageIncrease(PathCost(obstacle_file))->context(), 1969 obstacle_file, &created)); 1970 ASSERT_TRUE(created); 1971 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 1972 1973 int64 from_file_size = 1020; 1974 expected_total_file_size += from_file_size; 1975 ASSERT_EQ(base::PLATFORM_FILE_OK, 1976 ofu()->Truncate( 1977 AllowUsageIncrease(from_file_size)->context(), 1978 from_file, from_file_size)); 1979 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 1980 1981 int64 obstacle_file_size = 1; 1982 expected_total_file_size += obstacle_file_size; 1983 ASSERT_EQ(base::PLATFORM_FILE_OK, 1984 ofu()->Truncate( 1985 AllowUsageIncrease(obstacle_file_size)->context(), 1986 obstacle_file, obstacle_file_size)); 1987 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 1988 1989 int64 to_file1_size = from_file_size; 1990 expected_total_file_size += to_file1_size; 1991 ASSERT_EQ(base::PLATFORM_FILE_OK, 1992 ofu()->CopyOrMoveFile( 1993 AllowUsageIncrease( 1994 PathCost(to_file1) + to_file1_size)->context(), 1995 from_file, to_file1, true /* copy */)); 1996 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 1997 1998 ASSERT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, 1999 ofu()->CopyOrMoveFile( 2000 DisallowUsageIncrease( 2001 PathCost(to_file2) + from_file_size)->context(), 2002 from_file, to_file2, true /* copy */)); 2003 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2004 2005 int64 old_obstacle_file_size = obstacle_file_size; 2006 obstacle_file_size = from_file_size; 2007 expected_total_file_size += obstacle_file_size - old_obstacle_file_size; 2008 ASSERT_EQ(base::PLATFORM_FILE_OK, 2009 ofu()->CopyOrMoveFile( 2010 AllowUsageIncrease( 2011 obstacle_file_size - old_obstacle_file_size)->context(), 2012 from_file, obstacle_file, true /* copy */)); 2013 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2014 2015 int64 old_from_file_size = from_file_size; 2016 from_file_size = old_from_file_size - 1; 2017 expected_total_file_size += from_file_size - old_from_file_size; 2018 ASSERT_EQ(base::PLATFORM_FILE_OK, 2019 ofu()->Truncate( 2020 AllowUsageIncrease( 2021 from_file_size - old_from_file_size)->context(), 2022 from_file, from_file_size)); 2023 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2024 2025 // quota exceeded 2026 { 2027 old_obstacle_file_size = obstacle_file_size; 2028 obstacle_file_size = from_file_size; 2029 expected_total_file_size += obstacle_file_size - old_obstacle_file_size; 2030 scoped_ptr<UsageVerifyHelper> helper = AllowUsageIncrease( 2031 obstacle_file_size - old_obstacle_file_size); 2032 helper->context()->set_allowed_bytes_growth( 2033 helper->context()->allowed_bytes_growth() - 1); 2034 ASSERT_EQ(base::PLATFORM_FILE_OK, 2035 ofu()->CopyOrMoveFile( 2036 helper->context(), 2037 from_file, obstacle_file, true /* copy */)); 2038 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2039 } 2040} 2041 2042TEST_F(ObfuscatedFileUtilTest, TestQuotaOnMoveFile) { 2043 FileSystemURL from_file(CreateURLFromUTF8("fromfile")); 2044 FileSystemURL obstacle_file(CreateURLFromUTF8("obstaclefile")); 2045 FileSystemURL to_file(CreateURLFromUTF8("tofile")); 2046 bool created; 2047 2048 int64 expected_total_file_size = 0; 2049 ASSERT_EQ(base::PLATFORM_FILE_OK, 2050 ofu()->EnsureFileExists( 2051 AllowUsageIncrease(PathCost(from_file))->context(), 2052 from_file, &created)); 2053 ASSERT_TRUE(created); 2054 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2055 2056 int64 from_file_size = 1020; 2057 expected_total_file_size += from_file_size; 2058 ASSERT_EQ(base::PLATFORM_FILE_OK, 2059 ofu()->Truncate( 2060 AllowUsageIncrease(from_file_size)->context(), 2061 from_file, from_file_size)); 2062 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2063 2064 int64 to_file_size ALLOW_UNUSED = from_file_size; 2065 from_file_size = 0; 2066 ASSERT_EQ(base::PLATFORM_FILE_OK, 2067 ofu()->CopyOrMoveFile( 2068 AllowUsageIncrease(-PathCost(from_file) + 2069 PathCost(to_file))->context(), 2070 from_file, to_file, false /* move */)); 2071 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2072 2073 ASSERT_EQ(base::PLATFORM_FILE_OK, 2074 ofu()->EnsureFileExists( 2075 AllowUsageIncrease(PathCost(from_file))->context(), 2076 from_file, &created)); 2077 ASSERT_TRUE(created); 2078 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2079 2080 ASSERT_EQ(base::PLATFORM_FILE_OK, 2081 ofu()->EnsureFileExists( 2082 AllowUsageIncrease(PathCost(obstacle_file))->context(), 2083 obstacle_file, &created)); 2084 ASSERT_TRUE(created); 2085 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2086 2087 from_file_size = 1020; 2088 expected_total_file_size += from_file_size; 2089 ASSERT_EQ(base::PLATFORM_FILE_OK, 2090 ofu()->Truncate( 2091 AllowUsageIncrease(from_file_size)->context(), 2092 from_file, from_file_size)); 2093 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2094 2095 int64 obstacle_file_size = 1; 2096 expected_total_file_size += obstacle_file_size; 2097 ASSERT_EQ(base::PLATFORM_FILE_OK, 2098 ofu()->Truncate( 2099 AllowUsageIncrease(1)->context(), 2100 obstacle_file, obstacle_file_size)); 2101 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2102 2103 int64 old_obstacle_file_size = obstacle_file_size; 2104 obstacle_file_size = from_file_size; 2105 from_file_size = 0; 2106 expected_total_file_size -= old_obstacle_file_size; 2107 ASSERT_EQ(base::PLATFORM_FILE_OK, 2108 ofu()->CopyOrMoveFile( 2109 AllowUsageIncrease( 2110 -old_obstacle_file_size - PathCost(from_file))->context(), 2111 from_file, obstacle_file, 2112 false /* move */)); 2113 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2114 2115 ASSERT_EQ(base::PLATFORM_FILE_OK, 2116 ofu()->EnsureFileExists( 2117 AllowUsageIncrease(PathCost(from_file))->context(), 2118 from_file, &created)); 2119 ASSERT_TRUE(created); 2120 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2121 2122 from_file_size = 10; 2123 expected_total_file_size += from_file_size; 2124 ASSERT_EQ(base::PLATFORM_FILE_OK, 2125 ofu()->Truncate( 2126 AllowUsageIncrease(from_file_size)->context(), 2127 from_file, from_file_size)); 2128 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2129 2130 // quota exceeded even after operation 2131 old_obstacle_file_size = obstacle_file_size; 2132 obstacle_file_size = from_file_size; 2133 from_file_size = 0; 2134 expected_total_file_size -= old_obstacle_file_size; 2135 scoped_ptr<FileSystemOperationContext> context = 2136 LimitedContext(-old_obstacle_file_size - PathCost(from_file) - 1); 2137 ASSERT_EQ(base::PLATFORM_FILE_OK, 2138 ofu()->CopyOrMoveFile( 2139 context.get(), from_file, obstacle_file, false /* move */)); 2140 ASSERT_EQ(expected_total_file_size, ComputeTotalFileSize()); 2141 context.reset(); 2142} 2143 2144TEST_F(ObfuscatedFileUtilTest, TestQuotaOnRemove) { 2145 FileSystemURL dir(CreateURLFromUTF8("dir")); 2146 FileSystemURL file(CreateURLFromUTF8("file")); 2147 FileSystemURL dfile1(CreateURLFromUTF8("dir/dfile1")); 2148 FileSystemURL dfile2(CreateURLFromUTF8("dir/dfile2")); 2149 bool created; 2150 2151 ASSERT_EQ(base::PLATFORM_FILE_OK, 2152 ofu()->EnsureFileExists( 2153 AllowUsageIncrease(PathCost(file))->context(), 2154 file, &created)); 2155 ASSERT_TRUE(created); 2156 ASSERT_EQ(0, ComputeTotalFileSize()); 2157 2158 ASSERT_EQ(base::PLATFORM_FILE_OK, 2159 ofu()->CreateDirectory( 2160 AllowUsageIncrease(PathCost(dir))->context(), 2161 dir, false, false)); 2162 ASSERT_EQ(0, ComputeTotalFileSize()); 2163 2164 ASSERT_EQ(base::PLATFORM_FILE_OK, 2165 ofu()->EnsureFileExists( 2166 AllowUsageIncrease(PathCost(dfile1))->context(), 2167 dfile1, &created)); 2168 ASSERT_TRUE(created); 2169 ASSERT_EQ(0, ComputeTotalFileSize()); 2170 2171 ASSERT_EQ(base::PLATFORM_FILE_OK, 2172 ofu()->EnsureFileExists( 2173 AllowUsageIncrease(PathCost(dfile2))->context(), 2174 dfile2, &created)); 2175 ASSERT_TRUE(created); 2176 ASSERT_EQ(0, ComputeTotalFileSize()); 2177 2178 ASSERT_EQ(base::PLATFORM_FILE_OK, 2179 ofu()->Truncate( 2180 AllowUsageIncrease(340)->context(), 2181 file, 340)); 2182 ASSERT_EQ(340, ComputeTotalFileSize()); 2183 2184 ASSERT_EQ(base::PLATFORM_FILE_OK, 2185 ofu()->Truncate( 2186 AllowUsageIncrease(1020)->context(), 2187 dfile1, 1020)); 2188 ASSERT_EQ(1360, ComputeTotalFileSize()); 2189 2190 ASSERT_EQ(base::PLATFORM_FILE_OK, 2191 ofu()->Truncate( 2192 AllowUsageIncrease(120)->context(), 2193 dfile2, 120)); 2194 ASSERT_EQ(1480, ComputeTotalFileSize()); 2195 2196 ASSERT_EQ(base::PLATFORM_FILE_OK, 2197 ofu()->DeleteFile( 2198 AllowUsageIncrease(-PathCost(file) - 340)->context(), 2199 file)); 2200 ASSERT_EQ(1140, ComputeTotalFileSize()); 2201 2202 ASSERT_EQ(base::PLATFORM_FILE_OK, 2203 AsyncFileTestHelper::Remove( 2204 file_system_context(), dir, true /* recursive */)); 2205 ASSERT_EQ(0, ComputeTotalFileSize()); 2206} 2207 2208TEST_F(ObfuscatedFileUtilTest, TestQuotaOnOpen) { 2209 FileSystemURL file(CreateURLFromUTF8("file")); 2210 base::PlatformFile file_handle; 2211 bool created; 2212 2213 // Creating a file. 2214 ASSERT_EQ(base::PLATFORM_FILE_OK, 2215 ofu()->EnsureFileExists( 2216 AllowUsageIncrease(PathCost(file))->context(), 2217 file, &created)); 2218 ASSERT_TRUE(created); 2219 ASSERT_EQ(0, ComputeTotalFileSize()); 2220 2221 // Opening it, which shouldn't change the usage. 2222 ASSERT_EQ(base::PLATFORM_FILE_OK, 2223 ofu()->CreateOrOpen( 2224 AllowUsageIncrease(0)->context(), file, 2225 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE, 2226 &file_handle, &created)); 2227 ASSERT_EQ(0, ComputeTotalFileSize()); 2228 EXPECT_TRUE(base::ClosePlatformFile(file_handle)); 2229 2230 const int length = 33; 2231 ASSERT_EQ(base::PLATFORM_FILE_OK, 2232 ofu()->Truncate( 2233 AllowUsageIncrease(length)->context(), file, length)); 2234 ASSERT_EQ(length, ComputeTotalFileSize()); 2235 2236 // Opening it with CREATE_ALWAYS flag, which should truncate the file size. 2237 ASSERT_EQ(base::PLATFORM_FILE_OK, 2238 ofu()->CreateOrOpen( 2239 AllowUsageIncrease(-length)->context(), file, 2240 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE, 2241 &file_handle, &created)); 2242 ASSERT_EQ(0, ComputeTotalFileSize()); 2243 EXPECT_TRUE(base::ClosePlatformFile(file_handle)); 2244 2245 // Extending the file again. 2246 ASSERT_EQ(base::PLATFORM_FILE_OK, 2247 ofu()->Truncate( 2248 AllowUsageIncrease(length)->context(), file, length)); 2249 ASSERT_EQ(length, ComputeTotalFileSize()); 2250 2251 // Opening it with TRUNCATED flag, which should truncate the file size. 2252 ASSERT_EQ(base::PLATFORM_FILE_OK, 2253 ofu()->CreateOrOpen( 2254 AllowUsageIncrease(-length)->context(), file, 2255 base::PLATFORM_FILE_OPEN_TRUNCATED | base::PLATFORM_FILE_WRITE, 2256 &file_handle, &created)); 2257 ASSERT_EQ(0, ComputeTotalFileSize()); 2258 EXPECT_TRUE(base::ClosePlatformFile(file_handle)); 2259} 2260 2261TEST_F(ObfuscatedFileUtilTest, MaybeDropDatabasesAliveCase) { 2262 ObfuscatedFileUtil file_util(NULL, 2263 data_dir_path(), 2264 base::MessageLoopProxy::current().get()); 2265 file_util.InitOriginDatabase(true /*create*/); 2266 ASSERT_TRUE(file_util.origin_database_ != NULL); 2267 2268 // Callback to Drop DB is called while ObfuscatedFileUtilTest is still alive. 2269 file_util.db_flush_delay_seconds_ = 0; 2270 file_util.MarkUsed(); 2271 base::MessageLoop::current()->RunUntilIdle(); 2272 2273 ASSERT_TRUE(file_util.origin_database_ == NULL); 2274} 2275 2276TEST_F(ObfuscatedFileUtilTest, MaybeDropDatabasesAlreadyDeletedCase) { 2277 // Run message loop after OFU is already deleted to make sure callback doesn't 2278 // cause a crash for use after free. 2279 { 2280 ObfuscatedFileUtil file_util(NULL, 2281 data_dir_path(), 2282 base::MessageLoopProxy::current().get()); 2283 file_util.InitOriginDatabase(true /*create*/); 2284 file_util.db_flush_delay_seconds_ = 0; 2285 file_util.MarkUsed(); 2286 } 2287 2288 // At this point the callback is still in the message queue but OFU is gone. 2289 base::MessageLoop::current()->RunUntilIdle(); 2290} 2291 2292TEST_F(ObfuscatedFileUtilTest, DestroyDirectoryDatabase_Isolated) { 2293 storage_policy_->AddIsolated(origin_); 2294 ObfuscatedFileUtil file_util( 2295 storage_policy_.get(), data_dir_path(), 2296 base::MessageLoopProxy::current().get()); 2297 2298 // Create DirectoryDatabase for isolated origin. 2299 SandboxDirectoryDatabase* db = file_util.GetDirectoryDatabase( 2300 origin_, kFileSystemTypePersistent, true /* create */); 2301 ASSERT_TRUE(db != NULL); 2302 2303 // Destory it. 2304 ASSERT_TRUE( 2305 file_util.DestroyDirectoryDatabase(origin_, kFileSystemTypePersistent)); 2306 ASSERT_TRUE(file_util.directories_.empty()); 2307} 2308 2309TEST_F(ObfuscatedFileUtilTest, GetDirectoryDatabase_Isolated) { 2310 storage_policy_->AddIsolated(origin_); 2311 ObfuscatedFileUtil file_util( 2312 storage_policy_.get(), data_dir_path(), 2313 base::MessageLoopProxy::current().get()); 2314 2315 // Create DirectoryDatabase for isolated origin. 2316 SandboxDirectoryDatabase* db = file_util.GetDirectoryDatabase( 2317 origin_, kFileSystemTypePersistent, true /* create */); 2318 ASSERT_TRUE(db != NULL); 2319 ASSERT_EQ(1U, file_util.directories_.size()); 2320 2321 // Remove isolated. 2322 storage_policy_->RemoveIsolated(origin_); 2323 2324 // This should still get the same database. 2325 SandboxDirectoryDatabase* db2 = file_util.GetDirectoryDatabase( 2326 origin_, kFileSystemTypePersistent, false /* create */); 2327 ASSERT_EQ(db, db2); 2328} 2329 2330} // namespace fileapi 2331