blob: ce53a41e2ab761b1fc0a33ed908ed5fa469c1b8e [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/sync_file_system/fake_remote_change_processor.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"
#include "chrome/browser/sync_file_system/file_change.h"
#include "chrome/browser/sync_file_system/sync_file_metadata.h"
#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/common/fileapi/file_system_util.h"
namespace sync_file_system {
FakeRemoteChangeProcessor::FakeRemoteChangeProcessor() {
}
FakeRemoteChangeProcessor::~FakeRemoteChangeProcessor() {
}
void FakeRemoteChangeProcessor::PrepareForProcessRemoteChange(
const fileapi::FileSystemURL& url,
const PrepareChangeCallback& callback) {
SyncFileMetadata local_metadata;
if (fileapi::VirtualPath::IsRootPath(url.path())) {
// Origin root directory case.
local_metadata = SyncFileMetadata(
SYNC_FILE_TYPE_DIRECTORY, 0, base::Time::Now());
}
URLToFileMetadata::iterator found_metadata = local_file_metadata_.find(url);
if (found_metadata != local_file_metadata_.end())
local_metadata = found_metadata->second;
// Override |local_metadata| by applied changes.
URLToFileChangesMap::iterator found = applied_changes_.find(url);
if (found != applied_changes_.end()) {
DCHECK(!found->second.empty());
const FileChange& applied_change = found->second.back();
if (applied_change.IsAddOrUpdate()) {
local_metadata = SyncFileMetadata(
applied_change.file_type(),
100 /* size */,
base::Time::Now());
}
}
FileChangeList change_list;
URLToFileChangeList::iterator found_list = local_changes_.find(url);
if (found_list != local_changes_.end())
change_list = found_list->second;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(callback, SYNC_STATUS_OK,
local_metadata, change_list));
}
void FakeRemoteChangeProcessor::ApplyRemoteChange(
const FileChange& change,
const base::FilePath& local_path,
const fileapi::FileSystemURL& url,
const SyncStatusCallback& callback) {
SyncStatusCode status = SYNC_STATUS_UNKNOWN;
base::FilePath ancestor = fileapi::VirtualPath::DirName(url.path());
while (true) {
fileapi::FileSystemURL ancestor_url =
CreateSyncableFileSystemURL(url.origin(), ancestor);
if (!ancestor_url.is_valid())
break;
URLToFileChangeList::iterator found_list =
local_changes_.find(ancestor_url);
if (found_list != local_changes_.end()) {
const FileChange& local_change = found_list->second.back();
if (local_change.IsAddOrUpdate() &&
local_change.file_type() != SYNC_FILE_TYPE_DIRECTORY) {
status = SYNC_FILE_ERROR_NOT_A_DIRECTORY;
break;
}
}
base::FilePath ancestor_parent = fileapi::VirtualPath::DirName(ancestor);
if (ancestor == ancestor_parent)
break;
ancestor = ancestor_parent;
}
if (status == SYNC_STATUS_UNKNOWN) {
applied_changes_[url].push_back(change);
status = SYNC_STATUS_OK;
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(callback, status));
}
void FakeRemoteChangeProcessor::FinalizeRemoteSync(
const fileapi::FileSystemURL& url,
bool clear_local_changes,
const base::Closure& completion_callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, completion_callback);
}
void FakeRemoteChangeProcessor::RecordFakeLocalChange(
const fileapi::FileSystemURL& url,
const FileChange& change,
const SyncStatusCallback& callback) {
local_changes_[url].Update(change);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(callback, SYNC_STATUS_OK));
}
void FakeRemoteChangeProcessor::UpdateLocalFileMetadata(
const fileapi::FileSystemURL& url,
const FileChange& change) {
if (change.IsAddOrUpdate()) {
local_file_metadata_[url] = SyncFileMetadata(
change.file_type(), 100 /* size */, base::Time::Now());
} else {
local_file_metadata_.erase(url);
}
local_changes_[url].Update(change);
}
void FakeRemoteChangeProcessor::ClearLocalChanges(
const fileapi::FileSystemURL& url) {
local_changes_.erase(url);
}
const FakeRemoteChangeProcessor::URLToFileChangesMap&
FakeRemoteChangeProcessor::GetAppliedRemoteChanges() const {
return applied_changes_;
}
void FakeRemoteChangeProcessor::VerifyConsistency(
const URLToFileChangesMap& expected_changes) {
EXPECT_EQ(expected_changes.size(), applied_changes_.size());
for (URLToFileChangesMap::const_iterator itr = applied_changes_.begin();
itr != applied_changes_.end(); ++itr) {
const fileapi::FileSystemURL& url = itr->first;
URLToFileChangesMap::const_iterator found = expected_changes.find(url);
if (found == expected_changes.end()) {
EXPECT_TRUE(found != expected_changes.end())
<< "Change not expected for " << url.DebugString();
continue;
}
const std::vector<FileChange>& applied = itr->second;
const std::vector<FileChange>& expected = found->second;
if (applied.empty() || expected.empty()) {
EXPECT_TRUE(!applied.empty());
EXPECT_TRUE(!expected.empty());
continue;
}
EXPECT_EQ(expected.size(), applied.size());
for (size_t i = 0; i < applied.size() && i < expected.size(); ++i) {
EXPECT_EQ(expected[i], applied[i])
<< url.DebugString()
<< " expected:" << expected[i].DebugString()
<< " applied:" << applied[i].DebugString();
}
}
}
} // namespace sync_file_system