Home | History | Annotate | Download | only in drive
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/drive/file_cache.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/callback_helpers.h"
     11 #include "base/files/file_enumerator.h"
     12 #include "base/files/file_util.h"
     13 #include "base/files/scoped_temp_dir.h"
     14 #include "base/md5.h"
     15 #include "base/path_service.h"
     16 #include "chrome/browser/chromeos/drive/drive.pb.h"
     17 #include "chrome/browser/chromeos/drive/fake_free_disk_space_getter.h"
     18 #include "chrome/browser/chromeos/drive/file_system_util.h"
     19 #include "chrome/browser/chromeos/drive/resource_metadata_storage.h"
     20 #include "chrome/browser/chromeos/drive/test_util.h"
     21 #include "content/public/test/test_browser_thread_bundle.h"
     22 #include "google_apis/drive/test_util.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 
     25 namespace drive {
     26 namespace internal {
     27 namespace {
     28 
     29 const char kCacheFileDirectory[] = "files";
     30 
     31 }  // namespace
     32 
     33 // Tests FileCache methods working with the blocking task runner.
     34 class FileCacheTest : public testing::Test {
     35  protected:
     36   virtual void SetUp() OVERRIDE {
     37     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     38     const base::FilePath metadata_dir = temp_dir_.path().AppendASCII("meta");
     39     cache_files_dir_ = temp_dir_.path().AppendASCII(kCacheFileDirectory);
     40 
     41     ASSERT_TRUE(base::CreateDirectory(metadata_dir));
     42     ASSERT_TRUE(base::CreateDirectory(cache_files_dir_));
     43 
     44     fake_free_disk_space_getter_.reset(new FakeFreeDiskSpaceGetter);
     45 
     46     metadata_storage_.reset(new ResourceMetadataStorage(
     47         metadata_dir,
     48         base::MessageLoopProxy::current().get()));
     49     ASSERT_TRUE(metadata_storage_->Initialize());
     50 
     51     cache_.reset(new FileCache(
     52         metadata_storage_.get(),
     53         cache_files_dir_,
     54         base::MessageLoopProxy::current().get(),
     55         fake_free_disk_space_getter_.get()));
     56     ASSERT_TRUE(cache_->Initialize());
     57   }
     58 
     59   static bool RenameCacheFilesToNewFormat(FileCache* cache) {
     60     return cache->RenameCacheFilesToNewFormat();
     61   }
     62 
     63   content::TestBrowserThreadBundle thread_bundle_;
     64   base::ScopedTempDir temp_dir_;
     65   base::FilePath cache_files_dir_;
     66 
     67   scoped_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
     68       metadata_storage_;
     69   scoped_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
     70   scoped_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_;
     71 };
     72 
     73 TEST_F(FileCacheTest, RecoverFilesFromCacheDirectory) {
     74   base::FilePath dir_source_root;
     75   EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &dir_source_root));
     76   const base::FilePath src_path =
     77       dir_source_root.AppendASCII("chrome/test/data/chromeos/drive/image.png");
     78 
     79   // Store files. This file should not be moved.
     80   ResourceEntry entry;
     81   entry.set_local_id("id_foo");
     82   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
     83   EXPECT_EQ(FILE_ERROR_OK, cache_->Store("id_foo", "md5", src_path,
     84                                          FileCache::FILE_OPERATION_COPY));
     85 
     86   // Set up files in the cache directory. These files should be moved.
     87   const base::FilePath file_directory =
     88       temp_dir_.path().AppendASCII(kCacheFileDirectory);
     89   ASSERT_TRUE(base::CopyFile(src_path, file_directory.AppendASCII("id_bar")));
     90   ASSERT_TRUE(base::CopyFile(src_path, file_directory.AppendASCII("id_baz")));
     91 
     92   // Insert a dirty entry with "id_baz" to |recovered_cache_info|.
     93   // This should not prevent the file from being recovered.
     94   ResourceMetadataStorage::RecoveredCacheInfoMap recovered_cache_info;
     95   recovered_cache_info["id_baz"].is_dirty = true;
     96   recovered_cache_info["id_baz"].title = "baz.png";
     97 
     98   // Recover files.
     99   const base::FilePath dest_directory = temp_dir_.path().AppendASCII("dest");
    100   EXPECT_TRUE(cache_->RecoverFilesFromCacheDirectory(dest_directory,
    101                                                      recovered_cache_info));
    102 
    103   // Only two files should be recovered.
    104   EXPECT_TRUE(base::PathExists(dest_directory));
    105   // base::FileEnumerator does not guarantee the order.
    106   if (base::PathExists(dest_directory.AppendASCII("baz00000001.png"))) {
    107     EXPECT_TRUE(base::ContentsEqual(
    108         src_path,
    109         dest_directory.AppendASCII("baz00000001.png")));
    110     EXPECT_TRUE(base::ContentsEqual(
    111         src_path,
    112         dest_directory.AppendASCII("image00000002.png")));
    113   } else {
    114     EXPECT_TRUE(base::ContentsEqual(
    115         src_path,
    116         dest_directory.AppendASCII("image00000001.png")));
    117     EXPECT_TRUE(base::ContentsEqual(
    118         src_path,
    119         dest_directory.AppendASCII("baz00000002.png")));
    120   }
    121   EXPECT_FALSE(base::PathExists(
    122       dest_directory.AppendASCII("image00000003.png")));
    123 }
    124 
    125 TEST_F(FileCacheTest, FreeDiskSpaceIfNeededFor) {
    126   base::FilePath src_file;
    127   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
    128 
    129   // Store a file as a 'temporary' file and remember the path.
    130   const std::string id_tmp = "id_tmp", md5_tmp = "md5_tmp";
    131 
    132   ResourceEntry entry;
    133   entry.set_local_id(id_tmp);
    134   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    135   ASSERT_EQ(FILE_ERROR_OK,
    136             cache_->Store(id_tmp, md5_tmp, src_file,
    137                           FileCache::FILE_OPERATION_COPY));
    138   base::FilePath tmp_path;
    139   ASSERT_EQ(FILE_ERROR_OK, cache_->GetFile(id_tmp, &tmp_path));
    140 
    141   // Store a file as a pinned file and remember the path.
    142   const std::string id_pinned = "id_pinned", md5_pinned = "md5_pinned";
    143   entry.Clear();
    144   entry.set_local_id(id_pinned);
    145   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    146   ASSERT_EQ(FILE_ERROR_OK,
    147             cache_->Store(id_pinned, md5_pinned, src_file,
    148                           FileCache::FILE_OPERATION_COPY));
    149   ASSERT_EQ(FILE_ERROR_OK, cache_->Pin(id_pinned));
    150   base::FilePath pinned_path;
    151   ASSERT_EQ(FILE_ERROR_OK, cache_->GetFile(id_pinned, &pinned_path));
    152 
    153   // Call FreeDiskSpaceIfNeededFor().
    154   fake_free_disk_space_getter_->set_default_value(test_util::kLotsOfSpace);
    155   fake_free_disk_space_getter_->PushFakeValue(0);
    156   const int64 kNeededBytes = 1;
    157   EXPECT_TRUE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes));
    158 
    159   // Only 'temporary' file gets removed.
    160   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_tmp, &entry));
    161   EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());
    162   EXPECT_FALSE(base::PathExists(tmp_path));
    163 
    164   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_pinned, &entry));
    165   EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
    166   EXPECT_TRUE(base::PathExists(pinned_path));
    167 
    168   // Returns false when disk space cannot be freed.
    169   fake_free_disk_space_getter_->set_default_value(0);
    170   EXPECT_FALSE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes));
    171 }
    172 
    173 TEST_F(FileCacheTest, GetFile) {
    174   const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
    175   const std::string src_contents = "test";
    176   EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
    177                                                         src_contents));
    178   std::string id("id1");
    179   std::string md5(base::MD5String(src_contents));
    180 
    181   const base::FilePath cache_file_directory =
    182       temp_dir_.path().AppendASCII(kCacheFileDirectory);
    183 
    184   // Try to get an existing file from cache.
    185   ResourceEntry entry;
    186   entry.set_local_id(id);
    187   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    188   EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, md5, src_file_path,
    189                                          FileCache::FILE_OPERATION_COPY));
    190   base::FilePath cache_file_path;
    191   EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
    192   EXPECT_EQ(
    193       cache_file_directory.AppendASCII(util::EscapeCacheFileName(id)).value(),
    194       cache_file_path.value());
    195 
    196   std::string contents;
    197   EXPECT_TRUE(base::ReadFileToString(cache_file_path, &contents));
    198   EXPECT_EQ(src_contents, contents);
    199 
    200   // Get file from cache with different id.
    201   id = "id2";
    202   entry.Clear();
    203   entry.set_local_id(id);
    204   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    205   EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->GetFile(id, &cache_file_path));
    206 
    207   // Pin a non-existent file.
    208   EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id));
    209 
    210   // Get the non-existent pinned file from cache.
    211   EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->GetFile(id, &cache_file_path));
    212 
    213   // Get a previously pinned and stored file from cache.
    214   EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, md5, src_file_path,
    215                                          FileCache::FILE_OPERATION_COPY));
    216 
    217   EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
    218   EXPECT_EQ(
    219       cache_file_directory.AppendASCII(util::EscapeCacheFileName(id)).value(),
    220       cache_file_path.value());
    221 
    222   contents.clear();
    223   EXPECT_TRUE(base::ReadFileToString(cache_file_path, &contents));
    224   EXPECT_EQ(src_contents, contents);
    225 }
    226 
    227 TEST_F(FileCacheTest, Store) {
    228   const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
    229   const std::string src_contents = "test";
    230   EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
    231                                                         src_contents));
    232   std::string id("id");
    233   std::string md5(base::MD5String(src_contents));
    234 
    235   // Store a file.
    236   ResourceEntry entry;
    237   entry.set_local_id(id);
    238   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    239   EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
    240       id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
    241 
    242   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    243   EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
    244   EXPECT_EQ(md5, entry.file_specific_info().cache_state().md5());
    245 
    246   base::FilePath cache_file_path;
    247   EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
    248   EXPECT_TRUE(base::ContentsEqual(src_file_path, cache_file_path));
    249 
    250   // Store a non-existent file.
    251   EXPECT_EQ(FILE_ERROR_FAILED, cache_->Store(
    252       id, md5, base::FilePath::FromUTF8Unsafe("non_existent_file"),
    253       FileCache::FILE_OPERATION_COPY));
    254 
    255   // Passing empty MD5 marks the entry as dirty.
    256   EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
    257       id, std::string(), src_file_path, FileCache::FILE_OPERATION_COPY));
    258 
    259   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    260   EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
    261   EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty());
    262   EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
    263 
    264   // No free space available.
    265   fake_free_disk_space_getter_->set_default_value(0);
    266 
    267   EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, cache_->Store(
    268       id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
    269 }
    270 
    271 TEST_F(FileCacheTest, PinAndUnpin) {
    272   const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
    273   const std::string src_contents = "test";
    274   EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
    275                                                         src_contents));
    276   std::string id("id_present");
    277   std::string md5(base::MD5String(src_contents));
    278 
    279   // Store a file.
    280   ResourceEntry entry;
    281   entry.set_local_id(id);
    282   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    283   EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
    284       id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
    285 
    286   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    287   EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned());
    288 
    289   // Pin the existing file.
    290   EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id));
    291 
    292   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    293   EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned());
    294 
    295   // Unpin the file.
    296   EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id));
    297 
    298   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    299   EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned());
    300 
    301   // Pin a non-present file.
    302   std::string id_non_present = "id_non_present";
    303   entry.Clear();
    304   entry.set_local_id(id_non_present);
    305   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    306   EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id_non_present));
    307 
    308   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry));
    309   EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned());
    310 
    311   // Unpin the previously pinned non-existent file.
    312   EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id_non_present));
    313 
    314   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry));
    315   EXPECT_FALSE(entry.file_specific_info().has_cache_state());
    316 
    317   // Unpin a file that doesn't exist in cache and is not pinned.
    318   EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->Unpin("id_non_existent"));
    319 }
    320 
    321 TEST_F(FileCacheTest, MountUnmount) {
    322   const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
    323   const std::string src_contents = "test";
    324   EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
    325                                                         src_contents));
    326   std::string id("id_present");
    327   std::string md5(base::MD5String(src_contents));
    328 
    329   // Store a file.
    330   ResourceEntry entry;
    331   entry.set_local_id(id);
    332   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    333   EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
    334       id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
    335 
    336   // Mark the file mounted.
    337   base::FilePath cache_file_path;
    338   EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsMounted(id, &cache_file_path));
    339 
    340   // Try to remove it.
    341   EXPECT_EQ(FILE_ERROR_IN_USE, cache_->Remove(id));
    342 
    343   // Clear mounted state of the file.
    344   EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsUnmounted(cache_file_path));
    345 
    346   // Try to remove again.
    347   EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id));
    348 }
    349 
    350 TEST_F(FileCacheTest, OpenForWrite) {
    351   // Prepare a file.
    352   base::FilePath src_file;
    353   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
    354 
    355   const std::string id = "id";
    356   ResourceEntry entry;
    357   entry.set_local_id(id);
    358   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    359   ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file,
    360                                          FileCache::FILE_OPERATION_COPY));
    361   EXPECT_EQ(0, entry.file_info().last_modified());
    362 
    363   // Entry is not dirty nor opened.
    364   EXPECT_FALSE(cache_->IsOpenedForWrite(id));
    365   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    366   EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
    367 
    368   // Open (1).
    369   scoped_ptr<base::ScopedClosureRunner> file_closer1;
    370   EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer1));
    371   EXPECT_TRUE(cache_->IsOpenedForWrite(id));
    372 
    373   // Entry is dirty.
    374   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    375   EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
    376 
    377   // Open (2).
    378   scoped_ptr<base::ScopedClosureRunner> file_closer2;
    379   EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer2));
    380   EXPECT_TRUE(cache_->IsOpenedForWrite(id));
    381 
    382   // Close (1).
    383   file_closer1.reset();
    384   base::RunLoop().RunUntilIdle();
    385   EXPECT_TRUE(cache_->IsOpenedForWrite(id));
    386 
    387   // last_modified is updated.
    388   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    389   EXPECT_NE(0, entry.file_info().last_modified());
    390 
    391   // Close (2).
    392   file_closer2.reset();
    393   base::RunLoop().RunUntilIdle();
    394   EXPECT_FALSE(cache_->IsOpenedForWrite(id));
    395 
    396   // Try to open non-existent file.
    397   EXPECT_EQ(FILE_ERROR_NOT_FOUND,
    398             cache_->OpenForWrite("nonexistent_id", &file_closer1));
    399 }
    400 
    401 TEST_F(FileCacheTest, UpdateMd5) {
    402   // Store test data.
    403   const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
    404   const std::string contents_before = "before";
    405   EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
    406                                                         contents_before));
    407   std::string id("id1");
    408   ResourceEntry entry;
    409   entry.set_local_id(id);
    410   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    411   EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, base::MD5String(contents_before),
    412                                          src_file_path,
    413                                          FileCache::FILE_OPERATION_COPY));
    414 
    415   // Modify the cache file.
    416   scoped_ptr<base::ScopedClosureRunner> file_closer;
    417   EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer));
    418   base::FilePath cache_file_path;
    419   EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
    420   const std::string contents_after = "after";
    421   EXPECT_TRUE(google_apis::test_util::WriteStringToFile(cache_file_path,
    422                                                         contents_after));
    423 
    424   // Cannot update MD5 of an opend file.
    425   EXPECT_EQ(FILE_ERROR_IN_USE, cache_->UpdateMd5(id));
    426 
    427   // Close file.
    428   file_closer.reset();
    429   base::RunLoop().RunUntilIdle();
    430 
    431   // MD5 was cleared by OpenForWrite().
    432   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    433   EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty());
    434 
    435   // Update MD5.
    436   EXPECT_EQ(FILE_ERROR_OK, cache_->UpdateMd5(id));
    437   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    438   EXPECT_EQ(base::MD5String(contents_after),
    439             entry.file_specific_info().cache_state().md5());
    440 }
    441 
    442 TEST_F(FileCacheTest, ClearDirty) {
    443   // Prepare a file.
    444   base::FilePath src_file;
    445   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
    446 
    447   const std::string id = "id";
    448   ResourceEntry entry;
    449   entry.set_local_id(id);
    450   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    451   ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file,
    452                                          FileCache::FILE_OPERATION_COPY));
    453 
    454   // Open the file.
    455   scoped_ptr<base::ScopedClosureRunner> file_closer;
    456   EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer));
    457 
    458   // Entry is dirty.
    459   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    460   EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());
    461 
    462   // Cannot clear the dirty bit of an opened entry.
    463   EXPECT_EQ(FILE_ERROR_IN_USE, cache_->ClearDirty(id));
    464 
    465   // Close the file and clear the dirty bit.
    466   file_closer.reset();
    467   base::RunLoop().RunUntilIdle();
    468   EXPECT_EQ(FILE_ERROR_OK, cache_->ClearDirty(id));
    469 
    470   // Entry is not dirty.
    471   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry));
    472   EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
    473 }
    474 
    475 TEST_F(FileCacheTest, Remove) {
    476   const base::FilePath src_file_path = temp_dir_.path().Append("test.dat");
    477   const std::string src_contents = "test";
    478   EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path,
    479                                                         src_contents));
    480   std::string id("id");
    481   std::string md5(base::MD5String(src_contents));
    482 
    483   // First store a file to cache.
    484   ResourceEntry entry;
    485   entry.set_local_id(id);
    486   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    487   base::FilePath src_file;
    488   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
    489   EXPECT_EQ(FILE_ERROR_OK, cache_->Store(
    490       id, md5, src_file_path, FileCache::FILE_OPERATION_COPY));
    491 
    492   base::FilePath cache_file_path;
    493   EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path));
    494 
    495   // Then try to remove existing file from cache.
    496   EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id));
    497   EXPECT_FALSE(base::PathExists(cache_file_path));
    498 }
    499 
    500 TEST_F(FileCacheTest, RenameCacheFilesToNewFormat) {
    501   const base::FilePath file_directory =
    502       temp_dir_.path().AppendASCII(kCacheFileDirectory);
    503 
    504   // File with an old style "<prefix>:<ID>.<MD5>" name.
    505   ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
    506       file_directory.AppendASCII("file:id_koo.md5"), "koo"));
    507 
    508   // File with multiple extensions should be removed.
    509   ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
    510       file_directory.AppendASCII("id_kyu.md5.mounted"), "kyu (mounted)"));
    511   ASSERT_TRUE(google_apis::test_util::WriteStringToFile(
    512       file_directory.AppendASCII("id_kyu.md5"), "kyu"));
    513 
    514   // Rename and verify the result.
    515   EXPECT_TRUE(RenameCacheFilesToNewFormat(cache_.get()));
    516   std::string contents;
    517   EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"),
    518                                      &contents));
    519   EXPECT_EQ("koo", contents);
    520   contents.clear();
    521   EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"),
    522                                      &contents));
    523   EXPECT_EQ("kyu", contents);
    524 
    525   // Rename again.
    526   EXPECT_TRUE(RenameCacheFilesToNewFormat(cache_.get()));
    527 
    528   // Files with new style names are not affected.
    529   contents.clear();
    530   EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"),
    531                                      &contents));
    532   EXPECT_EQ("koo", contents);
    533   contents.clear();
    534   EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"),
    535                                      &contents));
    536   EXPECT_EQ("kyu", contents);
    537 }
    538 
    539 TEST_F(FileCacheTest, ClearAll) {
    540   const std::string id("1a2b");
    541   const std::string md5("abcdef0123456789");
    542 
    543   // Store an existing file.
    544   ResourceEntry entry;
    545   entry.set_local_id(id);
    546   EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry));
    547   base::FilePath src_file;
    548   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &src_file));
    549   ASSERT_EQ(FILE_ERROR_OK,
    550             cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY));
    551 
    552   // Clear cache.
    553   EXPECT_TRUE(cache_->ClearAll());
    554 
    555   // Verify that the cache is removed.
    556   EXPECT_TRUE(base::IsDirectoryEmpty(cache_files_dir_));
    557 }
    558 
    559 }  // namespace internal
    560 }  // namespace drive
    561