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
25namespace drive {
26namespace internal {
27namespace {
28
29const char kCacheFileDirectory[] = "files";
30
31}  // namespace
32
33// Tests FileCache methods working with the blocking task runner.
34class 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
73TEST_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
125TEST_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
173TEST_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
227TEST_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
271TEST_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
321TEST_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
350TEST_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
401TEST_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
442TEST_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
475TEST_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
500TEST_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
539TEST_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