Home | History | Annotate | Download | only in sync_file_system
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/sync_file_system/fake_remote_change_processor.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/files/file_path.h"
      9 #include "base/location.h"
     10 #include "base/single_thread_task_runner.h"
     11 #include "base/thread_task_runner_handle.h"
     12 #include "chrome/browser/sync_file_system/file_change.h"
     13 #include "chrome/browser/sync_file_system/sync_file_metadata.h"
     14 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
     15 #include "storage/browser/fileapi/file_system_url.h"
     16 #include "storage/common/fileapi/file_system_util.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 namespace sync_file_system {
     20 
     21 FakeRemoteChangeProcessor::FakeRemoteChangeProcessor() {
     22 }
     23 
     24 FakeRemoteChangeProcessor::~FakeRemoteChangeProcessor() {
     25 }
     26 
     27 void FakeRemoteChangeProcessor::PrepareForProcessRemoteChange(
     28     const storage::FileSystemURL& url,
     29     const PrepareChangeCallback& callback) {
     30   SyncFileMetadata local_metadata;
     31 
     32   if (storage::VirtualPath::IsRootPath(url.path())) {
     33     // Origin root directory case.
     34     local_metadata = SyncFileMetadata(
     35         SYNC_FILE_TYPE_DIRECTORY, 0, base::Time::Now());
     36   }
     37 
     38   URLToFileMetadata::iterator found_metadata = local_file_metadata_.find(url);
     39   if (found_metadata != local_file_metadata_.end())
     40     local_metadata = found_metadata->second;
     41 
     42   // Override |local_metadata| by applied changes.
     43   URLToFileChangesMap::iterator found = applied_changes_.find(url);
     44   if (found != applied_changes_.end()) {
     45     DCHECK(!found->second.empty());
     46     const FileChange& applied_change = found->second.back();
     47     if (applied_change.IsAddOrUpdate()) {
     48       local_metadata = SyncFileMetadata(
     49           applied_change.file_type(),
     50           100 /* size */,
     51           base::Time::Now());
     52     }
     53   }
     54 
     55   FileChangeList change_list;
     56   URLToFileChangeList::iterator found_list = local_changes_.find(url);
     57   if (found_list != local_changes_.end())
     58     change_list = found_list->second;
     59 
     60   base::ThreadTaskRunnerHandle::Get()->PostTask(
     61       FROM_HERE,
     62       base::Bind(callback, SYNC_STATUS_OK,
     63                  local_metadata, change_list));
     64 }
     65 
     66 void FakeRemoteChangeProcessor::ApplyRemoteChange(
     67     const FileChange& change,
     68     const base::FilePath& local_path,
     69     const storage::FileSystemURL& url,
     70     const SyncStatusCallback& callback) {
     71   SyncStatusCode status = SYNC_STATUS_UNKNOWN;
     72   base::FilePath ancestor = storage::VirtualPath::DirName(url.path());
     73   while (true) {
     74     storage::FileSystemURL ancestor_url =
     75         CreateSyncableFileSystemURL(url.origin(), ancestor);
     76     if (!ancestor_url.is_valid())
     77       break;
     78 
     79     URLToFileChangeList::iterator found_list =
     80         local_changes_.find(ancestor_url);
     81     if (found_list != local_changes_.end()) {
     82       const FileChange& local_change = found_list->second.back();
     83       if (local_change.IsAddOrUpdate() &&
     84           local_change.file_type() != SYNC_FILE_TYPE_DIRECTORY) {
     85         status = SYNC_FILE_ERROR_NOT_A_DIRECTORY;
     86         break;
     87       }
     88     }
     89 
     90     base::FilePath ancestor_parent = storage::VirtualPath::DirName(ancestor);
     91     if (ancestor == ancestor_parent)
     92       break;
     93     ancestor = ancestor_parent;
     94   }
     95   if (status == SYNC_STATUS_UNKNOWN) {
     96     applied_changes_[url].push_back(change);
     97     status = SYNC_STATUS_OK;
     98   }
     99   base::ThreadTaskRunnerHandle::Get()->PostTask(
    100       FROM_HERE, base::Bind(callback, status));
    101 }
    102 
    103 void FakeRemoteChangeProcessor::FinalizeRemoteSync(
    104     const storage::FileSystemURL& url,
    105     bool clear_local_changes,
    106     const base::Closure& completion_callback) {
    107   base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, completion_callback);
    108 }
    109 
    110 void FakeRemoteChangeProcessor::RecordFakeLocalChange(
    111     const storage::FileSystemURL& url,
    112     const FileChange& change,
    113     const SyncStatusCallback& callback) {
    114   local_changes_[url].Update(change);
    115   base::ThreadTaskRunnerHandle::Get()->PostTask(
    116       FROM_HERE, base::Bind(callback, SYNC_STATUS_OK));
    117 }
    118 
    119 void FakeRemoteChangeProcessor::UpdateLocalFileMetadata(
    120     const storage::FileSystemURL& url,
    121     const FileChange& change) {
    122   if (change.IsAddOrUpdate()) {
    123     local_file_metadata_[url] = SyncFileMetadata(
    124         change.file_type(), 100 /* size */, base::Time::Now());
    125   } else {
    126     local_file_metadata_.erase(url);
    127   }
    128   local_changes_[url].Update(change);
    129 }
    130 
    131 void FakeRemoteChangeProcessor::ClearLocalChanges(
    132     const storage::FileSystemURL& url) {
    133   local_changes_.erase(url);
    134 }
    135 
    136 const FakeRemoteChangeProcessor::URLToFileChangesMap&
    137 FakeRemoteChangeProcessor::GetAppliedRemoteChanges() const {
    138   return applied_changes_;
    139 }
    140 
    141 void FakeRemoteChangeProcessor::VerifyConsistency(
    142     const URLToFileChangesMap& expected_changes) {
    143   EXPECT_EQ(expected_changes.size(), applied_changes_.size());
    144   for (URLToFileChangesMap::const_iterator itr = applied_changes_.begin();
    145        itr != applied_changes_.end(); ++itr) {
    146     const storage::FileSystemURL& url = itr->first;
    147     URLToFileChangesMap::const_iterator found = expected_changes.find(url);
    148     if (found == expected_changes.end()) {
    149       EXPECT_TRUE(found != expected_changes.end())
    150           << "Change not expected for " << url.DebugString();
    151       continue;
    152     }
    153 
    154     const std::vector<FileChange>& applied = itr->second;
    155     const std::vector<FileChange>& expected = found->second;
    156 
    157     if (applied.empty() || expected.empty()) {
    158       EXPECT_TRUE(!applied.empty());
    159       EXPECT_TRUE(!expected.empty());
    160       continue;
    161     }
    162 
    163     EXPECT_EQ(expected.size(), applied.size());
    164 
    165     for (size_t i = 0; i < applied.size() && i < expected.size(); ++i) {
    166       EXPECT_EQ(expected[i], applied[i])
    167           << url.DebugString()
    168           << " expected:" << expected[i].DebugString()
    169           << " applied:" << applied[i].DebugString();
    170     }
    171   }
    172 }
    173 
    174 }  // namespace sync_file_system
    175