blob: 0c3d8c91ee3613bd4eb450c18daf02d805e7b34f [file] [log] [blame]
// Copyright 2014 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 "sync/test/engine/mock_non_blocking_type_processor.h"
#include "base/bind.h"
namespace syncer {
MockNonBlockingTypeProcessor::MockNonBlockingTypeProcessor()
: is_synchronous_(true) {
}
MockNonBlockingTypeProcessor::~MockNonBlockingTypeProcessor() {
}
void MockNonBlockingTypeProcessor::ReceiveCommitResponse(
const DataTypeState& type_state,
const CommitResponseDataList& response_list) {
base::Closure task =
base::Bind(&MockNonBlockingTypeProcessor::ReceiveCommitResponseImpl,
base::Unretained(this),
type_state,
response_list);
pending_tasks_.push_back(task);
if (is_synchronous_)
RunQueuedTasks();
}
void MockNonBlockingTypeProcessor::ReceiveUpdateResponse(
const DataTypeState& type_state,
const UpdateResponseDataList& response_list) {
base::Closure task =
base::Bind(&MockNonBlockingTypeProcessor::ReceiveUpdateResponseImpl,
base::Unretained(this),
type_state,
response_list);
pending_tasks_.push_back(task);
if (is_synchronous_)
RunQueuedTasks();
}
void MockNonBlockingTypeProcessor::SetSynchronousExecution(
bool is_synchronous) {
is_synchronous_ = is_synchronous;
}
void MockNonBlockingTypeProcessor::RunQueuedTasks() {
for (std::vector<base::Closure>::iterator it = pending_tasks_.begin();
it != pending_tasks_.end();
++it) {
it->Run();
}
pending_tasks_.clear();
}
CommitRequestData MockNonBlockingTypeProcessor::CommitRequest(
const std::string& tag_hash,
const sync_pb::EntitySpecifics& specifics) {
const int64 base_version = GetBaseVersion(tag_hash);
CommitRequestData data;
if (HasServerAssignedId(tag_hash)) {
data.id = GetServerAssignedId(tag_hash);
}
data.client_tag_hash = tag_hash;
data.sequence_number = GetNextSequenceNumber(tag_hash);
data.deleted = false;
data.specifics = specifics;
data.base_version = base_version;
// These fields are not really used for much, but we set them anyway
// to make this item look more realistic.
data.ctime = base::Time::UnixEpoch() + base::TimeDelta::FromDays(1);
data.mtime = data.ctime + base::TimeDelta::FromSeconds(base_version);
data.non_unique_name = "Name: " + tag_hash;
return data;
}
CommitRequestData MockNonBlockingTypeProcessor::DeleteRequest(
const std::string& tag_hash) {
const int64 base_version = GetBaseVersion(tag_hash);
CommitRequestData data;
if (HasServerAssignedId(tag_hash)) {
data.id = GetServerAssignedId(tag_hash);
}
data.client_tag_hash = tag_hash;
data.sequence_number = GetNextSequenceNumber(tag_hash);
data.base_version = base_version;
data.mtime = data.ctime + base::TimeDelta::FromSeconds(base_version);
data.deleted = true;
// These fields have little or no effect on behavior. We set them anyway to
// make the test more realistic.
data.ctime = base::Time::UnixEpoch() + base::TimeDelta::FromDays(1);
data.non_unique_name = "Name deleted";
return data;
}
size_t MockNonBlockingTypeProcessor::GetNumUpdateResponses() const {
return received_update_responses_.size();
}
UpdateResponseDataList MockNonBlockingTypeProcessor::GetNthUpdateResponse(
size_t n) const {
DCHECK_LT(n, GetNumUpdateResponses());
return received_update_responses_[n];
}
DataTypeState
MockNonBlockingTypeProcessor::GetNthTypeStateReceivedInUpdateResponse(
size_t n) const {
DCHECK_LT(n, GetNumUpdateResponses());
return type_states_received_on_update_[n];
}
size_t MockNonBlockingTypeProcessor::GetNumCommitResponses() const {
return received_commit_responses_.size();
}
CommitResponseDataList MockNonBlockingTypeProcessor::GetNthCommitResponse(
size_t n) const {
DCHECK_LT(n, GetNumCommitResponses());
return received_commit_responses_[n];
}
DataTypeState
MockNonBlockingTypeProcessor::GetNthTypeStateReceivedInCommitResponse(
size_t n) const {
DCHECK_LT(n, GetNumCommitResponses());
return type_states_received_on_commit_[n];
}
bool MockNonBlockingTypeProcessor::HasUpdateResponse(
const std::string& tag_hash) const {
std::map<const std::string, UpdateResponseData>::const_iterator it =
update_response_items_.find(tag_hash);
return it != update_response_items_.end();
}
UpdateResponseData MockNonBlockingTypeProcessor::GetUpdateResponse(
const std::string& tag_hash) const {
DCHECK(HasUpdateResponse(tag_hash));
std::map<const std::string, UpdateResponseData>::const_iterator it =
update_response_items_.find(tag_hash);
return it->second;
}
bool MockNonBlockingTypeProcessor::HasCommitResponse(
const std::string& tag_hash) const {
std::map<const std::string, CommitResponseData>::const_iterator it =
commit_response_items_.find(tag_hash);
return it != commit_response_items_.end();
}
CommitResponseData MockNonBlockingTypeProcessor::GetCommitResponse(
const std::string& tag_hash) const {
DCHECK(HasCommitResponse(tag_hash));
std::map<const std::string, CommitResponseData>::const_iterator it =
commit_response_items_.find(tag_hash);
return it->second;
}
void MockNonBlockingTypeProcessor::ReceiveCommitResponseImpl(
const DataTypeState& type_state,
const CommitResponseDataList& response_list) {
received_commit_responses_.push_back(response_list);
type_states_received_on_commit_.push_back(type_state);
for (CommitResponseDataList::const_iterator it = response_list.begin();
it != response_list.end();
++it) {
commit_response_items_.insert(std::make_pair(it->client_tag_hash, *it));
// Server wins. Set the model's base version.
SetBaseVersion(it->client_tag_hash, it->response_version);
SetServerAssignedId(it->client_tag_hash, it->id);
}
}
void MockNonBlockingTypeProcessor::ReceiveUpdateResponseImpl(
const DataTypeState& type_state,
const UpdateResponseDataList& response_list) {
received_update_responses_.push_back(response_list);
type_states_received_on_update_.push_back(type_state);
for (UpdateResponseDataList::const_iterator it = response_list.begin();
it != response_list.end();
++it) {
update_response_items_.insert(std::make_pair(it->client_tag_hash, *it));
// Server wins. Set the model's base version.
SetBaseVersion(it->client_tag_hash, it->response_version);
SetServerAssignedId(it->client_tag_hash, it->id);
}
}
// Fetches the sequence number as of the most recent update request.
int64 MockNonBlockingTypeProcessor::GetCurrentSequenceNumber(
const std::string& tag_hash) const {
std::map<const std::string, int64>::const_iterator it =
sequence_numbers_.find(tag_hash);
if (it == sequence_numbers_.end()) {
return 0;
} else {
return it->second;
}
}
// The model thread should be sending us items with strictly increasing
// sequence numbers. Here's where we emulate that behavior.
int64 MockNonBlockingTypeProcessor::GetNextSequenceNumber(
const std::string& tag_hash) {
int64 sequence_number = GetCurrentSequenceNumber(tag_hash);
sequence_number++;
sequence_numbers_[tag_hash] = sequence_number;
return sequence_number;
}
int64 MockNonBlockingTypeProcessor::GetBaseVersion(
const std::string& tag_hash) const {
std::map<const std::string, int64>::const_iterator it =
base_versions_.find(tag_hash);
if (it == base_versions_.end()) {
return kUncommittedVersion;
} else {
return it->second;
}
}
void MockNonBlockingTypeProcessor::SetBaseVersion(const std::string& tag_hash,
int64 version) {
base_versions_[tag_hash] = version;
}
bool MockNonBlockingTypeProcessor::HasServerAssignedId(
const std::string& tag_hash) const {
return assigned_ids_.find(tag_hash) != assigned_ids_.end();
}
const std::string& MockNonBlockingTypeProcessor::GetServerAssignedId(
const std::string& tag_hash) const {
DCHECK(HasServerAssignedId(tag_hash));
return assigned_ids_.find(tag_hash)->second;
}
void MockNonBlockingTypeProcessor::SetServerAssignedId(
const std::string& tag_hash,
const std::string& id) {
assigned_ids_[tag_hash] = id;
}
} // namespace syncer