summaryrefslogtreecommitdiffstats
path: root/sync/test
diff options
context:
space:
mode:
Diffstat (limited to 'sync/test')
-rw-r--r--sync/test/fake_server/fake_server.cc71
-rw-r--r--sync/test/fake_server/fake_server.h63
-rw-r--r--sync/test/fake_server/fake_server_http_post_provider.cc43
-rw-r--r--sync/test/fake_server/fake_server_http_post_provider.h20
-rw-r--r--sync/test/fake_server/fake_server_network_resources.cc5
5 files changed, 140 insertions, 62 deletions
diff --git a/sync/test/fake_server/fake_server.cc b/sync/test/fake_server/fake_server.cc
index d758e5d..798797e 100644
--- a/sync/test/fake_server/fake_server.cc
+++ b/sync/test/fake_server/fake_server.cc
@@ -4,6 +4,7 @@
#include "sync/test/fake_server/fake_server.h"
+#include <algorithm>
#include <limits>
#include <string>
#include <vector>
@@ -29,7 +30,6 @@
using std::string;
using std::vector;
-using base::AutoLock;
using syncer::GetModelType;
using syncer::ModelType;
using syncer::ModelTypeSet;
@@ -238,11 +238,8 @@ void FakeServer::SaveEntity(FakeServerEntity* entity) {
entities_[entity->GetId()] = entity;
}
-int FakeServer::HandleCommand(const string& request,
- int* response_code,
- string* response) {
- AutoLock lock(lock_);
-
+void FakeServer::HandleCommand(const string& request,
+ const HandleCommandCallback& callback) {
sync_pb::ClientToServerMessage message;
bool parsed = message.ParseFromString(request);
DCHECK(parsed);
@@ -259,20 +256,20 @@ int FakeServer::HandleCommand(const string& request,
response_proto.mutable_commit());
break;
default:
- return net::ERR_NOT_IMPLEMENTED;
+ callback.Run(net::ERR_NOT_IMPLEMENTED, 0, string());;
+ return;
}
if (!success) {
// TODO(pvalenzuela): Add logging here so that tests have more info about
// the failure.
- return net::HTTP_BAD_REQUEST;
+ callback.Run(net::ERR_FAILED, 0, string());
+ return;
}
response_proto.set_error_code(sync_pb::SyncEnums::SUCCESS);
response_proto.set_store_birthday(birthday_);
- *response_code = net::HTTP_OK;
- *response = response_proto.SerializeAsString();
- return 0;
+ callback.Run(0, net::HTTP_OK, response_proto.SerializeAsString());
}
bool FakeServer::HandleGetUpdatesRequest(
@@ -324,13 +321,13 @@ bool FakeServer::HandleGetUpdatesRequest(
return true;
}
-bool FakeServer::CommitEntity(
+string FakeServer::CommitEntity(
const sync_pb::SyncEntity& client_entity,
sync_pb::CommitResponse_EntryResponse* entry_response,
string client_guid,
- std::map<string, string>* client_to_server_ids) {
+ string parent_id) {
if (client_entity.version() == 0 && client_entity.deleted()) {
- return false;
+ return string();
}
FakeServerEntity* entity;
@@ -339,7 +336,7 @@ bool FakeServer::CommitEntity(
// TODO(pvalenzuela): Change the behavior of DeleteChilden so that it does
// not modify server data if it fails.
if (!DeleteChildren(client_entity.id_string())) {
- return false;
+ return string();
}
} else if (GetModelType(client_entity) == syncer::NIGORI) {
// NIGORI is the only permanent item type that should be updated by the
@@ -356,11 +353,6 @@ bool FakeServer::CommitEntity(
entity = UniqueClientEntity::CreateNew(client_entity);
}
} else {
- string parent_id = client_entity.parent_id_string();
- if (client_to_server_ids->find(parent_id) !=
- client_to_server_ids->end()) {
- parent_id = (*client_to_server_ids)[parent_id];
- }
// TODO(pvalenzuela): Validate entity's parent ID.
if (entities_.find(client_entity.id_string()) != entities_.end()) {
entity = BookmarkEntity::CreateUpdatedVersion(
@@ -375,17 +367,12 @@ bool FakeServer::CommitEntity(
if (entity == NULL) {
// TODO(pvalenzuela): Add logging so that it is easier to determine why
// creation failed.
- return false;
- }
-
- // Record the ID if it was renamed.
- if (client_entity.id_string() != entity->GetId()) {
- (*client_to_server_ids)[client_entity.id_string()] = entity->GetId();
+ return string();
}
SaveEntity(entity);
BuildEntryResponseForSuccessfulCommit(entry_response, entity);
- return true;
+ return entity->GetId();
}
void FakeServer::BuildEntryResponseForSuccessfulCommit(
@@ -442,6 +429,7 @@ bool FakeServer::HandleCommitRequest(
sync_pb::CommitResponse* response) {
std::map<string, string> client_to_server_ids;
string guid = commit.cache_guid();
+ ModelTypeSet committed_model_types;
// TODO(pvalenzuela): Add validation of CommitMessage.entries.
::google::protobuf::RepeatedPtrField<sync_pb::SyncEntity>::const_iterator it;
@@ -449,11 +437,30 @@ bool FakeServer::HandleCommitRequest(
sync_pb::CommitResponse_EntryResponse* entry_response =
response->add_entryresponse();
- if (!CommitEntity(*it, entry_response, guid, &client_to_server_ids)) {
+ sync_pb::SyncEntity client_entity = *it;
+ string parent_id = client_entity.parent_id_string();
+ if (client_to_server_ids.find(parent_id) !=
+ client_to_server_ids.end()) {
+ parent_id = client_to_server_ids[parent_id];
+ }
+
+ string entity_id = CommitEntity(client_entity,
+ entry_response,
+ guid,
+ parent_id);
+ if (entity_id.empty()) {
return false;
}
+
+ // Record the ID if it was renamed.
+ if (entity_id != client_entity.id_string()) {
+ client_to_server_ids[client_entity.id_string()] = entity_id;
+ }
+ FakeServerEntity* entity = entities_[entity_id];
+ committed_model_types.Put(entity->GetModelType());
}
+ FOR_EACH_OBSERVER(Observer, observers_, OnCommit(committed_model_types));
return true;
}
@@ -489,4 +496,12 @@ scoped_ptr<base::DictionaryValue> FakeServer::GetEntitiesAsDictionaryValue() {
return dictionary.Pass();
}
+void FakeServer::AddObserver(Observer* observer) {
+ observers_.AddObserver(observer);
+}
+
+void FakeServer::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
} // namespace fake_server
diff --git a/sync/test/fake_server/fake_server.h b/sync/test/fake_server/fake_server.h
index 0621bbc..6af77ab 100644
--- a/sync/test/fake_server/fake_server.h
+++ b/sync/test/fake_server/fake_server.h
@@ -7,10 +7,12 @@
#include <map>
#include <string>
+#include <vector>
#include "base/basictypes.h"
+#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
-#include "base/synchronization/lock.h"
+#include "base/observer_list.h"
#include "base/values.h"
#include "sync/internal_api/public/base/model_type.h"
#include "sync/protocol/sync.pb.h"
@@ -21,15 +23,26 @@ namespace fake_server {
// A fake version of the Sync server used for testing.
class FakeServer {
public:
+ typedef base::Callback<void(int, int, const std::string&)>
+ HandleCommandCallback;
+
+ class Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Called after FakeServer has processed a successful commit. The types
+ // updated as part of the commit are passed in |committed_model_types|.
+ virtual void OnCommit(syncer::ModelTypeSet committed_model_types) = 0;
+ };
+
FakeServer();
virtual ~FakeServer();
- // Handles a /command POST to the server. If the return value is 0 (success),
- // |response_code| and |response| will be set. Otherwise, the return value
- // will be a network error code.
- int HandleCommand(const std::string& request,
- int* response_code,
- std::string* response);
+ // Asynchronously handles a /command POST to the server. If the error_code is
+ // passed to |callback| is 0 (success), the POST's response code and content
+ // will also be passed.
+ void HandleCommand(const std::string& request,
+ const HandleCommandCallback& callback);
// Creates a DicionaryValue representation of all entities present in the
// server. The dictionary keys are the strings generated by ModelTypeToString
@@ -37,6 +50,14 @@ class FakeServer {
// names.
scoped_ptr<base::DictionaryValue> GetEntitiesAsDictionaryValue();
+ // Adds |observer| to FakeServer's observer list. This should be called
+ // before the Profile associated with |observer| is connected to the server.
+ void AddObserver(Observer* observer);
+
+ // Removes |observer| from the FakeServer's observer list. This method
+ // must be called if AddObserver was ever called with |observer|.
+ void RemoveObserver(Observer* observer);
+
private:
typedef std::map<std::string, FakeServerEntity*> EntityMap;
@@ -59,14 +80,15 @@ class FakeServer {
void SaveEntity(FakeServerEntity* entity);
// Commits a client-side SyncEntity to the server as a FakeServerEntity.
- // The client that sent the commit is identified via |client_guid| and all
- // entity ID renaming is tracked with |client_to_server_ids|. If the commit
- // is successful, true is returned and the server's version of the SyncEntity
- // is stored in |server_entity|.
- bool CommitEntity(const sync_pb::SyncEntity& client_entity,
- sync_pb::CommitResponse_EntryResponse* entry_response,
- std::string client_guid,
- std::map<std::string, std::string>* client_to_server_ids);
+ // The client that sent the commit is identified via |client_guid|. The
+ // parent ID string present in |client_entity| should be ignored in favor
+ // of |parent_id|. If the commit is successful, the entity's server ID string
+ // is returned and a new FakeServerEntity is saved in |entities_|.
+ std::string CommitEntity(
+ const sync_pb::SyncEntity& client_entity,
+ sync_pb::CommitResponse_EntryResponse* entry_response,
+ std::string client_guid,
+ std::string parent_id);
// Populates |entry_response| based on |entity|. It is assumed that
// SaveEntity has already been called on |entity|.
@@ -82,14 +104,6 @@ class FakeServer {
// |id|. A tombstone is not created for the entity itself.
bool DeleteChildren(const std::string& id);
- // The lock used to ensure that only one client is communicating with server
- // at any given time.
- //
- // It is probably preferable to have FakeServer operate on its own thread and
- // communicate with it via PostTask, but clients would still need to wait for
- // requests to finish before proceeding.
- base::Lock lock_;
-
// This is the last version number assigned to an entity. The next entity will
// have a version number of version_ + 1.
int64 version_;
@@ -108,6 +122,9 @@ class FakeServer {
// are kept track of so that permanent entities are not recreated for new
// clients.
syncer::ModelTypeSet created_permanent_entity_types_;
+
+ // FakeServer's observers.
+ ObserverList<Observer, true> observers_;
};
} // namespace fake_server
diff --git a/sync/test/fake_server/fake_server_http_post_provider.cc b/sync/test/fake_server/fake_server_http_post_provider.cc
index e0b3436..fbfe16f 100644
--- a/sync/test/fake_server/fake_server_http_post_provider.cc
+++ b/sync/test/fake_server/fake_server_http_post_provider.cc
@@ -6,6 +6,11 @@
#include <string>
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
+#include "base/synchronization/waitable_event.h"
#include "sync/test/fake_server/fake_server.h"
using syncer::HttpPostProviderInterface;
@@ -13,7 +18,9 @@ using syncer::HttpPostProviderInterface;
namespace fake_server {
FakeServerHttpPostProviderFactory::FakeServerHttpPostProviderFactory(
- FakeServer* fake_server) : fake_server_(fake_server) { }
+ FakeServer* fake_server,
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : fake_server_(fake_server), task_runner_(task_runner) { }
FakeServerHttpPostProviderFactory::~FakeServerHttpPostProviderFactory() { }
@@ -21,7 +28,7 @@ void FakeServerHttpPostProviderFactory::Init(const std::string& user_agent) { }
HttpPostProviderInterface* FakeServerHttpPostProviderFactory::Create() {
FakeServerHttpPostProvider* http =
- new FakeServerHttpPostProvider(fake_server_);
+ new FakeServerHttpPostProvider(fake_server_, task_runner_);
http->AddRef();
return http;
}
@@ -32,7 +39,11 @@ void FakeServerHttpPostProviderFactory::Destroy(
}
FakeServerHttpPostProvider::FakeServerHttpPostProvider(
- FakeServer* fake_server) : fake_server_(fake_server) { }
+ FakeServer* fake_server,
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : fake_server_(fake_server),
+ task_runner_(task_runner),
+ post_complete_(false, false) { }
FakeServerHttpPostProvider::~FakeServerHttpPostProvider() { }
@@ -54,13 +65,29 @@ void FakeServerHttpPostProvider::SetPostPayload(const char* content_type,
request_content_.assign(content, content_length);
}
+void FakeServerHttpPostProvider::OnPostComplete(int error_code,
+ int response_code,
+ const std::string& response) {
+ post_error_code_ = error_code;
+ post_response_code_ = response_code;
+ response_ = response;
+ post_complete_.Signal();
+}
+
bool FakeServerHttpPostProvider::MakeSynchronousPost(int* error_code,
int* response_code) {
- // This assumes that a POST is being made to /command.
- *error_code = fake_server_->HandleCommand(request_content_,
- response_code,
- &response_);
- return (*error_code == 0);
+ // It is assumed that a POST is being made to /command.
+ FakeServer::HandleCommandCallback callback = base::Bind(
+ &FakeServerHttpPostProvider::OnPostComplete, base::Unretained(this));
+ task_runner_->PostNonNestableTask(FROM_HERE,
+ base::Bind(&FakeServer::HandleCommand,
+ base::Unretained(fake_server_),
+ base::ConstRef(request_content_),
+ base::ConstRef(callback)));
+ post_complete_.Wait();
+ *error_code = post_error_code_;
+ *response_code = post_response_code_;
+ return *error_code == 0;
}
int FakeServerHttpPostProvider::GetResponseContentLength() const {
diff --git a/sync/test/fake_server/fake_server_http_post_provider.h b/sync/test/fake_server/fake_server_http_post_provider.h
index 63f1eda..9e2aa0e 100644
--- a/sync/test/fake_server/fake_server_http_post_provider.h
+++ b/sync/test/fake_server/fake_server_http_post_provider.h
@@ -8,6 +8,8 @@
#include <string>
#include "base/memory/ref_counted.h"
+#include "base/sequenced_task_runner.h"
+#include "base/synchronization/waitable_event.h"
#include "sync/internal_api/public/http_post_provider_factory.h"
#include "sync/internal_api/public/http_post_provider_interface.h"
@@ -19,7 +21,9 @@ class FakeServerHttpPostProvider
: public syncer::HttpPostProviderInterface,
public base::RefCountedThreadSafe<FakeServerHttpPostProvider> {
public:
- explicit FakeServerHttpPostProvider(FakeServer* fake_server);
+ explicit FakeServerHttpPostProvider(
+ FakeServer* fake_server,
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
// HttpPostProviderInterface implementation.
virtual void SetExtraRequestHeaders(const char* headers) OVERRIDE;
@@ -39,13 +43,22 @@ class FakeServerHttpPostProvider
virtual ~FakeServerHttpPostProvider();
private:
+ void OnPostComplete(int error_code,
+ int response_code,
+ const std::string& response);
+
FakeServer* const fake_server_;
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
std::string response_;
std::string request_url_;
int request_port_;
std::string request_content_;
std::string request_content_type_;
std::string extra_request_headers_;
+ int post_error_code_;
+ int post_response_code_;
+ base::WaitableEvent post_complete_;
DISALLOW_COPY_AND_ASSIGN(FakeServerHttpPostProvider);
};
@@ -53,7 +66,9 @@ class FakeServerHttpPostProvider
class FakeServerHttpPostProviderFactory
: public syncer::HttpPostProviderFactory {
public:
- explicit FakeServerHttpPostProviderFactory(FakeServer* fake_server);
+ explicit FakeServerHttpPostProviderFactory(
+ FakeServer* fake_server,
+ scoped_refptr<base::SequencedTaskRunner> task_runner);
virtual ~FakeServerHttpPostProviderFactory();
// HttpPostProviderFactory:
@@ -63,6 +78,7 @@ class FakeServerHttpPostProviderFactory
private:
FakeServer* const fake_server_;
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
DISALLOW_COPY_AND_ASSIGN(FakeServerHttpPostProviderFactory);
};
diff --git a/sync/test/fake_server/fake_server_network_resources.cc b/sync/test/fake_server/fake_server_network_resources.cc
index 56d5ea2..c3bedb0 100644
--- a/sync/test/fake_server/fake_server_network_resources.cc
+++ b/sync/test/fake_server/fake_server_network_resources.cc
@@ -5,6 +5,7 @@
#include "sync/test/fake_server/fake_server_network_resources.h"
#include "base/memory/scoped_ptr.h"
+#include "base/message_loop/message_loop.h"
#include "sync/internal_api/public/base/cancelation_signal.h"
#include "sync/internal_api/public/http_post_provider_factory.h"
#include "sync/internal_api/public/network_time_update_callback.h"
@@ -28,7 +29,9 @@ scoped_ptr<syncer::HttpPostProviderFactory>
const NetworkTimeUpdateCallback& network_time_update_callback,
CancelationSignal* cancelation_signal) {
return make_scoped_ptr<syncer::HttpPostProviderFactory>(
- new FakeServerHttpPostProviderFactory(fake_server_));
+ new FakeServerHttpPostProviderFactory(
+ fake_server_,
+ base::MessageLoop::current()->message_loop_proxy()));
}
} // namespace fake_server