Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_cache_unittest.cc

Issue 10877005: Rename GDataCache* to DriveCache* (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 <algorithm>
6 #include <vector>
7
8 #include "base/file_util.h"
9 #include "base/message_loop.h"
10 #include "base/path_service.h"
11 #include "base/threading/sequenced_worker_pool.h"
12 #include "chrome/browser/chromeos/gdata/drive.pb.h"
13 #include "chrome/browser/chromeos/gdata/gdata_cache.h"
14 #include "chrome/browser/chromeos/gdata/gdata_file_system.h"
15 #include "chrome/browser/chromeos/gdata/gdata_test_util.h"
16 #include "chrome/browser/chromeos/gdata/gdata_util.h"
17 #include "chrome/browser/chromeos/gdata/mock_gdata_cache_observer.h"
18 #include "chrome/common/chrome_paths.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "content/public/test/test_browser_thread.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 using ::testing::AtLeast;
25 using ::testing::Return;
26 using ::testing::StrictMock;
27
28 namespace gdata {
29 namespace {
30
31 const char kSymLinkToDevNull[] = "/dev/null";
32
33 struct InitialCacheResource {
34 const char* source_file; // Source file to be used for cache.
35 const char* resource_id; // Resource id of cache file.
36 const char* md5; // MD5 of cache file.
37 int cache_state; // Cache state of cache file.
38 const char* expected_file_extension; // Expected extension of cached file.
39 // Expected CacheSubDirectoryType of cached file.
40 GDataCache::CacheSubDirectoryType expected_sub_dir_type;
41 } const initial_cache_resources[] = {
42 // Cache resource in tmp dir, i.e. not pinned or dirty.
43 { "root_feed.json", "tmp:resource_id", "md5_tmp_alphanumeric",
44 test_util::TEST_CACHE_STATE_PRESENT,
45 "md5_tmp_alphanumeric", GDataCache::CACHE_TYPE_TMP },
46 // Cache resource in tmp dir, i.e. not pinned or dirty, with resource_id
47 // containing non-alphanumeric characters, to test resource_id is escaped and
48 // unescaped correctly.
49 { "subdir_feed.json", "tmp:`~!@#$%^&*()-_=+[{|]}\\;',<.>/?",
50 "md5_tmp_non_alphanumeric",
51 test_util::TEST_CACHE_STATE_PRESENT,
52 "md5_tmp_non_alphanumeric", GDataCache::CACHE_TYPE_TMP },
53 // Cache resource that is pinned, to test a pinned file is in persistent dir
54 // with a symlink in pinned dir referencing it.
55 { "directory_entry_atom.json", "pinned:existing", "md5_pinned_existing",
56 test_util::TEST_CACHE_STATE_PRESENT |
57 test_util::TEST_CACHE_STATE_PINNED |
58 test_util::TEST_CACHE_STATE_PERSISTENT,
59 "md5_pinned_existing", GDataCache::CACHE_TYPE_PERSISTENT },
60 // Cache resource with a non-existent source file that is pinned, to test that
61 // a pinned file can reference a non-existent file.
62 { "", "pinned:non-existent", "md5_pinned_non_existent",
63 test_util::TEST_CACHE_STATE_PINNED,
64 "md5_pinned_non_existent", GDataCache::CACHE_TYPE_TMP },
65 // Cache resource that is dirty, to test a dirty file is in persistent dir
66 // with a symlink in outgoing dir referencing it.
67 { "account_metadata.json", "dirty:existing", "md5_dirty_existing",
68 test_util::TEST_CACHE_STATE_PRESENT |
69 test_util::TEST_CACHE_STATE_DIRTY |
70 test_util::TEST_CACHE_STATE_PERSISTENT,
71 "local", GDataCache::CACHE_TYPE_PERSISTENT },
72 // Cache resource that is pinned and dirty, to test a dirty pinned file is in
73 // persistent dir with symlink in pinned and outgoing dirs referencing it.
74 { "basic_feed.json", "dirty_and_pinned:existing",
75 "md5_dirty_and_pinned_existing",
76 test_util::TEST_CACHE_STATE_PRESENT |
77 test_util::TEST_CACHE_STATE_PINNED |
78 test_util::TEST_CACHE_STATE_DIRTY |
79 test_util::TEST_CACHE_STATE_PERSISTENT,
80 "local", GDataCache::CACHE_TYPE_PERSISTENT },
81 };
82
83 const int64 kLotsOfSpace = kMinFreeSpace * 10;
84
85 struct PathToVerify {
86 PathToVerify(const FilePath& in_path_to_scan,
87 const FilePath& in_expected_existing_path) :
88 path_to_scan(in_path_to_scan),
89 expected_existing_path(in_expected_existing_path) {
90 }
91
92 FilePath path_to_scan;
93 FilePath expected_existing_path;
94 };
95
96 class MockFreeDiskSpaceGetter : public FreeDiskSpaceGetterInterface {
97 public:
98 virtual ~MockFreeDiskSpaceGetter() {}
99 MOCK_CONST_METHOD0(AmountOfFreeDiskSpace, int64());
100 };
101
102 // Copies results from GetResourceIdsOfBacklogCallback.
103 void OnGetResourceIdsOfBacklog(std::vector<std::string>* out_to_fetch,
104 std::vector<std::string>* out_to_upload,
105 const std::vector<std::string>& to_fetch,
106 const std::vector<std::string>& to_upload) {
107 *out_to_fetch = to_fetch;
108 *out_to_upload = to_upload;
109 }
110
111 // Copies results from GetResourceIdsCallback.
112 void OnGetResourceIds(std::vector<std::string>* out_resource_ids,
113 const std::vector<std::string>& resource_ids) {
114 *out_resource_ids = resource_ids;
115 }
116
117 // Copies results from ClearAllOnUIThread.
118 void OnClearAll(GDataFileError* out_error,
119 FilePath* out_file_path,
120 GDataFileError error,
121 const FilePath& file_path) {
122 *out_file_path = file_path;
123 *out_error = error;
124 }
125
126 } // namespace
127
128 class GDataCacheTest : public testing::Test {
129 protected:
130 GDataCacheTest()
131 : ui_thread_(content::BrowserThread::UI, &message_loop_),
132 io_thread_(content::BrowserThread::IO),
133 cache_(NULL),
134 num_callback_invocations_(0),
135 expected_error_(GDATA_FILE_OK),
136 expected_cache_state_(0),
137 expected_sub_dir_type_(GDataCache::CACHE_TYPE_META),
138 expected_success_(true),
139 expect_outgoing_symlink_(false),
140 root_feed_changestamp_(0) {
141 }
142
143 virtual void SetUp() OVERRIDE {
144 io_thread_.StartIOThread();
145
146 profile_.reset(new TestingProfile);
147
148 mock_free_disk_space_checker_ = new MockFreeDiskSpaceGetter;
149 SetFreeDiskSpaceGetterForTesting(mock_free_disk_space_checker_);
150
151 scoped_refptr<base::SequencedWorkerPool> pool =
152 content::BrowserThread::GetBlockingPool();
153 blocking_task_runner_ =
154 pool->GetSequencedTaskRunner(pool->GetSequenceToken());
155 cache_ = GDataCache::CreateGDataCacheOnUIThread(
156 GDataCache::GetCacheRootPath(profile_.get()), blocking_task_runner_);
157
158 mock_cache_observer_.reset(new StrictMock<MockGDataCacheObserver>);
159 cache_->AddObserver(mock_cache_observer_.get());
160
161 cache_->RequestInitializeOnUIThread();
162 test_util::RunBlockingPoolTask();
163 }
164
165 virtual void TearDown() OVERRIDE {
166 SetFreeDiskSpaceGetterForTesting(NULL);
167 cache_->DestroyOnUIThread();
168 // The cache destruction requires to post a task to the blocking pool.
169 test_util::RunBlockingPoolTask();
170
171 profile_.reset(NULL);
172 }
173
174 void PrepareForInitCacheTest() {
175 DVLOG(1) << "PrepareForInitCacheTest start";
176 // Create gdata cache sub directories.
177 ASSERT_TRUE(file_util::CreateDirectory(
178 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_PERSISTENT)));
179 ASSERT_TRUE(file_util::CreateDirectory(
180 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_TMP)));
181 ASSERT_TRUE(file_util::CreateDirectory(
182 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_PINNED)));
183 ASSERT_TRUE(file_util::CreateDirectory(
184 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_OUTGOING)));
185
186 // Dump some files into cache dirs so that
187 // GDataFileSystem::InitializeCacheOnBlockingPool would scan through them
188 // and populate cache map accordingly.
189
190 // Copy files from data dir to cache dir to act as cached files.
191 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(initial_cache_resources); ++i) {
192 const struct InitialCacheResource& resource = initial_cache_resources[i];
193 // Determine gdata cache file absolute path according to cache state.
194 FilePath dest_path = cache_->GetCacheFilePath(
195 resource.resource_id,
196 resource.md5,
197 test_util::ToCacheEntry(resource.cache_state).is_pinned() ||
198 test_util::ToCacheEntry(resource.cache_state).is_dirty() ?
199 GDataCache::CACHE_TYPE_PERSISTENT :
200 GDataCache::CACHE_TYPE_TMP,
201 test_util::ToCacheEntry(resource.cache_state).is_dirty() ?
202 GDataCache::CACHED_FILE_LOCALLY_MODIFIED :
203 GDataCache::CACHED_FILE_FROM_SERVER);
204
205 // Copy file from data dir to cache subdir, naming it per cache files
206 // convention.
207 if (test_util::ToCacheEntry(resource.cache_state).is_present()) {
208 FilePath source_path = GetTestFilePath(resource.source_file);
209 ASSERT_TRUE(file_util::CopyFile(source_path, dest_path));
210 } else {
211 dest_path = FilePath(FILE_PATH_LITERAL(kSymLinkToDevNull));
212 }
213
214 // Create symbolic link in pinned dir, naming it per cache files
215 // convention.
216 if (test_util::ToCacheEntry(resource.cache_state).is_pinned()) {
217 FilePath link_path = cache_->GetCacheFilePath(
218 resource.resource_id,
219 "",
220 GDataCache::CACHE_TYPE_PINNED,
221 GDataCache::CACHED_FILE_FROM_SERVER);
222 ASSERT_TRUE(file_util::CreateSymbolicLink(dest_path, link_path));
223 }
224
225 // Create symbolic link in outgoing dir, naming it per cache files
226 // convention.
227 if (test_util::ToCacheEntry(resource.cache_state).is_dirty()) {
228 FilePath link_path = cache_->GetCacheFilePath(
229 resource.resource_id,
230 "",
231 GDataCache::CACHE_TYPE_OUTGOING,
232 GDataCache::CACHED_FILE_FROM_SERVER);
233 ASSERT_TRUE(file_util::CreateSymbolicLink(dest_path, link_path));
234 }
235 }
236
237 DVLOG(1) << "PrepareForInitCacheTest finished";
238 cache_->ForceRescanOnUIThreadForTesting();
239 test_util::RunBlockingPoolTask();
240 }
241
242 void TestInitializeCache() {
243 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(initial_cache_resources); ++i) {
244 const struct InitialCacheResource& resource = initial_cache_resources[i];
245 // Check cache file.
246 num_callback_invocations_ = 0;
247 TestGetFileFromCacheByResourceIdAndMd5(
248 resource.resource_id,
249 resource.md5,
250 test_util::ToCacheEntry(resource.cache_state).is_present() ?
251 GDATA_FILE_OK :
252 GDATA_FILE_ERROR_NOT_FOUND,
253 resource.expected_file_extension);
254 EXPECT_EQ(1, num_callback_invocations_);
255
256 // Verify cache state.
257 std::string md5;
258 if (test_util::ToCacheEntry(resource.cache_state).is_present())
259 md5 = resource.md5;
260 DriveCacheEntry cache_entry;
261 ASSERT_TRUE(GetCacheEntryFromOriginThread(
262 resource.resource_id, md5, &cache_entry));
263 EXPECT_TRUE(test_util::CacheStatesEqual(
264 test_util::ToCacheEntry(resource.cache_state),
265 cache_entry));
266 EXPECT_EQ(resource.expected_sub_dir_type,
267 GDataCache::GetSubDirectoryType(cache_entry));
268 }
269 }
270
271 void TestGetFileFromCacheByResourceIdAndMd5(
272 const std::string& resource_id,
273 const std::string& md5,
274 GDataFileError expected_error,
275 const std::string& expected_file_extension) {
276 expected_error_ = expected_error;
277 expected_file_extension_ = expected_file_extension;
278
279 cache_->GetFileOnUIThread(
280 resource_id, md5,
281 base::Bind(&GDataCacheTest::VerifyGetFromCache,
282 base::Unretained(this)));
283
284 test_util::RunBlockingPoolTask();
285 }
286
287 void TestStoreToCache(
288 const std::string& resource_id,
289 const std::string& md5,
290 const FilePath& source_path,
291 GDataFileError expected_error,
292 int expected_cache_state,
293 GDataCache::CacheSubDirectoryType expected_sub_dir_type) {
294 expected_error_ = expected_error;
295 expected_cache_state_ = expected_cache_state;
296 expected_sub_dir_type_ = expected_sub_dir_type;
297
298 cache_->StoreOnUIThread(
299 resource_id, md5, source_path,
300 GDataCache::FILE_OPERATION_COPY,
301 base::Bind(&GDataCacheTest::VerifyCacheFileState,
302 base::Unretained(this)));
303
304 test_util::RunBlockingPoolTask();
305 }
306
307 void VerifyGetFromCache(GDataFileError error,
308 const std::string& resource_id,
309 const std::string& md5,
310 const FilePath& cache_file_path) {
311 ++num_callback_invocations_;
312
313 EXPECT_EQ(expected_error_, error);
314
315 if (error == GDATA_FILE_OK) {
316 // Verify filename of |cache_file_path|.
317 FilePath base_name = cache_file_path.BaseName();
318 EXPECT_EQ(util::EscapeCacheFileName(resource_id) +
319 FilePath::kExtensionSeparator +
320 util::EscapeCacheFileName(
321 expected_file_extension_.empty() ?
322 md5 : expected_file_extension_),
323 base_name.value());
324 } else {
325 EXPECT_TRUE(cache_file_path.empty());
326 }
327 }
328
329 void TestRemoveFromCache(const std::string& resource_id,
330 GDataFileError expected_error) {
331 expected_error_ = expected_error;
332
333 cache_->RemoveOnUIThread(
334 resource_id,
335 base::Bind(&GDataCacheTest::VerifyRemoveFromCache,
336 base::Unretained(this)));
337
338 test_util::RunBlockingPoolTask();
339 }
340
341 void VerifyRemoveFromCache(GDataFileError error,
342 const std::string& resource_id,
343 const std::string& md5) {
344 ++num_callback_invocations_;
345
346 EXPECT_EQ(expected_error_, error);
347
348 // Verify cache map.
349 DriveCacheEntry cache_entry;
350 const bool cache_entry_found =
351 GetCacheEntryFromOriginThread(resource_id, md5, &cache_entry);
352 if (cache_entry_found)
353 EXPECT_TRUE(cache_entry.is_dirty());
354
355 // If entry doesn't exist, verify that:
356 // - no files with "<resource_id>.* exists in persistent and tmp dirs
357 // - no "<resource_id>" symlink exists in pinned and outgoing dirs.
358 std::vector<PathToVerify> paths_to_verify;
359 paths_to_verify.push_back( // Index 0: CACHE_TYPE_TMP.
360 PathToVerify(cache_->GetCacheFilePath(resource_id, "*",
361 GDataCache::CACHE_TYPE_TMP,
362 GDataCache::CACHED_FILE_FROM_SERVER), FilePath()));
363 paths_to_verify.push_back( // Index 1: CACHE_TYPE_PERSISTENT.
364 PathToVerify(cache_->GetCacheFilePath(resource_id, "*",
365 GDataCache::CACHE_TYPE_PERSISTENT,
366 GDataCache::CACHED_FILE_FROM_SERVER), FilePath()));
367 paths_to_verify.push_back( // Index 2: CACHE_TYPE_TMP, but STATE_PINNED.
368 PathToVerify(cache_->GetCacheFilePath(resource_id, "",
369 GDataCache::CACHE_TYPE_PINNED,
370 GDataCache::CACHED_FILE_FROM_SERVER), FilePath()));
371 paths_to_verify.push_back( // Index 3: CACHE_TYPE_OUTGOING.
372 PathToVerify(cache_->GetCacheFilePath(resource_id, "",
373 GDataCache::CACHE_TYPE_OUTGOING,
374 GDataCache::CACHED_FILE_FROM_SERVER), FilePath()));
375 if (!cache_entry_found) {
376 for (size_t i = 0; i < paths_to_verify.size(); ++i) {
377 file_util::FileEnumerator enumerator(
378 paths_to_verify[i].path_to_scan.DirName(), false /* not recursive*/,
379 file_util::FileEnumerator::FILES |
380 file_util::FileEnumerator::SHOW_SYM_LINKS,
381 paths_to_verify[i].path_to_scan.BaseName().value());
382 EXPECT_TRUE(enumerator.Next().empty());
383 }
384 } else {
385 // Entry is dirty, verify that:
386 // - no files with "<resource_id>.*" exist in tmp dir
387 // - only 1 "<resource_id>.local" exists in persistent dir
388 // - only 1 <resource_id> exists in outgoing dir
389 // - if entry is pinned, only 1 <resource_id> exists in pinned dir.
390
391 // Change expected_existing_path of CACHE_TYPE_PERSISTENT (index 1).
392 paths_to_verify[1].expected_existing_path =
393 GetCacheFilePath(resource_id,
394 std::string(),
395 GDataCache::CACHE_TYPE_PERSISTENT,
396 GDataCache::CACHED_FILE_LOCALLY_MODIFIED);
397
398 // Change expected_existing_path of CACHE_TYPE_OUTGOING (index 3).
399 paths_to_verify[3].expected_existing_path =
400 GetCacheFilePath(resource_id,
401 std::string(),
402 GDataCache::CACHE_TYPE_OUTGOING,
403 GDataCache::CACHED_FILE_FROM_SERVER);
404
405 if (cache_entry.is_pinned()) {
406 // Change expected_existing_path of CACHE_TYPE_TMP but STATE_PINNED
407 // (index 2).
408 paths_to_verify[2].expected_existing_path =
409 GetCacheFilePath(resource_id,
410 std::string(),
411 GDataCache::CACHE_TYPE_PINNED,
412 GDataCache::CACHED_FILE_FROM_SERVER);
413 }
414
415 for (size_t i = 0; i < paths_to_verify.size(); ++i) {
416 const struct PathToVerify& verify = paths_to_verify[i];
417 file_util::FileEnumerator enumerator(
418 verify.path_to_scan.DirName(), false /* not recursive */,
419 file_util::FileEnumerator::FILES |
420 file_util::FileEnumerator::SHOW_SYM_LINKS,
421 verify.path_to_scan.BaseName().value());
422 size_t num_files_found = 0;
423 for (FilePath current = enumerator.Next(); !current.empty();
424 current = enumerator.Next()) {
425 ++num_files_found;
426 EXPECT_EQ(verify.expected_existing_path, current);
427 }
428 if (verify.expected_existing_path.empty())
429 EXPECT_EQ(0U, num_files_found);
430 else
431 EXPECT_EQ(1U, num_files_found);
432 }
433 }
434 }
435
436 void TestPin(
437 const std::string& resource_id,
438 const std::string& md5,
439 GDataFileError expected_error,
440 int expected_cache_state,
441 GDataCache::CacheSubDirectoryType expected_sub_dir_type) {
442 expected_error_ = expected_error;
443 expected_cache_state_ = expected_cache_state;
444 expected_sub_dir_type_ = expected_sub_dir_type;
445
446 cache_->PinOnUIThread(
447 resource_id, md5,
448 base::Bind(&GDataCacheTest::VerifyCacheFileState,
449 base::Unretained(this)));
450
451 test_util::RunBlockingPoolTask();
452 }
453
454 void TestUnpin(
455 const std::string& resource_id,
456 const std::string& md5,
457 GDataFileError expected_error,
458 int expected_cache_state,
459 GDataCache::CacheSubDirectoryType expected_sub_dir_type) {
460 expected_error_ = expected_error;
461 expected_cache_state_ = expected_cache_state;
462 expected_sub_dir_type_ = expected_sub_dir_type;
463
464 cache_->UnpinOnUIThread(
465 resource_id, md5,
466 base::Bind(&GDataCacheTest::VerifyCacheFileState,
467 base::Unretained(this)));
468
469 test_util::RunBlockingPoolTask();
470 }
471
472 void TestMarkDirty(
473 const std::string& resource_id,
474 const std::string& md5,
475 GDataFileError expected_error,
476 int expected_cache_state,
477 GDataCache::CacheSubDirectoryType expected_sub_dir_type) {
478 expected_error_ = expected_error;
479 expected_cache_state_ = expected_cache_state;
480 expected_sub_dir_type_ = expected_sub_dir_type;
481 expect_outgoing_symlink_ = false;
482
483 cache_->MarkDirtyOnUIThread(
484 resource_id, md5,
485 base::Bind(&GDataCacheTest::VerifyMarkDirty,
486 base::Unretained(this)));
487
488 test_util::RunBlockingPoolTask();
489 }
490
491 void VerifyMarkDirty(GDataFileError error,
492 const std::string& resource_id,
493 const std::string& md5,
494 const FilePath& cache_file_path) {
495 VerifyCacheFileState(error, resource_id, md5);
496
497 // Verify filename of |cache_file_path|.
498 if (error == GDATA_FILE_OK) {
499 FilePath base_name = cache_file_path.BaseName();
500 EXPECT_EQ(util::EscapeCacheFileName(resource_id) +
501 FilePath::kExtensionSeparator +
502 "local",
503 base_name.value());
504 } else {
505 EXPECT_TRUE(cache_file_path.empty());
506 }
507 }
508
509 void TestCommitDirty(
510 const std::string& resource_id,
511 const std::string& md5,
512 GDataFileError expected_error,
513 int expected_cache_state,
514 GDataCache::CacheSubDirectoryType expected_sub_dir_type) {
515 expected_error_ = expected_error;
516 expected_cache_state_ = expected_cache_state;
517 expected_sub_dir_type_ = expected_sub_dir_type;
518 expect_outgoing_symlink_ = true;
519
520 cache_->CommitDirtyOnUIThread(
521 resource_id, md5,
522 base::Bind(&GDataCacheTest::VerifyCacheFileState,
523 base::Unretained(this)));
524
525 test_util::RunBlockingPoolTask();
526 }
527
528 void TestClearDirty(
529 const std::string& resource_id,
530 const std::string& md5,
531 GDataFileError expected_error,
532 int expected_cache_state,
533 GDataCache::CacheSubDirectoryType expected_sub_dir_type) {
534 expected_error_ = expected_error;
535 expected_cache_state_ = expected_cache_state;
536 expected_sub_dir_type_ = expected_sub_dir_type;
537 expect_outgoing_symlink_ = false;
538
539 cache_->ClearDirtyOnUIThread(resource_id, md5,
540 base::Bind(&GDataCacheTest::VerifyCacheFileState,
541 base::Unretained(this)));
542
543 test_util::RunBlockingPoolTask();
544 }
545
546 void TestSetMountedState(
547 const std::string& resource_id,
548 const std::string& md5,
549 const FilePath& file_path,
550 bool to_mount,
551 GDataFileError expected_error,
552 int expected_cache_state,
553 GDataCache::CacheSubDirectoryType expected_sub_dir_type) {
554 expected_error_ = expected_error;
555 expected_cache_state_ = expected_cache_state;
556 expected_sub_dir_type_ = expected_sub_dir_type;
557 expect_outgoing_symlink_ = false;
558
559 cache_->SetMountedStateOnUIThread(file_path, to_mount,
560 base::Bind(&GDataCacheTest::VerifySetMountedState,
561 base::Unretained(this), resource_id, md5, to_mount));
562
563 test_util::RunBlockingPoolTask();
564 }
565
566 void VerifySetMountedState(const std::string& resource_id,
567 const std::string& md5,
568 bool to_mount,
569 GDataFileError error,
570 const FilePath& file_path) {
571 ++num_callback_invocations_;
572 EXPECT_TRUE(file_util::PathExists(file_path));
573 EXPECT_TRUE(file_path == cache_->GetCacheFilePath(
574 resource_id,
575 md5,
576 expected_sub_dir_type_,
577 to_mount ?
578 GDataCache::CACHED_FILE_MOUNTED :
579 GDataCache::CACHED_FILE_FROM_SERVER));
580 }
581
582 void VerifyCacheFileState(GDataFileError error,
583 const std::string& resource_id,
584 const std::string& md5) {
585 ++num_callback_invocations_;
586
587 EXPECT_EQ(expected_error_, error);
588
589 // Verify cache map.
590 DriveCacheEntry cache_entry;
591 const bool cache_entry_found =
592 GetCacheEntryFromOriginThread(resource_id, md5, &cache_entry);
593 if (test_util::ToCacheEntry(expected_cache_state_).is_present() ||
594 test_util::ToCacheEntry(expected_cache_state_).is_pinned()) {
595 ASSERT_TRUE(cache_entry_found);
596 EXPECT_TRUE(test_util::CacheStatesEqual(
597 test_util::ToCacheEntry(expected_cache_state_),
598 cache_entry));
599 EXPECT_EQ(expected_sub_dir_type_,
600 GDataCache::GetSubDirectoryType(cache_entry));
601 } else {
602 EXPECT_FALSE(cache_entry_found);
603 }
604
605 // Verify actual cache file.
606 FilePath dest_path = cache_->GetCacheFilePath(
607 resource_id,
608 md5,
609 test_util::ToCacheEntry(expected_cache_state_).is_pinned() ||
610 test_util::ToCacheEntry(expected_cache_state_).is_dirty() ?
611 GDataCache::CACHE_TYPE_PERSISTENT :
612 GDataCache::CACHE_TYPE_TMP,
613 test_util::ToCacheEntry(expected_cache_state_).is_dirty() ?
614 GDataCache::CACHED_FILE_LOCALLY_MODIFIED :
615 GDataCache::CACHED_FILE_FROM_SERVER);
616 bool exists = file_util::PathExists(dest_path);
617 if (test_util::ToCacheEntry(expected_cache_state_).is_present())
618 EXPECT_TRUE(exists);
619 else
620 EXPECT_FALSE(exists);
621
622 // Verify symlink in pinned dir.
623 FilePath symlink_path = cache_->GetCacheFilePath(
624 resource_id,
625 std::string(),
626 GDataCache::CACHE_TYPE_PINNED,
627 GDataCache::CACHED_FILE_FROM_SERVER);
628 // Check that pin symlink exists, without deferencing to target path.
629 exists = file_util::IsLink(symlink_path);
630 if (test_util::ToCacheEntry(expected_cache_state_).is_pinned()) {
631 EXPECT_TRUE(exists);
632 FilePath target_path;
633 EXPECT_TRUE(file_util::ReadSymbolicLink(symlink_path, &target_path));
634 if (test_util::ToCacheEntry(expected_cache_state_).is_present())
635 EXPECT_EQ(dest_path, target_path);
636 else
637 EXPECT_EQ(kSymLinkToDevNull, target_path.value());
638 } else {
639 EXPECT_FALSE(exists);
640 }
641
642 // Verify symlink in outgoing dir.
643 symlink_path = cache_->GetCacheFilePath(
644 resource_id,
645 std::string(),
646 GDataCache::CACHE_TYPE_OUTGOING,
647 GDataCache::CACHED_FILE_FROM_SERVER);
648 // Check that outgoing symlink exists, without deferencing to target path.
649 exists = file_util::IsLink(symlink_path);
650 if (expect_outgoing_symlink_ &&
651 test_util::ToCacheEntry(expected_cache_state_).is_dirty()) {
652 EXPECT_TRUE(exists);
653 FilePath target_path;
654 EXPECT_TRUE(file_util::ReadSymbolicLink(symlink_path, &target_path));
655 EXPECT_TRUE(target_path.value() != kSymLinkToDevNull);
656 if (test_util::ToCacheEntry(expected_cache_state_).is_present())
657 EXPECT_EQ(dest_path, target_path);
658 } else {
659 EXPECT_FALSE(exists);
660 }
661 }
662
663 FilePath GetCacheFilePath(const std::string& resource_id,
664 const std::string& md5,
665 GDataCache::CacheSubDirectoryType sub_dir_type,
666 GDataCache::CachedFileOrigin file_origin) {
667 return cache_->GetCacheFilePath(resource_id, md5, sub_dir_type,
668 file_origin);
669 }
670
671 // Helper function to call GetCacheEntry from origin thread.
672 bool GetCacheEntryFromOriginThread(const std::string& resource_id,
673 const std::string& md5,
674 DriveCacheEntry* cache_entry) {
675 bool result = false;
676 blocking_task_runner_->PostTask(
677 FROM_HERE,
678 base::Bind(&GDataCacheTest::GetCacheEntryFromOriginThreadInternal,
679 base::Unretained(this),
680 resource_id,
681 md5,
682 cache_entry,
683 &result));
684 test_util::RunBlockingPoolTask();
685 return result;
686 }
687
688 // Used to implement GetCacheEntry.
689 void GetCacheEntryFromOriginThreadInternal(
690 const std::string& resource_id,
691 const std::string& md5,
692 DriveCacheEntry* cache_entry,
693 bool* result) {
694 *result = cache_->GetCacheEntry(resource_id, md5, cache_entry);
695 }
696
697 // Returns true if the cache entry exists for the given resource ID and MD5.
698 bool CacheEntryExists(const std::string& resource_id,
699 const std::string& md5) {
700 DriveCacheEntry cache_entry;
701 return GetCacheEntryFromOriginThread(resource_id, md5, &cache_entry);
702 }
703
704 void TestGetCacheFilePath(const std::string& resource_id,
705 const std::string& md5,
706 const std::string& expected_filename) {
707 FilePath actual_path = cache_->GetCacheFilePath(
708 resource_id,
709 md5,
710 GDataCache::CACHE_TYPE_TMP,
711 GDataCache::CACHED_FILE_FROM_SERVER);
712 FilePath expected_path =
713 cache_->GetCacheDirectoryPath(GDataCache::CACHE_TYPE_TMP);
714 expected_path = expected_path.Append(expected_filename);
715 EXPECT_EQ(expected_path, actual_path);
716
717 FilePath base_name = actual_path.BaseName();
718
719 // FilePath::Extension returns ".", so strip it.
720 std::string unescaped_md5 = util::UnescapeCacheFileName(
721 base_name.Extension().substr(1));
722 EXPECT_EQ(md5, unescaped_md5);
723 std::string unescaped_resource_id = util::UnescapeCacheFileName(
724 base_name.RemoveExtension().value());
725 EXPECT_EQ(resource_id, unescaped_resource_id);
726 }
727
728 // Returns the number of the cache files with name <resource_id>, and Confirm
729 // that they have the <md5>. This should return 1 or 0.
730 size_t CountCacheFiles(const std::string& resource_id,
731 const std::string& md5) {
732 FilePath path = GetCacheFilePath(
733 resource_id, "*",
734 (test_util::ToCacheEntry(expected_cache_state_).is_pinned() ?
735 GDataCache::CACHE_TYPE_PERSISTENT :
736 GDataCache::CACHE_TYPE_TMP),
737 GDataCache::CACHED_FILE_FROM_SERVER);
738 file_util::FileEnumerator enumerator(path.DirName(), false,
739 file_util::FileEnumerator::FILES,
740 path.BaseName().value());
741 size_t num_files_found = 0;
742 for (FilePath current = enumerator.Next(); !current.empty();
743 current = enumerator.Next()) {
744 ++num_files_found;
745 EXPECT_EQ(util::EscapeCacheFileName(resource_id) +
746 FilePath::kExtensionSeparator +
747 util::EscapeCacheFileName(md5),
748 current.BaseName().value());
749 }
750 return num_files_found;
751 }
752
753 static FilePath GetTestFilePath(const FilePath::StringType& filename) {
754 FilePath path;
755 std::string error;
756 PathService::Get(chrome::DIR_TEST_DATA, &path);
757 path = path.AppendASCII("chromeos")
758 .AppendASCII("gdata")
759 .AppendASCII(filename.c_str());
760 EXPECT_TRUE(file_util::PathExists(path)) <<
761 "Couldn't find " << path.value();
762 return path;
763 }
764
765 MessageLoopForUI message_loop_;
766 // The order of the test threads is important, do not change the order.
767 // See also content/browser/browser_thread_imple.cc.
768 content::TestBrowserThread ui_thread_;
769 content::TestBrowserThread io_thread_;
770 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
771 scoped_ptr<TestingProfile> profile_;
772 GDataCache* cache_;
773 MockFreeDiskSpaceGetter* mock_free_disk_space_checker_;
774 scoped_ptr<StrictMock<MockGDataCacheObserver> > mock_cache_observer_;
775
776 int num_callback_invocations_;
777 GDataFileError expected_error_;
778 int expected_cache_state_;
779 GDataCache::CacheSubDirectoryType expected_sub_dir_type_;
780 bool expected_success_;
781 bool expect_outgoing_symlink_;
782 std::string expected_file_extension_;
783 int root_feed_changestamp_;
784 };
785
786 TEST_F(GDataCacheTest, InitializeCache) {
787 PrepareForInitCacheTest();
788 TestInitializeCache();
789 }
790
791 TEST_F(GDataCacheTest, GetCacheFilePath) {
792 // Use alphanumeric characters for resource id.
793 std::string resource_id("pdf:1a2b");
794 std::string md5("abcdef0123456789");
795 TestGetCacheFilePath(resource_id, md5,
796 resource_id + FilePath::kExtensionSeparator + md5);
797 EXPECT_EQ(0, num_callback_invocations_);
798
799 // Use non-alphanumeric characters for resource id, including '.' which is an
800 // extension separator, to test that the characters are escaped and unescaped
801 // correctly, and '.' doesn't mess up the filename format and operations.
802 resource_id = "pdf:`~!@#$%^&*()-_=+[{|]}\\;',<.>/?";
803 std::string escaped_resource_id = util::EscapeCacheFileName(resource_id);
804 std::string escaped_md5 = util::EscapeCacheFileName(md5);
805 num_callback_invocations_ = 0;
806 TestGetCacheFilePath(resource_id, md5,
807 escaped_resource_id + FilePath::kExtensionSeparator +
808 escaped_md5);
809 EXPECT_EQ(0, num_callback_invocations_);
810 }
811
812 TEST_F(GDataCacheTest, StoreToCacheSimple) {
813 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
814 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
815
816 std::string resource_id("pdf:1a2b");
817 std::string md5("abcdef0123456789");
818
819 // Store an existing file.
820 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
821 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
822 GDataCache::CACHE_TYPE_TMP);
823 EXPECT_EQ(1, num_callback_invocations_);
824
825 // Store a non-existent file to the same |resource_id| and |md5|.
826 num_callback_invocations_ = 0;
827 TestStoreToCache(resource_id, md5, FilePath("./non_existent.json"),
828 GDATA_FILE_ERROR_FAILED,
829 test_util::TEST_CACHE_STATE_PRESENT,
830 GDataCache::CACHE_TYPE_TMP);
831 EXPECT_EQ(1, num_callback_invocations_);
832
833 // Store a different existing file to the same |resource_id| but different
834 // |md5|.
835 md5 = "new_md5";
836 num_callback_invocations_ = 0;
837 TestStoreToCache(resource_id, md5, GetTestFilePath("subdir_feed.json"),
838 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
839 GDataCache::CACHE_TYPE_TMP);
840 EXPECT_EQ(1, num_callback_invocations_);
841
842 // Verify that there's only one file with name <resource_id>, i.e. previously
843 // cached file with the different md5 should be deleted.
844 EXPECT_EQ(1U, CountCacheFiles(resource_id, md5));
845 }
846
847 TEST_F(GDataCacheTest, GetFromCacheSimple) {
848 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
849 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
850
851 std::string resource_id("pdf:1a2b");
852 std::string md5("abcdef0123456789");
853 // First store a file to cache.
854 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
855 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
856 GDataCache::CACHE_TYPE_TMP);
857
858 // Then try to get the existing file from cache.
859 num_callback_invocations_ = 0;
860 TestGetFileFromCacheByResourceIdAndMd5(
861 resource_id, md5, GDATA_FILE_OK, md5);
862 EXPECT_EQ(1, num_callback_invocations_);
863
864 // Get file from cache with same resource id as existing file but different
865 // md5.
866 num_callback_invocations_ = 0;
867 TestGetFileFromCacheByResourceIdAndMd5(
868 resource_id, "9999", GDATA_FILE_ERROR_NOT_FOUND, md5);
869 EXPECT_EQ(1, num_callback_invocations_);
870
871 // Get file from cache with different resource id from existing file but same
872 // md5.
873 num_callback_invocations_ = 0;
874 resource_id = "document:1a2b";
875 TestGetFileFromCacheByResourceIdAndMd5(
876 resource_id, md5, GDATA_FILE_ERROR_NOT_FOUND, md5);
877 EXPECT_EQ(1, num_callback_invocations_);
878 }
879
880 TEST_F(GDataCacheTest, RemoveFromCacheSimple) {
881 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
882 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
883
884 // Use alphanumeric characters for resource id.
885 std::string resource_id("pdf:1a2b");
886 std::string md5("abcdef0123456789");
887 // First store a file to cache.
888 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
889 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
890 GDataCache::CACHE_TYPE_TMP);
891
892 // Then try to remove existing file from cache.
893 num_callback_invocations_ = 0;
894 TestRemoveFromCache(resource_id, GDATA_FILE_OK);
895 EXPECT_EQ(1, num_callback_invocations_);
896
897 // Repeat using non-alphanumeric characters for resource id, including '.'
898 // which is an extension separator.
899 resource_id = "pdf:`~!@#$%^&*()-_=+[{|]}\\;',<.>/?";
900 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
901 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
902 GDataCache::CACHE_TYPE_TMP);
903
904 num_callback_invocations_ = 0;
905 TestRemoveFromCache(resource_id, GDATA_FILE_OK);
906 EXPECT_EQ(1, num_callback_invocations_);
907 }
908
909 TEST_F(GDataCacheTest, PinAndUnpin) {
910 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
911 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
912
913 std::string resource_id("pdf:1a2b");
914 std::string md5("abcdef0123456789");
915 EXPECT_CALL(*mock_cache_observer_, OnCachePinned(resource_id, md5)).Times(2);
916 EXPECT_CALL(*mock_cache_observer_, OnCacheUnpinned(resource_id, md5))
917 .Times(1);
918
919 // First store a file to cache.
920 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
921 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
922 GDataCache::CACHE_TYPE_TMP);
923
924 // Pin the existing file in cache.
925 num_callback_invocations_ = 0;
926 TestPin(resource_id, md5, GDATA_FILE_OK,
927 test_util::TEST_CACHE_STATE_PRESENT |
928 test_util::TEST_CACHE_STATE_PINNED |
929 test_util::TEST_CACHE_STATE_PERSISTENT,
930 GDataCache::CACHE_TYPE_PERSISTENT);
931 EXPECT_EQ(1, num_callback_invocations_);
932
933 // Unpin the existing file in cache.
934 num_callback_invocations_ = 0;
935 TestUnpin(resource_id, md5, GDATA_FILE_OK,
936 test_util::TEST_CACHE_STATE_PRESENT,
937 GDataCache::CACHE_TYPE_TMP);
938 EXPECT_EQ(1, num_callback_invocations_);
939
940 // Pin back the same existing file in cache.
941 num_callback_invocations_ = 0;
942 TestPin(resource_id, md5, GDATA_FILE_OK,
943 test_util::TEST_CACHE_STATE_PRESENT |
944 test_util::TEST_CACHE_STATE_PINNED |
945 test_util::TEST_CACHE_STATE_PERSISTENT,
946 GDataCache::CACHE_TYPE_PERSISTENT);
947 EXPECT_EQ(1, num_callback_invocations_);
948
949 // Pin a non-existent file in cache.
950 resource_id = "document:1a2b";
951 EXPECT_CALL(*mock_cache_observer_, OnCachePinned(resource_id, md5)).Times(1);
952 EXPECT_CALL(*mock_cache_observer_, OnCacheUnpinned(resource_id, md5))
953 .Times(1);
954
955 num_callback_invocations_ = 0;
956 TestPin(resource_id, md5, GDATA_FILE_OK,
957 test_util::TEST_CACHE_STATE_PINNED,
958 GDataCache::CACHE_TYPE_TMP);
959 EXPECT_EQ(1, num_callback_invocations_);
960
961 // Unpin the previously pinned non-existent file in cache.
962 num_callback_invocations_ = 0;
963 TestUnpin(resource_id, md5, GDATA_FILE_OK,
964 test_util::TEST_CACHE_STATE_NONE,
965 GDataCache::CACHE_TYPE_TMP);
966 EXPECT_EQ(1, num_callback_invocations_);
967
968 // Unpin a file that doesn't exist in cache and is not pinned, i.e. cache
969 // has zero knowledge of the file.
970 resource_id = "not-in-cache:1a2b";
971 // Because unpinning will fail, OnCacheUnpinned() won't be run.
972 EXPECT_CALL(*mock_cache_observer_, OnCacheUnpinned(resource_id, md5))
973 .Times(0);
974
975 num_callback_invocations_ = 0;
976 TestUnpin(resource_id, md5, GDATA_FILE_ERROR_NOT_FOUND,
977 test_util::TEST_CACHE_STATE_NONE,
978 GDataCache::CACHE_TYPE_TMP /* non-applicable */);
979 EXPECT_EQ(1, num_callback_invocations_);
980 }
981
982 TEST_F(GDataCacheTest, StoreToCachePinned) {
983 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
984 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
985
986 std::string resource_id("pdf:1a2b");
987 std::string md5("abcdef0123456789");
988 EXPECT_CALL(*mock_cache_observer_, OnCachePinned(resource_id, md5)).Times(1);
989
990 // Pin a non-existent file.
991 TestPin(resource_id, md5, GDATA_FILE_OK,
992 test_util::TEST_CACHE_STATE_PINNED,
993 GDataCache::CACHE_TYPE_TMP);
994
995 // Store an existing file to a previously pinned file.
996 num_callback_invocations_ = 0;
997 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
998 GDATA_FILE_OK,
999 test_util::TEST_CACHE_STATE_PRESENT |
1000 test_util::TEST_CACHE_STATE_PINNED |
1001 test_util::TEST_CACHE_STATE_PERSISTENT,
1002 GDataCache::CACHE_TYPE_PERSISTENT);
1003 EXPECT_EQ(1, num_callback_invocations_);
1004
1005 // Store a non-existent file to a previously pinned and stored file.
1006 num_callback_invocations_ = 0;
1007 TestStoreToCache(resource_id, md5, FilePath("./non_existent.json"),
1008 GDATA_FILE_ERROR_FAILED,
1009 test_util::TEST_CACHE_STATE_PRESENT |
1010 test_util::TEST_CACHE_STATE_PINNED |
1011 test_util::TEST_CACHE_STATE_PERSISTENT,
1012 GDataCache::CACHE_TYPE_PERSISTENT);
1013 EXPECT_EQ(1, num_callback_invocations_);
1014 }
1015
1016 TEST_F(GDataCacheTest, GetFromCachePinned) {
1017 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1018 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
1019
1020 std::string resource_id("pdf:1a2b");
1021 std::string md5("abcdef0123456789");
1022 EXPECT_CALL(*mock_cache_observer_, OnCachePinned(resource_id, md5)).Times(1);
1023
1024 // Pin a non-existent file.
1025 TestPin(resource_id, md5, GDATA_FILE_OK,
1026 test_util::TEST_CACHE_STATE_PINNED,
1027 GDataCache::CACHE_TYPE_TMP);
1028
1029 // Get the non-existent pinned file from cache.
1030 num_callback_invocations_ = 0;
1031 TestGetFileFromCacheByResourceIdAndMd5(
1032 resource_id, md5, GDATA_FILE_ERROR_NOT_FOUND, md5);
1033 EXPECT_EQ(1, num_callback_invocations_);
1034
1035 // Store an existing file to the previously pinned non-existent file.
1036 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1037 GDATA_FILE_OK,
1038 test_util::TEST_CACHE_STATE_PRESENT |
1039 test_util::TEST_CACHE_STATE_PINNED |
1040 test_util::TEST_CACHE_STATE_PERSISTENT,
1041 GDataCache::CACHE_TYPE_PERSISTENT);
1042
1043 // Get the previously pinned and stored file from cache.
1044 num_callback_invocations_ = 0;
1045 TestGetFileFromCacheByResourceIdAndMd5(
1046 resource_id, md5, GDATA_FILE_OK, md5);
1047 EXPECT_EQ(1, num_callback_invocations_);
1048 }
1049
1050 TEST_F(GDataCacheTest, RemoveFromCachePinned) {
1051 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1052 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
1053
1054 // Use alphanumeric characters for resource_id.
1055 std::string resource_id("pdf:1a2b");
1056 std::string md5("abcdef0123456789");
1057 EXPECT_CALL(*mock_cache_observer_, OnCachePinned(resource_id, md5)).Times(1);
1058
1059 // Store a file to cache, and pin it.
1060 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1061 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
1062 GDataCache::CACHE_TYPE_TMP);
1063 TestPin(resource_id, md5, GDATA_FILE_OK,
1064 test_util::TEST_CACHE_STATE_PRESENT |
1065 test_util::TEST_CACHE_STATE_PINNED |
1066 test_util::TEST_CACHE_STATE_PERSISTENT,
1067 GDataCache::CACHE_TYPE_PERSISTENT);
1068
1069 // Remove |resource_id| from cache.
1070 num_callback_invocations_ = 0;
1071 TestRemoveFromCache(resource_id, GDATA_FILE_OK);
1072 EXPECT_EQ(1, num_callback_invocations_);
1073
1074 // Repeat using non-alphanumeric characters for resource id, including '.'
1075 // which is an extension separator.
1076 resource_id = "pdf:`~!@#$%^&*()-_=+[{|]}\\;',<.>/?";
1077 EXPECT_CALL(*mock_cache_observer_, OnCachePinned(resource_id, md5)).Times(1);
1078
1079 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1080 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
1081 GDataCache::CACHE_TYPE_TMP);
1082 TestPin(resource_id, md5, GDATA_FILE_OK,
1083 test_util::TEST_CACHE_STATE_PRESENT |
1084 test_util::TEST_CACHE_STATE_PINNED |
1085 test_util::TEST_CACHE_STATE_PERSISTENT,
1086 GDataCache::CACHE_TYPE_PERSISTENT);
1087
1088 num_callback_invocations_ = 0;
1089 TestRemoveFromCache(resource_id, GDATA_FILE_OK);
1090 EXPECT_EQ(1, num_callback_invocations_);
1091 }
1092
1093 TEST_F(GDataCacheTest, DirtyCacheSimple) {
1094 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1095 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
1096
1097 std::string resource_id("pdf:1a2b");
1098 std::string md5("abcdef0123456789");
1099 EXPECT_CALL(*mock_cache_observer_, OnCacheCommitted(resource_id)).Times(1);
1100
1101 // First store a file to cache.
1102 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1103 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
1104 GDataCache::CACHE_TYPE_TMP);
1105
1106 // Mark the file dirty.
1107 num_callback_invocations_ = 0;
1108 TestMarkDirty(resource_id, md5, GDATA_FILE_OK,
1109 test_util::TEST_CACHE_STATE_PRESENT |
1110 test_util::TEST_CACHE_STATE_DIRTY |
1111 test_util::TEST_CACHE_STATE_PERSISTENT,
1112 GDataCache::CACHE_TYPE_PERSISTENT);
1113 EXPECT_EQ(1, num_callback_invocations_);
1114
1115 // Commit the file dirty.
1116 num_callback_invocations_ = 0;
1117 TestCommitDirty(resource_id, md5, GDATA_FILE_OK,
1118 test_util::TEST_CACHE_STATE_PRESENT |
1119 test_util::TEST_CACHE_STATE_DIRTY |
1120 test_util::TEST_CACHE_STATE_PERSISTENT,
1121 GDataCache::CACHE_TYPE_PERSISTENT);
1122 EXPECT_EQ(1, num_callback_invocations_);
1123
1124 // Clear dirty state of the file.
1125 num_callback_invocations_ = 0;
1126 TestClearDirty(resource_id, md5, GDATA_FILE_OK,
1127 test_util::TEST_CACHE_STATE_PRESENT,
1128 GDataCache::CACHE_TYPE_TMP);
1129 EXPECT_EQ(1, num_callback_invocations_);
1130 }
1131
1132 TEST_F(GDataCacheTest, DirtyCachePinned) {
1133 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1134 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
1135
1136 std::string resource_id("pdf:1a2b");
1137 std::string md5("abcdef0123456789");
1138 EXPECT_CALL(*mock_cache_observer_, OnCachePinned(resource_id, md5)).Times(1);
1139 EXPECT_CALL(*mock_cache_observer_, OnCacheCommitted(resource_id)).Times(1);
1140
1141 // First store a file to cache and pin it.
1142 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1143 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
1144 GDataCache::CACHE_TYPE_TMP);
1145 TestPin(resource_id, md5, GDATA_FILE_OK,
1146 test_util::TEST_CACHE_STATE_PRESENT |
1147 test_util::TEST_CACHE_STATE_PINNED |
1148 test_util::TEST_CACHE_STATE_PERSISTENT,
1149 GDataCache::CACHE_TYPE_PERSISTENT);
1150
1151 // Mark the file dirty.
1152 num_callback_invocations_ = 0;
1153 TestMarkDirty(resource_id, md5, GDATA_FILE_OK,
1154 test_util::TEST_CACHE_STATE_PRESENT |
1155 test_util::TEST_CACHE_STATE_DIRTY |
1156 test_util::TEST_CACHE_STATE_PINNED |
1157 test_util::TEST_CACHE_STATE_PERSISTENT,
1158 GDataCache::CACHE_TYPE_PERSISTENT);
1159 EXPECT_EQ(1, num_callback_invocations_);
1160
1161 // Commit the file dirty.
1162 num_callback_invocations_ = 0;
1163 TestCommitDirty(resource_id, md5, GDATA_FILE_OK,
1164 test_util::TEST_CACHE_STATE_PRESENT |
1165 test_util::TEST_CACHE_STATE_DIRTY |
1166 test_util::TEST_CACHE_STATE_PINNED |
1167 test_util::TEST_CACHE_STATE_PERSISTENT,
1168 GDataCache::CACHE_TYPE_PERSISTENT);
1169 EXPECT_EQ(1, num_callback_invocations_);
1170
1171 // Clear dirty state of the file.
1172 num_callback_invocations_ = 0;
1173 TestClearDirty(resource_id, md5, GDATA_FILE_OK,
1174 test_util::TEST_CACHE_STATE_PRESENT |
1175 test_util::TEST_CACHE_STATE_PINNED |
1176 test_util::TEST_CACHE_STATE_PERSISTENT,
1177 GDataCache::CACHE_TYPE_PERSISTENT);
1178 EXPECT_EQ(1, num_callback_invocations_);
1179 }
1180
1181 // Test is disabled because it is flaky (http://crbug.com/134146)
1182 TEST_F(GDataCacheTest, PinAndUnpinDirtyCache) {
1183 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1184 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
1185
1186 std::string resource_id("pdf:1a2b");
1187 std::string md5("abcdef0123456789");
1188 EXPECT_CALL(*mock_cache_observer_, OnCachePinned(resource_id, md5)).Times(1);
1189 EXPECT_CALL(*mock_cache_observer_, OnCacheUnpinned(resource_id, md5))
1190 .Times(1);
1191
1192 // First store a file to cache and mark it as dirty.
1193 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1194 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
1195 GDataCache::CACHE_TYPE_TMP);
1196 TestMarkDirty(resource_id, md5, GDATA_FILE_OK,
1197 test_util::TEST_CACHE_STATE_PRESENT |
1198 test_util::TEST_CACHE_STATE_DIRTY |
1199 test_util::TEST_CACHE_STATE_PERSISTENT,
1200 GDataCache::CACHE_TYPE_PERSISTENT);
1201
1202 // Verifies dirty file exists.
1203 FilePath dirty_path = GetCacheFilePath(
1204 resource_id,
1205 md5,
1206 GDataCache::CACHE_TYPE_PERSISTENT,
1207 GDataCache::CACHED_FILE_LOCALLY_MODIFIED);
1208 EXPECT_TRUE(file_util::PathExists(dirty_path));
1209
1210 // Pin the dirty file.
1211 TestPin(resource_id, md5, GDATA_FILE_OK,
1212 test_util::TEST_CACHE_STATE_PRESENT |
1213 test_util::TEST_CACHE_STATE_DIRTY |
1214 test_util::TEST_CACHE_STATE_PINNED |
1215 test_util::TEST_CACHE_STATE_PERSISTENT,
1216 GDataCache::CACHE_TYPE_PERSISTENT);
1217
1218 // Verify dirty file still exist at the same pathname.
1219 EXPECT_TRUE(file_util::PathExists(dirty_path));
1220
1221 // Unpin the dirty file.
1222 TestUnpin(resource_id, md5, GDATA_FILE_OK,
1223 test_util::TEST_CACHE_STATE_PRESENT |
1224 test_util::TEST_CACHE_STATE_DIRTY |
1225 test_util::TEST_CACHE_STATE_PERSISTENT,
1226 GDataCache::CACHE_TYPE_PERSISTENT);
1227
1228 // Verify dirty file still exist at the same pathname.
1229 EXPECT_TRUE(file_util::PathExists(dirty_path));
1230 }
1231
1232 TEST_F(GDataCacheTest, DirtyCacheRepetitive) {
1233 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1234 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
1235
1236 std::string resource_id("pdf:1a2b");
1237 std::string md5("abcdef0123456789");
1238 EXPECT_CALL(*mock_cache_observer_, OnCacheCommitted(resource_id)).Times(3);
1239
1240 // First store a file to cache.
1241 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1242 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
1243 GDataCache::CACHE_TYPE_TMP);
1244
1245 // Mark the file dirty.
1246 num_callback_invocations_ = 0;
1247 TestMarkDirty(resource_id, md5, GDATA_FILE_OK,
1248 test_util::TEST_CACHE_STATE_PRESENT |
1249 test_util::TEST_CACHE_STATE_DIRTY |
1250 test_util::TEST_CACHE_STATE_PERSISTENT,
1251 GDataCache::CACHE_TYPE_PERSISTENT);
1252 EXPECT_EQ(1, num_callback_invocations_);
1253
1254 // Again, mark the file dirty. Nothing should change.
1255 num_callback_invocations_ = 0;
1256 TestMarkDirty(resource_id, md5, GDATA_FILE_OK,
1257 test_util::TEST_CACHE_STATE_PRESENT |
1258 test_util::TEST_CACHE_STATE_DIRTY |
1259 test_util::TEST_CACHE_STATE_PERSISTENT,
1260 GDataCache::CACHE_TYPE_PERSISTENT);
1261 EXPECT_EQ(1, num_callback_invocations_);
1262
1263 // Commit the file dirty. Outgoing symlink should be created.
1264 num_callback_invocations_ = 0;
1265 TestCommitDirty(resource_id, md5, GDATA_FILE_OK,
1266 test_util::TEST_CACHE_STATE_PRESENT |
1267 test_util::TEST_CACHE_STATE_DIRTY |
1268 test_util::TEST_CACHE_STATE_PERSISTENT,
1269 GDataCache::CACHE_TYPE_PERSISTENT);
1270 EXPECT_EQ(1, num_callback_invocations_);
1271
1272 // Again, commit the file dirty. Nothing should change.
1273 num_callback_invocations_ = 0;
1274 TestCommitDirty(resource_id, md5, GDATA_FILE_OK,
1275 test_util::TEST_CACHE_STATE_PRESENT |
1276 test_util::TEST_CACHE_STATE_DIRTY |
1277 test_util::TEST_CACHE_STATE_PERSISTENT,
1278 GDataCache::CACHE_TYPE_PERSISTENT);
1279 EXPECT_EQ(1, num_callback_invocations_);
1280
1281 // Mark the file dirty agian after it's being committed. Outgoing symlink
1282 // should be deleted.
1283 num_callback_invocations_ = 0;
1284 TestMarkDirty(resource_id, md5, GDATA_FILE_OK,
1285 test_util::TEST_CACHE_STATE_PRESENT |
1286 test_util::TEST_CACHE_STATE_DIRTY |
1287 test_util::TEST_CACHE_STATE_PERSISTENT,
1288 GDataCache::CACHE_TYPE_PERSISTENT);
1289 EXPECT_EQ(1, num_callback_invocations_);
1290
1291 // Commit the file dirty. Outgoing symlink should be created again.
1292 num_callback_invocations_ = 0;
1293 TestCommitDirty(resource_id, md5, GDATA_FILE_OK,
1294 test_util::TEST_CACHE_STATE_PRESENT |
1295 test_util::TEST_CACHE_STATE_DIRTY |
1296 test_util::TEST_CACHE_STATE_PERSISTENT,
1297 GDataCache::CACHE_TYPE_PERSISTENT);
1298 EXPECT_EQ(1, num_callback_invocations_);
1299
1300 // Clear dirty state of the file.
1301 num_callback_invocations_ = 0;
1302 TestClearDirty(resource_id, md5, GDATA_FILE_OK,
1303 test_util::TEST_CACHE_STATE_PRESENT,
1304 GDataCache::CACHE_TYPE_TMP);
1305 EXPECT_EQ(1, num_callback_invocations_);
1306
1307 // Again, clear dirty state of the file, which is no longer dirty.
1308 num_callback_invocations_ = 0;
1309 TestClearDirty(resource_id, md5, GDATA_FILE_ERROR_INVALID_OPERATION,
1310 test_util::TEST_CACHE_STATE_PRESENT,
1311 GDataCache::CACHE_TYPE_TMP);
1312 EXPECT_EQ(1, num_callback_invocations_);
1313 }
1314
1315 TEST_F(GDataCacheTest, DirtyCacheInvalid) {
1316 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1317 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
1318
1319 std::string resource_id("pdf:1a2b");
1320 std::string md5("abcdef0123456789");
1321
1322 // Mark a non-existent file dirty.
1323 num_callback_invocations_ = 0;
1324 TestMarkDirty(resource_id, md5, GDATA_FILE_ERROR_NOT_FOUND,
1325 test_util::TEST_CACHE_STATE_NONE,
1326 GDataCache::CACHE_TYPE_TMP);
1327 EXPECT_EQ(1, num_callback_invocations_);
1328
1329 // Commit a non-existent file dirty.
1330 num_callback_invocations_ = 0;
1331 TestCommitDirty(resource_id, md5, GDATA_FILE_ERROR_NOT_FOUND,
1332 test_util::TEST_CACHE_STATE_NONE,
1333 GDataCache::CACHE_TYPE_TMP);
1334 EXPECT_EQ(1, num_callback_invocations_);
1335
1336 // Clear dirty state of a non-existent file.
1337 num_callback_invocations_ = 0;
1338 TestClearDirty(resource_id, md5, GDATA_FILE_ERROR_NOT_FOUND,
1339 test_util::TEST_CACHE_STATE_NONE,
1340 GDataCache::CACHE_TYPE_TMP);
1341 EXPECT_EQ(1, num_callback_invocations_);
1342
1343 // Store a file to cache.
1344 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1345 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
1346 GDataCache::CACHE_TYPE_TMP);
1347
1348 // Commit a non-dirty existing file dirty.
1349 num_callback_invocations_ = 0;
1350 TestCommitDirty(resource_id, md5, GDATA_FILE_ERROR_INVALID_OPERATION,
1351 test_util::TEST_CACHE_STATE_PRESENT,
1352 GDataCache::CACHE_TYPE_TMP);
1353 EXPECT_EQ(1, num_callback_invocations_);
1354
1355 // Clear dirty state of a non-dirty existing file.
1356 num_callback_invocations_ = 0;
1357 TestClearDirty(resource_id, md5, GDATA_FILE_ERROR_INVALID_OPERATION,
1358 test_util::TEST_CACHE_STATE_PRESENT,
1359 GDataCache::CACHE_TYPE_TMP);
1360 EXPECT_EQ(1, num_callback_invocations_);
1361
1362 // Mark an existing file dirty, then store a new file to the same resource id
1363 // but different md5, which should fail.
1364 TestMarkDirty(resource_id, md5, GDATA_FILE_OK,
1365 test_util::TEST_CACHE_STATE_PRESENT |
1366 test_util::TEST_CACHE_STATE_DIRTY |
1367 test_util::TEST_CACHE_STATE_PERSISTENT,
1368 GDataCache::CACHE_TYPE_PERSISTENT);
1369 num_callback_invocations_ = 0;
1370 md5 = "new_md5";
1371 TestStoreToCache(resource_id, md5, GetTestFilePath("subdir_feed.json"),
1372 GDATA_FILE_ERROR_IN_USE,
1373 test_util::TEST_CACHE_STATE_PRESENT |
1374 test_util::TEST_CACHE_STATE_DIRTY |
1375 test_util::TEST_CACHE_STATE_PERSISTENT,
1376 GDataCache::CACHE_TYPE_PERSISTENT);
1377 EXPECT_EQ(1, num_callback_invocations_);
1378 }
1379
1380 TEST_F(GDataCacheTest, RemoveFromDirtyCache) {
1381 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1382 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
1383
1384 std::string resource_id("pdf:1a2b");
1385 std::string md5("abcdef0123456789");
1386 EXPECT_CALL(*mock_cache_observer_, OnCachePinned(resource_id, md5)).Times(1);
1387 EXPECT_CALL(*mock_cache_observer_, OnCacheCommitted(resource_id)).Times(1);
1388
1389 // Store a file to cache, pin it, mark it dirty and commit it.
1390 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1391 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
1392 GDataCache::CACHE_TYPE_TMP);
1393 TestPin(resource_id, md5, GDATA_FILE_OK,
1394 test_util::TEST_CACHE_STATE_PRESENT |
1395 test_util::TEST_CACHE_STATE_PINNED |
1396 test_util::TEST_CACHE_STATE_PERSISTENT,
1397 GDataCache::CACHE_TYPE_PERSISTENT);
1398 TestMarkDirty(resource_id, md5, GDATA_FILE_OK,
1399 test_util::TEST_CACHE_STATE_PRESENT |
1400 test_util::TEST_CACHE_STATE_PINNED |
1401 test_util::TEST_CACHE_STATE_DIRTY |
1402 test_util::TEST_CACHE_STATE_PERSISTENT,
1403 GDataCache::CACHE_TYPE_PERSISTENT);
1404 TestCommitDirty(resource_id, md5, GDATA_FILE_OK,
1405 test_util::TEST_CACHE_STATE_PRESENT |
1406 test_util::TEST_CACHE_STATE_PINNED |
1407 test_util::TEST_CACHE_STATE_DIRTY |
1408 test_util::TEST_CACHE_STATE_PERSISTENT,
1409 GDataCache::CACHE_TYPE_PERSISTENT);
1410
1411 // Try to remove the file. Since file is dirty, it and the corresponding
1412 // pinned and outgoing symlinks should not be removed.
1413 num_callback_invocations_ = 0;
1414 TestRemoveFromCache(resource_id, GDATA_FILE_OK);
1415 EXPECT_EQ(1, num_callback_invocations_);
1416 }
1417
1418 TEST_F(GDataCacheTest, MountUnmount) {
1419 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1420 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
1421
1422 FilePath file_path;
1423 std::string resource_id("pdf:1a2b");
1424 std::string md5("abcdef0123456789");
1425
1426 // First store a file to cache in the tmp subdir.
1427 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1428 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
1429 GDataCache::CACHE_TYPE_TMP);
1430
1431 // Mark the file mounted.
1432 num_callback_invocations_ = 0;
1433 file_path = cache_->GetCacheFilePath(resource_id, md5,
1434 GDataCache::CACHE_TYPE_TMP,
1435 GDataCache::CACHED_FILE_FROM_SERVER);
1436 TestSetMountedState(resource_id, md5, file_path, true,
1437 GDATA_FILE_OK,
1438 test_util::TEST_CACHE_STATE_PRESENT |
1439 test_util::TEST_CACHE_STATE_MOUNTED |
1440 test_util::TEST_CACHE_STATE_PERSISTENT,
1441 GDataCache::CACHE_TYPE_PERSISTENT);
1442 EXPECT_EQ(1, num_callback_invocations_);
1443 EXPECT_TRUE(CacheEntryExists(resource_id, md5));
1444
1445 // Clear mounted state of the file.
1446 num_callback_invocations_ = 0;
1447 file_path = cache_->GetCacheFilePath(resource_id,
1448 md5,
1449 GDataCache::CACHE_TYPE_PERSISTENT,
1450 GDataCache::CACHED_FILE_MOUNTED);
1451 TestSetMountedState(resource_id, md5, file_path, false,
1452 GDATA_FILE_OK,
1453 test_util::TEST_CACHE_STATE_PRESENT,
1454 GDataCache::CACHE_TYPE_TMP);
1455 EXPECT_EQ(1, num_callback_invocations_);
1456 EXPECT_TRUE(CacheEntryExists(resource_id, md5));
1457
1458 // Try to remove the file.
1459 num_callback_invocations_ = 0;
1460 TestRemoveFromCache(resource_id, GDATA_FILE_OK);
1461 EXPECT_EQ(1, num_callback_invocations_);
1462 }
1463
1464 TEST_F(GDataCacheTest, GetResourceIdsOfBacklogOnUIThread) {
1465 PrepareForInitCacheTest();
1466
1467 std::vector<std::string> to_fetch;
1468 std::vector<std::string> to_upload;
1469 cache_->GetResourceIdsOfBacklogOnUIThread(
1470 base::Bind(&OnGetResourceIdsOfBacklog, &to_fetch, &to_upload));
1471 test_util::RunBlockingPoolTask();
1472
1473 sort(to_fetch.begin(), to_fetch.end());
1474 ASSERT_EQ(1U, to_fetch.size());
1475 EXPECT_EQ("pinned:non-existent", to_fetch[0]);
1476
1477 sort(to_upload.begin(), to_upload.end());
1478 ASSERT_EQ(2U, to_upload.size());
1479 EXPECT_EQ("dirty:existing", to_upload[0]);
1480 EXPECT_EQ("dirty_and_pinned:existing", to_upload[1]);
1481 }
1482
1483 TEST_F(GDataCacheTest, GetResourceIdsOfExistingPinnedFilesOnUIThread) {
1484 PrepareForInitCacheTest();
1485
1486 std::vector<std::string> resource_ids;
1487 cache_->GetResourceIdsOfExistingPinnedFilesOnUIThread(
1488 base::Bind(&OnGetResourceIds, &resource_ids));
1489 test_util::RunBlockingPoolTask();
1490
1491 sort(resource_ids.begin(), resource_ids.end());
1492 ASSERT_EQ(2U, resource_ids.size());
1493 EXPECT_EQ("dirty_and_pinned:existing", resource_ids[0]);
1494 EXPECT_EQ("pinned:existing", resource_ids[1]);
1495 }
1496
1497 TEST_F(GDataCacheTest, GetResourceIdsOfAllFilesOnUIThread) {
1498 PrepareForInitCacheTest();
1499
1500 std::vector<std::string> resource_ids;
1501 cache_->GetResourceIdsOfAllFilesOnUIThread(
1502 base::Bind(&OnGetResourceIds, &resource_ids));
1503 test_util::RunBlockingPoolTask();
1504
1505 sort(resource_ids.begin(), resource_ids.end());
1506 ASSERT_EQ(6U, resource_ids.size());
1507 EXPECT_EQ("dirty:existing", resource_ids[0]);
1508 EXPECT_EQ("dirty_and_pinned:existing", resource_ids[1]);
1509 EXPECT_EQ("pinned:existing", resource_ids[2]);
1510 EXPECT_EQ("pinned:non-existent", resource_ids[3]);
1511 EXPECT_EQ("tmp:`~!@#$%^&*()-_=+[{|]}\\;',<.>/?", resource_ids[4]);
1512 EXPECT_EQ("tmp:resource_id", resource_ids[5]);
1513 }
1514
1515
1516 TEST_F(GDataCacheTest, ClearAllOnUIThread) {
1517 PrepareForInitCacheTest();
1518
1519 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1520 .Times(AtLeast(1)).WillRepeatedly(Return(kLotsOfSpace));
1521
1522 std::string resource_id("pdf:1a2b");
1523 std::string md5("abcdef0123456789");
1524
1525 // Store an existing file.
1526 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1527 GDATA_FILE_OK, test_util::TEST_CACHE_STATE_PRESENT,
1528 GDataCache::CACHE_TYPE_TMP);
1529 EXPECT_EQ(1, num_callback_invocations_);
1530
1531 // Verify that there's only one cached file.
1532 EXPECT_EQ(1U, CountCacheFiles(resource_id, md5));
1533
1534 // Clear cache.
1535 GDataFileError error = GDATA_FILE_OK;
1536 FilePath file_path;
1537 cache_->ClearAllOnUIThread(base::Bind(&OnClearAll,
1538 &error,
1539 &file_path));
1540 test_util::RunBlockingPoolTask();
1541 EXPECT_EQ(GDATA_FILE_OK, error);
1542
1543 // Verify that all the cache is removed.
1544 VerifyRemoveFromCache(error, resource_id, md5);
1545 EXPECT_EQ(0U, CountCacheFiles(resource_id, md5));
1546 }
1547
1548 TEST_F(GDataCacheTest, StoreToCacheNoSpace) {
1549 EXPECT_CALL(*mock_free_disk_space_checker_, AmountOfFreeDiskSpace())
1550 .Times(AtLeast(1)).WillRepeatedly(Return(0));
1551
1552 std::string resource_id("pdf:1a2b");
1553 std::string md5("abcdef0123456789");
1554
1555 // Try to store an existing file.
1556 TestStoreToCache(resource_id, md5, GetTestFilePath("root_feed.json"),
1557 GDATA_FILE_ERROR_NO_SPACE,
1558 test_util::TEST_CACHE_STATE_NONE,
1559 GDataCache::CACHE_TYPE_TMP);
1560 EXPECT_EQ(1, num_callback_invocations_);
1561
1562 // Verify that there's no files added.
1563 EXPECT_EQ(0U, CountCacheFiles(resource_id, md5));
1564 }
1565
1566
1567 } // namespace gdata
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698