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