fake_remote_change_processor.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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 18namespace sync_file_system { 19 20FakeRemoteChangeProcessor::FakeRemoteChangeProcessor() { 21} 22 23FakeRemoteChangeProcessor::~FakeRemoteChangeProcessor() { 24} 25 26void 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 65void 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 102void 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 109void 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 118void 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 130void FakeRemoteChangeProcessor::ClearLocalChanges( 131 const fileapi::FileSystemURL& url) { 132 local_changes_.erase(url); 133} 134 135const FakeRemoteChangeProcessor::URLToFileChangesMap& 136FakeRemoteChangeProcessor::GetAppliedRemoteChanges() const { 137 return applied_changes_; 138} 139 140void 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