fake_remote_change_processor.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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 "testing/gtest/include/gtest/gtest.h" 16#include "webkit/browser/fileapi/file_system_url.h" 17#include "webkit/common/fileapi/file_system_util.h" 18 19namespace sync_file_system { 20 21FakeRemoteChangeProcessor::FakeRemoteChangeProcessor() { 22} 23 24FakeRemoteChangeProcessor::~FakeRemoteChangeProcessor() { 25} 26 27void FakeRemoteChangeProcessor::PrepareForProcessRemoteChange( 28 const fileapi::FileSystemURL& url, 29 const PrepareChangeCallback& callback) { 30 SyncFileMetadata local_metadata; 31 32 if (fileapi::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 66void FakeRemoteChangeProcessor::ApplyRemoteChange( 67 const FileChange& change, 68 const base::FilePath& local_path, 69 const fileapi::FileSystemURL& url, 70 const SyncStatusCallback& callback) { 71 SyncStatusCode status = SYNC_STATUS_UNKNOWN; 72 base::FilePath ancestor = fileapi::VirtualPath::DirName(url.path()); 73 while (true) { 74 fileapi::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 = fileapi::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 103void FakeRemoteChangeProcessor::FinalizeRemoteSync( 104 const fileapi::FileSystemURL& url, 105 bool clear_local_changes, 106 const base::Closure& completion_callback) { 107 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, completion_callback); 108} 109 110void FakeRemoteChangeProcessor::RecordFakeLocalChange( 111 const fileapi::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 119void FakeRemoteChangeProcessor::UpdateLocalFileMetadata( 120 const fileapi::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 131void FakeRemoteChangeProcessor::ClearLocalChanges( 132 const fileapi::FileSystemURL& url) { 133 local_changes_.erase(url); 134} 135 136const FakeRemoteChangeProcessor::URLToFileChangesMap& 137FakeRemoteChangeProcessor::GetAppliedRemoteChanges() const { 138 return applied_changes_; 139} 140 141void 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 fileapi::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