summaryrefslogtreecommitdiffstats
path: root/sync
diff options
context:
space:
mode:
authorrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-12 22:27:11 +0000
committerrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-12 22:27:11 +0000
commita5e1b96eb81958086c94965380b234e16133f471 (patch)
treee87129bed797495c1092bd95c81db4792435a10a /sync
parentd9dda41217df075eb2f2dca1c5763e22cb75523b (diff)
downloadchromium_src-a5e1b96eb81958086c94965380b234e16133f471.zip
chromium_src-a5e1b96eb81958086c94965380b234e16133f471.tar.gz
chromium_src-a5e1b96eb81958086c94965380b234e16133f471.tar.bz2
sync: Refactor NonBlockingTypeProcessor tests
Moves some test support classes out of the NonBlockingTypeProcessor's unit test .cc files and into their own files. Rearranges some responsibilities between the test harness and the mock classes. Much of the functionality related to mocking out server behavior has been moved into the MockNonBlockingTypeProcessor. This makes it possible to share that code with other test harnesses. This is one of several follow-ups to the commits that introduced the NonBlockingTypeProcessor and NonBlockingTypeProcessorCore. BUG=351005 Review URL: https://codereview.chromium.org/318193002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@276830 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'sync')
-rw-r--r--sync/engine/non_blocking_type_processor_unittest.cc257
-rw-r--r--sync/sync_tests.gypi4
-rw-r--r--sync/test/engine/injectable_sync_core_proxy.cc51
-rw-r--r--sync/test/engine/injectable_sync_core_proxy.h47
-rw-r--r--sync/test/engine/mock_non_blocking_type_processor_core.cc175
-rw-r--r--sync/test/engine/mock_non_blocking_type_processor_core.h82
6 files changed, 385 insertions, 231 deletions
diff --git a/sync/engine/non_blocking_type_processor_unittest.cc b/sync/engine/non_blocking_type_processor_unittest.cc
index 3a3ca5c..20ecb24 100644
--- a/sync/engine/non_blocking_type_processor_unittest.cc
+++ b/sync/engine/non_blocking_type_processor_unittest.cc
@@ -10,103 +10,13 @@
#include "sync/internal_api/public/sync_core_proxy.h"
#include "sync/protocol/sync.pb.h"
#include "sync/syncable/syncable_util.h"
+#include "sync/test/engine/injectable_sync_core_proxy.h"
+#include "sync/test/engine/mock_non_blocking_type_processor_core.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
-namespace {
-
-class MockNonBlockingTypeProcessorCore
- : public NonBlockingTypeProcessorCoreInterface {
- public:
- MockNonBlockingTypeProcessorCore();
- virtual ~MockNonBlockingTypeProcessorCore();
-
- virtual void RequestCommits(const CommitRequestDataList& list) OVERRIDE;
-
- bool is_connected_;
-
- std::vector<CommitRequestDataList> commit_request_lists_;
-};
-
-MockNonBlockingTypeProcessorCore::MockNonBlockingTypeProcessorCore()
- : is_connected_(false) {
-}
-
-MockNonBlockingTypeProcessorCore::~MockNonBlockingTypeProcessorCore() {
-}
-
-void MockNonBlockingTypeProcessorCore::RequestCommits(
- const CommitRequestDataList& list) {
- commit_request_lists_.push_back(list);
-}
-
-class MockSyncCoreProxy : public syncer::SyncCoreProxy {
- public:
- MockSyncCoreProxy();
- virtual ~MockSyncCoreProxy();
-
- virtual void ConnectTypeToCore(
- syncer::ModelType type,
- const DataTypeState& data_type_state,
- base::WeakPtr<syncer::NonBlockingTypeProcessor> type_processor) OVERRIDE;
- virtual void Disconnect(syncer::ModelType type) OVERRIDE;
- virtual scoped_ptr<SyncCoreProxy> Clone() const OVERRIDE;
-
- MockNonBlockingTypeProcessorCore* GetMockProcessorCore();
-
- private:
- explicit MockSyncCoreProxy(MockNonBlockingTypeProcessorCore*);
-
- // The NonBlockingTypeProcessor's contract expects that it gets to own this
- // object, so we can retain only a non-owned pointer to it.
- //
- // This is very unsafe, but we can get away with it since these tests are not
- // exercising the processor <-> processor_core connection code.
- MockNonBlockingTypeProcessorCore* mock_core_;
-};
-
-MockSyncCoreProxy::MockSyncCoreProxy()
- : mock_core_(new MockNonBlockingTypeProcessorCore) {
-}
-
-MockSyncCoreProxy::MockSyncCoreProxy(MockNonBlockingTypeProcessorCore* core)
- : mock_core_(core) {
-}
-
-MockSyncCoreProxy::~MockSyncCoreProxy() {
-}
-
-void MockSyncCoreProxy::ConnectTypeToCore(
- syncer::ModelType type,
- const DataTypeState& data_type_state,
- base::WeakPtr<syncer::NonBlockingTypeProcessor> type_processor) {
- // This class is allowed to participate in only one connection.
- DCHECK(!mock_core_->is_connected_);
- mock_core_->is_connected_ = true;
-
- // Hands off ownership of our member to the type_processor, while keeping
- // an unsafe pointer to it. This is why we can only connect once.
- scoped_ptr<NonBlockingTypeProcessorCoreInterface> core(mock_core_);
-
- type_processor->OnConnect(core.Pass());
-}
-
-void MockSyncCoreProxy::Disconnect(syncer::ModelType type) {
- // This mock object is not meant for connect and disconnect tests.
- NOTREACHED() << "Not implemented";
-}
-
-scoped_ptr<SyncCoreProxy> MockSyncCoreProxy::Clone() const {
- // There's no sensible way to clone this MockSyncCoreProxy.
- return scoped_ptr<SyncCoreProxy>(new MockSyncCoreProxy(mock_core_));
-}
-
-MockNonBlockingTypeProcessorCore* MockSyncCoreProxy::GetMockProcessorCore() {
- return mock_core_;
-}
-
-} // namespace
+static const ModelType kModelType = PREFERENCES;
// Tests the sync engine parts of NonBlockingTypeProcessor.
//
@@ -169,37 +79,32 @@ class NonBlockingTypeProcessorTest : public ::testing::Test {
void SuccessfulCommitResponse(const CommitRequestData& request_data);
private:
- std::string GenerateId(const std::string& tag) const;
- std::string GenerateTagHash(const std::string& tag) const;
- sync_pb::EntitySpecifics GenerateSpecifics(const std::string& tag,
- const std::string& value) const;
+ static std::string GenerateTagHash(const std::string& tag);
+ static sync_pb::EntitySpecifics GenerateSpecifics(const std::string& tag,
+ const std::string& value);
int64 GetServerVersion(const std::string& tag);
void SetServerVersion(const std::string& tag, int64 version);
- const ModelType type_;
-
- scoped_ptr<MockSyncCoreProxy> mock_sync_core_proxy_;
- scoped_ptr<NonBlockingTypeProcessor> processor_;
MockNonBlockingTypeProcessorCore* mock_processor_core_;
+ scoped_ptr<InjectableSyncCoreProxy> injectable_sync_core_proxy_;
+ scoped_ptr<NonBlockingTypeProcessor> processor_;
DataTypeState data_type_state_;
-
- std::map<const std::string, int64> server_versions_;
};
NonBlockingTypeProcessorTest::NonBlockingTypeProcessorTest()
- : type_(PREFERENCES),
- mock_sync_core_proxy_(new MockSyncCoreProxy()),
- processor_(new NonBlockingTypeProcessor(type_)) {
+ : mock_processor_core_(new MockNonBlockingTypeProcessorCore()),
+ injectable_sync_core_proxy_(
+ new InjectableSyncCoreProxy(mock_processor_core_)),
+ processor_(new NonBlockingTypeProcessor(kModelType)) {
}
NonBlockingTypeProcessorTest::~NonBlockingTypeProcessorTest() {
}
void NonBlockingTypeProcessorTest::FirstTimeInitialize() {
- processor_->Enable(mock_sync_core_proxy_->Clone());
- mock_processor_core_ = mock_sync_core_proxy_->GetMockProcessorCore();
+ processor_->Enable(injectable_sync_core_proxy_->Clone());
}
void NonBlockingTypeProcessorTest::InitializeToReadyState() {
@@ -232,27 +137,11 @@ void NonBlockingTypeProcessorTest::UpdateFromServer(int64 version_offset,
const std::string& tag,
const std::string& value) {
const std::string tag_hash = GenerateTagHash(tag);
-
- // Overwrite the existing server version if this is the new highest version.
- int64 old_version = GetServerVersion(tag_hash);
- int64 version = old_version + version_offset;
- if (version > old_version) {
- SetServerVersion(tag_hash, version);
- }
-
- UpdateResponseData data;
- data.id = GenerateId(tag_hash);
- data.client_tag_hash = tag_hash;
- data.response_version = version;
- data.ctime = base::Time::UnixEpoch() + base::TimeDelta::FromDays(1);
- data.mtime = data.ctime + base::TimeDelta::FromSeconds(version);
- data.non_unique_name = tag;
- data.deleted = false;
- data.specifics = GenerateSpecifics(tag, value);
+ UpdateResponseData data = mock_processor_core_->UpdateFromServer(
+ version_offset, tag_hash, GenerateSpecifics(tag, value));
UpdateResponseDataList list;
list.push_back(data);
-
processor_->OnUpdateReceived(data_type_state_, list);
}
@@ -260,85 +149,30 @@ void NonBlockingTypeProcessorTest::TombstoneFromServer(int64 version_offset,
const std::string& tag) {
// Overwrite the existing server version if this is the new highest version.
std::string tag_hash = GenerateTagHash(tag);
- int64 old_version = GetServerVersion(tag_hash);
- int64 version = old_version + version_offset;
- if (version > old_version) {
- SetServerVersion(tag_hash, version);
- }
-
- UpdateResponseData data;
- data.id = GenerateId(tag_hash);
- data.client_tag_hash = tag_hash;
- data.response_version = version;
- data.ctime = base::Time::UnixEpoch() + base::TimeDelta::FromDays(1);
- data.mtime = data.ctime + base::TimeDelta::FromSeconds(version);
- data.non_unique_name = tag;
- data.deleted = true;
+
+ UpdateResponseData data =
+ mock_processor_core_->TombstoneFromServer(version_offset, tag_hash);
UpdateResponseDataList list;
list.push_back(data);
-
processor_->OnUpdateReceived(data_type_state_, list);
}
void NonBlockingTypeProcessorTest::SuccessfulCommitResponse(
const CommitRequestData& request_data) {
- const std::string& client_tag_hash = request_data.client_tag_hash;
- CommitResponseData response_data;
-
- if (request_data.base_version == 0) {
- // Server assigns new ID to newly committed items.
- DCHECK(request_data.id.empty());
- response_data.id = request_data.id;
- } else {
- // Otherwise we reuse the ID from the request.
- response_data.id = GenerateId(client_tag_hash);
- }
-
- response_data.client_tag_hash = client_tag_hash;
- response_data.sequence_number = request_data.sequence_number;
-
- // Increment the server version on successful commit.
- int64 version = GetServerVersion(client_tag_hash);
- version++;
- SetServerVersion(client_tag_hash, version);
-
- response_data.response_version = version;
-
CommitResponseDataList list;
- list.push_back(response_data);
-
+ list.push_back(mock_processor_core_->SuccessfulCommitResponse(request_data));
processor_->OnCommitCompletion(data_type_state_, list);
}
-int64 NonBlockingTypeProcessorTest::GetServerVersion(const std::string& tag) {
- std::map<const std::string, int64>::const_iterator it;
- it = server_versions_.find(tag);
- if (it == server_versions_.end()) {
- return 0;
- } else {
- return it->second;
- }
-}
-
-void NonBlockingTypeProcessorTest::SetServerVersion(const std::string& tag_hash,
- int64 version) {
- server_versions_[tag_hash] = version;
-}
-
-std::string NonBlockingTypeProcessorTest::GenerateId(
- const std::string& tag) const {
- return "FakeId:" + tag;
-}
-
std::string NonBlockingTypeProcessorTest::GenerateTagHash(
- const std::string& tag) const {
- return syncable::GenerateSyncableHash(type_, tag);
+ const std::string& tag) {
+ return syncable::GenerateSyncableHash(kModelType, tag);
}
sync_pb::EntitySpecifics NonBlockingTypeProcessorTest::GenerateSpecifics(
const std::string& tag,
- const std::string& value) const {
+ const std::string& value) {
sync_pb::EntitySpecifics specifics;
specifics.mutable_preference()->set_name(tag);
specifics.mutable_preference()->set_value(value);
@@ -346,63 +180,24 @@ sync_pb::EntitySpecifics NonBlockingTypeProcessorTest::GenerateSpecifics(
}
size_t NonBlockingTypeProcessorTest::GetNumCommitRequestLists() {
- return mock_processor_core_->commit_request_lists_.size();
+ return mock_processor_core_->GetNumCommitRequestLists();
}
CommitRequestDataList NonBlockingTypeProcessorTest::GetNthCommitRequestList(
size_t n) {
- DCHECK_LT(n, GetNumCommitRequestLists());
- return mock_processor_core_->commit_request_lists_[n];
+ return mock_processor_core_->GetNthCommitRequestList(n);
}
bool NonBlockingTypeProcessorTest::HasCommitRequestForTag(
const std::string& tag) {
const std::string tag_hash = GenerateTagHash(tag);
- const std::vector<CommitRequestDataList>& lists =
- mock_processor_core_->commit_request_lists_;
-
- // Iterate backward through the sets of commit requests to find the most
- // recent one that applies to the specified tag.
- for (std::vector<CommitRequestDataList>::const_reverse_iterator lists_it =
- lists.rbegin();
- lists_it != lists.rend();
- ++lists_it) {
- for (CommitRequestDataList::const_iterator it = lists_it->begin();
- it != lists_it->end();
- ++it) {
- if (it->client_tag_hash == tag_hash) {
- return true;
- }
- }
- }
-
- return false;
+ return mock_processor_core_->HasCommitRequestForTagHash(tag_hash);
}
CommitRequestData NonBlockingTypeProcessorTest::GetLatestCommitRequestForTag(
const std::string& tag) {
const std::string tag_hash = GenerateTagHash(tag);
- const std::vector<CommitRequestDataList>& lists =
- mock_processor_core_->commit_request_lists_;
-
- // Iterate backward through the sets of commit requests to find the most
- // recent one that applies to the specified tag.
- for (std::vector<CommitRequestDataList>::const_reverse_iterator lists_it =
- lists.rbegin();
- lists_it != lists.rend();
- ++lists_it) {
- for (CommitRequestDataList::const_iterator it = lists_it->begin();
- it != lists_it->end();
- ++it) {
- if (it->client_tag_hash == tag_hash) {
- return *it;
- }
- }
- }
-
- NOTREACHED() << "Could not find any commits for given tag " << tag << ". "
- << "Test should have checked HasCommitRequestForTag() first.";
- return CommitRequestData();
+ return mock_processor_core_->GetLatestCommitRequestForTagHash(tag_hash);
}
// Creates a new item locally.
diff --git a/sync/sync_tests.gypi b/sync/sync_tests.gypi
index d11dbde..4cb5d17 100644
--- a/sync/sync_tests.gypi
+++ b/sync/sync_tests.gypi
@@ -40,6 +40,8 @@
'test/engine/fake_sync_scheduler.h',
'test/engine/mock_connection_manager.cc',
'test/engine/mock_connection_manager.h',
+ 'test/engine/mock_non_blocking_type_processor_core.cc',
+ 'test/engine/mock_non_blocking_type_processor_core.h',
'test/engine/mock_update_handler.cc',
'test/engine/mock_update_handler.h',
'test/engine/test_directory_setter_upper.cc',
@@ -47,6 +49,8 @@
'test/engine/test_id_factory.h',
'test/engine/test_syncable_utils.cc',
'test/engine/test_syncable_utils.h',
+ 'test/engine/injectable_sync_core_proxy.cc',
+ 'test/engine/injectable_sync_core_proxy.h',
'test/fake_encryptor.cc',
'test/fake_encryptor.h',
'test/fake_sync_encryption_handler.cc',
diff --git a/sync/test/engine/injectable_sync_core_proxy.cc b/sync/test/engine/injectable_sync_core_proxy.cc
new file mode 100644
index 0000000..ac96ca4
--- /dev/null
+++ b/sync/test/engine/injectable_sync_core_proxy.cc
@@ -0,0 +1,51 @@
+// 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/injectable_sync_core_proxy.h"
+
+#include "sync/engine/non_blocking_type_processor.h"
+#include "sync/engine/non_blocking_type_processor_core_interface.h"
+
+namespace syncer {
+
+InjectableSyncCoreProxy::InjectableSyncCoreProxy(
+ NonBlockingTypeProcessorCoreInterface* core)
+ : is_core_connected_(false), processor_core_(core) {
+}
+
+InjectableSyncCoreProxy::~InjectableSyncCoreProxy() {
+}
+
+void InjectableSyncCoreProxy::ConnectTypeToCore(
+ syncer::ModelType type,
+ const DataTypeState& data_type_state,
+ base::WeakPtr<syncer::NonBlockingTypeProcessor> type_processor) {
+ // This class is allowed to participate in only one connection.
+ DCHECK(!is_core_connected_);
+ is_core_connected_ = true;
+
+ // Hands off ownership of our member to the type_processor, while keeping
+ // an unsafe pointer to it. This is why we can only connect once.
+ scoped_ptr<NonBlockingTypeProcessorCoreInterface> core(processor_core_);
+
+ type_processor->OnConnect(core.Pass());
+}
+
+void InjectableSyncCoreProxy::Disconnect(syncer::ModelType type) {
+ // This mock object is not meant for connect and disconnect tests.
+ NOTREACHED() << "Not implemented";
+}
+
+scoped_ptr<SyncCoreProxy> InjectableSyncCoreProxy::Clone() const {
+ // This confuses ownership. We trust that our callers are well-behaved.
+ return scoped_ptr<SyncCoreProxy>(
+ new InjectableSyncCoreProxy(processor_core_));
+}
+
+NonBlockingTypeProcessorCoreInterface*
+InjectableSyncCoreProxy::GetProcessorCore() {
+ return processor_core_;
+}
+
+} // namespace syncer
diff --git a/sync/test/engine/injectable_sync_core_proxy.h b/sync/test/engine/injectable_sync_core_proxy.h
new file mode 100644
index 0000000..2dc273d
--- /dev/null
+++ b/sync/test/engine/injectable_sync_core_proxy.h
@@ -0,0 +1,47 @@
+// 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.
+
+#ifndef SYNC_TEST_ENGINE_INJECTABLE_SYNC_CORE_PROXY_H_
+#define SYNC_TEST_ENGINE_INJECTABLE_SYNC_CORE_PROXY_H_
+
+#include "sync/internal_api/public/base/model_type.h"
+#include "sync/internal_api/public/sync_core_proxy.h"
+
+namespace syncer {
+
+struct DataTypeState;
+class NonBlockingTypeProcessor;
+class NonBlockingTypeProcessorCoreInterface;
+
+// A SyncCoreProxy implementation that, when a connection request is made,
+// initalizes a connection to a previously injected NonBlockingTypeProcessor.
+class InjectableSyncCoreProxy : public syncer::SyncCoreProxy {
+ public:
+ explicit InjectableSyncCoreProxy(NonBlockingTypeProcessorCoreInterface* core);
+ virtual ~InjectableSyncCoreProxy();
+
+ virtual void ConnectTypeToCore(
+ syncer::ModelType type,
+ const DataTypeState& data_type_state,
+ base::WeakPtr<syncer::NonBlockingTypeProcessor> type_processor) OVERRIDE;
+ virtual void Disconnect(syncer::ModelType type) OVERRIDE;
+ virtual scoped_ptr<SyncCoreProxy> Clone() const OVERRIDE;
+
+ NonBlockingTypeProcessorCoreInterface* GetProcessorCore();
+
+ private:
+ // A flag to ensure ConnectTypeToCore is called at most once.
+ bool is_core_connected_;
+
+ // The NonBlockingTypeProcessor's contract expects that it gets to own this
+ // object, so we can retain only a non-owned pointer to it.
+ //
+ // This is very unsafe, but we can get away with it since these tests are not
+ // exercising the processor <-> processor_core connection code.
+ NonBlockingTypeProcessorCoreInterface* processor_core_;
+};
+
+} // namespace syncer
+
+#endif // SYNC_TEST_ENGINE_INJECTABLE_SYNC_CORE_PROXY_H_
diff --git a/sync/test/engine/mock_non_blocking_type_processor_core.cc b/sync/test/engine/mock_non_blocking_type_processor_core.cc
new file mode 100644
index 0000000..b164c2a
--- /dev/null
+++ b/sync/test/engine/mock_non_blocking_type_processor_core.cc
@@ -0,0 +1,175 @@
+// 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_core.h"
+
+#include "base/logging.h"
+
+namespace syncer {
+
+MockNonBlockingTypeProcessorCore::MockNonBlockingTypeProcessorCore() {
+}
+
+MockNonBlockingTypeProcessorCore::~MockNonBlockingTypeProcessorCore() {
+}
+
+void MockNonBlockingTypeProcessorCore::RequestCommits(
+ const CommitRequestDataList& list) {
+ commit_request_lists_.push_back(list);
+}
+
+size_t MockNonBlockingTypeProcessorCore::GetNumCommitRequestLists() const {
+ return commit_request_lists_.size();
+}
+
+CommitRequestDataList MockNonBlockingTypeProcessorCore::GetNthCommitRequestList(
+ size_t n) const {
+ DCHECK_LT(n, GetNumCommitRequestLists());
+ return commit_request_lists_[n];
+}
+
+bool MockNonBlockingTypeProcessorCore::HasCommitRequestForTagHash(
+ const std::string& tag_hash) const {
+ // Iterate backward through the sets of commit requests to find the most
+ // recent one that applies to the specified tag_hash.
+ for (std::vector<CommitRequestDataList>::const_reverse_iterator lists_it =
+ commit_request_lists_.rbegin();
+ lists_it != commit_request_lists_.rend();
+ ++lists_it) {
+ for (CommitRequestDataList::const_iterator it = lists_it->begin();
+ it != lists_it->end();
+ ++it) {
+ if (it->client_tag_hash == tag_hash) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+CommitRequestData
+MockNonBlockingTypeProcessorCore::GetLatestCommitRequestForTagHash(
+ const std::string& tag_hash) const {
+ // Iterate backward through the sets of commit requests to find the most
+ // recent one that applies to the specified tag_hash.
+ for (std::vector<CommitRequestDataList>::const_reverse_iterator lists_it =
+ commit_request_lists_.rbegin();
+ lists_it != commit_request_lists_.rend();
+ ++lists_it) {
+ for (CommitRequestDataList::const_iterator it = lists_it->begin();
+ it != lists_it->end();
+ ++it) {
+ if (it->client_tag_hash == tag_hash) {
+ return *it;
+ }
+ }
+ }
+
+ NOTREACHED() << "Could not find commit for tag hash " << tag_hash << ".";
+ return CommitRequestData();
+}
+
+UpdateResponseData MockNonBlockingTypeProcessorCore::UpdateFromServer(
+ int64 version_offset,
+ const std::string& tag_hash,
+ const sync_pb::EntitySpecifics& specifics) {
+ // Overwrite the existing server version if this is the new highest version.
+ int64 old_version = GetServerVersion(tag_hash);
+ int64 version = old_version + version_offset;
+ if (version > old_version) {
+ SetServerVersion(tag_hash, version);
+ }
+
+ UpdateResponseData data;
+ data.id = GenerateId(tag_hash);
+ data.client_tag_hash = tag_hash;
+ data.response_version = version;
+ data.deleted = false;
+ data.specifics = specifics;
+
+ // These elements should have no effect on behavior, but we set them anyway
+ // so we can test they are properly copied around the system if we want to.
+ data.ctime = base::Time::UnixEpoch() + base::TimeDelta::FromDays(1);
+ data.mtime = data.ctime + base::TimeDelta::FromSeconds(version);
+ data.non_unique_name = specifics.preference().name();
+
+ return data;
+}
+
+UpdateResponseData MockNonBlockingTypeProcessorCore::TombstoneFromServer(
+ int64 version_offset,
+ const std::string& tag_hash) {
+ int64 old_version = GetServerVersion(tag_hash);
+ int64 version = old_version + version_offset;
+ if (version > old_version) {
+ SetServerVersion(tag_hash, version);
+ }
+
+ UpdateResponseData data;
+ data.id = GenerateId(tag_hash);
+ data.client_tag_hash = tag_hash;
+ data.response_version = version;
+ data.deleted = true;
+
+ // These elements should have no effect on behavior, but we set them anyway
+ // so we can test they are properly copied around the system if we want to.
+ data.ctime = base::Time::UnixEpoch() + base::TimeDelta::FromDays(1);
+ data.mtime = data.ctime + base::TimeDelta::FromSeconds(version);
+ data.non_unique_name = "Name Non Unique";
+
+ return data;
+}
+
+CommitResponseData MockNonBlockingTypeProcessorCore::SuccessfulCommitResponse(
+ const CommitRequestData& request_data) {
+ const std::string& client_tag_hash = request_data.client_tag_hash;
+
+ CommitResponseData response_data;
+
+ if (request_data.base_version == 0) {
+ // Server assigns new ID to newly committed items.
+ DCHECK(request_data.id.empty());
+ response_data.id = request_data.id;
+ } else {
+ // Otherwise we reuse the ID from the request.
+ response_data.id = GenerateId(client_tag_hash);
+ }
+
+ response_data.client_tag_hash = client_tag_hash;
+ response_data.sequence_number = request_data.sequence_number;
+
+ // Increment the server version on successful commit.
+ int64 version = GetServerVersion(client_tag_hash);
+ version++;
+ SetServerVersion(client_tag_hash, version);
+
+ response_data.response_version = version;
+
+ return response_data;
+}
+
+std::string MockNonBlockingTypeProcessorCore::GenerateId(
+ const std::string& tag_hash) {
+ return "FakeId:" + tag_hash;
+}
+
+int64 MockNonBlockingTypeProcessorCore::GetServerVersion(
+ const std::string& tag_hash) {
+ std::map<const std::string, int64>::const_iterator it;
+ it = server_versions_.find(tag_hash);
+ if (it == server_versions_.end()) {
+ return 0;
+ } else {
+ return it->second;
+ }
+}
+
+void MockNonBlockingTypeProcessorCore::SetServerVersion(
+ const std::string& tag_hash,
+ int64 version) {
+ server_versions_[tag_hash] = version;
+}
+
+} // namespace syncer
diff --git a/sync/test/engine/mock_non_blocking_type_processor_core.h b/sync/test/engine/mock_non_blocking_type_processor_core.h
new file mode 100644
index 0000000..2ee73a4
--- /dev/null
+++ b/sync/test/engine/mock_non_blocking_type_processor_core.h
@@ -0,0 +1,82 @@
+// 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.
+
+#ifndef SYNC_TEST_ENGINE_MOCK_NON_BLOCKING_TYPE_PROCESSOR_CORE_H_
+#define SYNC_TEST_ENGINE_MOCK_NON_BLOCKING_TYPE_PROCESSOR_CORE_H_
+
+#include <vector>
+
+#include "base/macros.h"
+#include "sync/engine/non_blocking_sync_common.h"
+#include "sync/engine/non_blocking_type_processor_core_interface.h"
+
+namespace syncer {
+
+// Receives and records commit requests sent through the
+// NonBlockingTypeProcessorCoreInterface.
+//
+// This class also includes features intended to help mock out server behavior.
+// It has some basic functionality to keep track of server state and generate
+// plausible UpdateResponseData and CommitResponseData messages.
+class MockNonBlockingTypeProcessorCore
+ : public NonBlockingTypeProcessorCoreInterface {
+ public:
+ MockNonBlockingTypeProcessorCore();
+ virtual ~MockNonBlockingTypeProcessorCore();
+
+ // Implementation of NonBlockingTypeProcessorCoreInterface.
+ virtual void RequestCommits(const CommitRequestDataList& list) OVERRIDE;
+
+ // Getters to inspect the requests sent to this object.
+ size_t GetNumCommitRequestLists() const;
+ CommitRequestDataList GetNthCommitRequestList(size_t n) const;
+ bool HasCommitRequestForTagHash(const std::string& tag_hash) const;
+ CommitRequestData GetLatestCommitRequestForTagHash(
+ const std::string& tag_hash) const;
+
+ // Functions to produce state as though it came from a real server and had
+ // been filtered through a real NonBlockinTypeProcessorCore.
+
+ // Returns an UpdateResponseData representing an update received from
+ // the server. Updates server state accordingly.
+ //
+ // The |version_offset| field can be used to emulate stale data (ie. versions
+ // going backwards), reflections and redeliveries (ie. several instances of
+ // the same version) or new updates.
+ UpdateResponseData UpdateFromServer(
+ int64 version_offset,
+ const std::string& tag_hash,
+ const sync_pb::EntitySpecifics& specifics);
+
+ // Returns an UpdateResponseData representing a tombstone update from the
+ // server. Updates server state accordingly.
+ UpdateResponseData TombstoneFromServer(int64 version_offset,
+ const std::string& tag_hash);
+
+ // Returns a commit response that indicates a successful commit of the
+ // given |request_data|. Updates server state accordingly.
+ CommitResponseData SuccessfulCommitResponse(
+ const CommitRequestData& request_data);
+
+ private:
+ // Generate an ID string.
+ static std::string GenerateId(const std::string& tag_hash);
+
+ // Retrieve or set the server version.
+ int64 GetServerVersion(const std::string& tag_hash);
+ void SetServerVersion(const std::string& tag_hash, int64 version);
+
+ // A record of past commits requests.
+ std::vector<CommitRequestDataList> commit_request_lists_;
+
+ // Map of versions by client tag.
+ // This is an essential part of the mocked server state.
+ std::map<const std::string, int64> server_versions_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockNonBlockingTypeProcessorCore);
+};
+
+} // namespace syncer
+
+#endif // SYNC_TEST_ENGINE_MOCK_NON_BLOCKING_TYPE_PROCESSOR_CORE_H_