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