1 // Copyright (c) 2012 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.
5 // Mock ServerConnectionManager class for use in client unit tests.
7 #ifndef SYNC_TEST_ENGINE_MOCK_CONNECTION_MANAGER_H_
8 #define SYNC_TEST_ENGINE_MOCK_CONNECTION_MANAGER_H_
15 #include "base/callback.h"
16 #include "base/compiler_specific.h"
17 #include "base/memory/scoped_vector.h"
18 #include "base/synchronization/lock.h"
19 #include "sync/engine/net/server_connection_manager.h"
20 #include "sync/internal_api/public/base/model_type.h"
21 #include "sync/internal_api/public/base/unique_position.h"
22 #include "sync/protocol/sync.pb.h"
26 class MockConnectionManager : public ServerConnectionManager {
28 class MidCommitObserver {
30 virtual void Observe() = 0;
33 virtual ~MidCommitObserver() {}
36 MockConnectionManager(syncable::Directory*,
37 CancelationSignal* signal);
38 virtual ~MockConnectionManager();
40 // Overridden ServerConnectionManager functions.
41 virtual bool PostBufferToPath(
43 const std::string& path,
44 const std::string& auth_token,
45 ScopedServerStatusWatcher* watcher) OVERRIDE;
47 // Control of commit response.
48 // NOTE: Commit callback is invoked only once then reset.
49 void SetMidCommitCallback(const base::Closure& callback);
50 void SetMidCommitObserver(MidCommitObserver* observer);
52 // Set this if you want commit to perform commit time rename. Will request
53 // that the client renames all commited entries, prepending this string.
54 void SetCommitTimeRename(std::string prepend);
56 // Generic versions of AddUpdate functions. Tests using these function should
57 // compile for both the int64 and string id based versions of the server.
58 // The SyncEntity returned is only valid until the Sync is completed
59 // (e.g. with SyncShare.) It allows to add further entity properties before
60 // sync, using SetLastXXX() methods and/or GetMutableLastUpdate().
61 sync_pb::SyncEntity* AddUpdateDirectory(
63 syncable::Id parent_id,
67 std::string originator_cache_guid,
68 std::string originator_client_item_id);
69 sync_pb::SyncEntity* AddUpdateBookmark(syncable::Id id,
70 syncable::Id parent_id,
74 std::string originator_cache_guid,
75 std::string originator_client_item_id);
76 // Versions of the AddUpdate functions that accept integer IDs.
77 sync_pb::SyncEntity* AddUpdateDirectory(
83 std::string originator_cache_guid,
84 std::string originator_client_item_id);
85 sync_pb::SyncEntity* AddUpdateBookmark(int id,
90 std::string originator_cache_guid,
91 std::string originator_client_item_id);
92 // New protocol versions of the AddUpdate functions.
93 sync_pb::SyncEntity* AddUpdateDirectory(
95 std::string parent_id,
99 std::string originator_cache_guid,
100 std::string originator_client_item_id);
101 sync_pb::SyncEntity* AddUpdateBookmark(std::string id,
102 std::string parent_id,
106 std::string originator_cache_guid,
107 std::string originator_client_item_id);
108 // Versions of the AddUpdate function that accept specifics.
109 sync_pb::SyncEntity* AddUpdateSpecifics(
117 const sync_pb::EntitySpecifics& specifics);
118 sync_pb::SyncEntity* AddUpdateSpecifics(
126 const sync_pb::EntitySpecifics& specifics,
127 std::string originator_cache_guid,
128 std::string originator_client_item_id);
129 sync_pb::SyncEntity* SetNigori(
133 const sync_pb::EntitySpecifics& specifics);
134 // Unique client tag variant for adding items.
135 sync_pb::SyncEntity* AddUpdatePref(std::string id,
136 std::string parent_id,
137 std::string client_tag,
141 // Find the last commit sent by the client, and replay it for the next get
142 // updates command. This can be used to simulate the GetUpdates that happens
143 // immediately after a successful commit.
144 sync_pb::SyncEntity* AddUpdateFromLastCommit();
146 // Add a deleted item. Deletion records typically contain no
147 // additional information beyond the deletion, and no specifics.
148 // The server may send the originator fields.
149 void AddUpdateTombstone(const syncable::Id& id);
151 void SetLastUpdateDeleted();
152 void SetLastUpdateServerTag(const std::string& tag);
153 void SetLastUpdateClientTag(const std::string& tag);
154 void SetLastUpdateOriginatorFields(const std::string& client_id,
155 const std::string& entry_id);
156 void SetLastUpdatePosition(int64 position_in_parent);
157 void SetNewTimestamp(int ts);
158 void SetChangesRemaining(int64 count);
160 // Add a new batch of updates after the current one. Allows multiple
161 // GetUpdates responses to be buffered up, since the syncer may
162 // issue multiple requests during a sync cycle.
163 void NextUpdateBatch();
165 void FailNextPostBufferToPathCall() { countdown_to_postbuffer_fail_ = 1; }
166 void FailNthPostBufferToPathCall(int n) { countdown_to_postbuffer_fail_ = n; }
168 void SetKeystoreKey(const std::string& key);
170 void FailNonPeriodicGetUpdates() { fail_non_periodic_get_updates_ = true; }
172 // Simple inspectors.
173 bool client_stuck() const { return client_stuck_; }
175 // warning: These take ownership of their input.
176 void SetGUClientCommand(sync_pb::ClientCommand* command);
177 void SetCommitClientCommand(sync_pb::ClientCommand* command);
179 void SetTransientErrorId(syncable::Id);
181 const std::vector<syncable::Id>& committed_ids() const {
182 return committed_ids_;
184 const std::vector<sync_pb::CommitMessage*>& commit_messages() const {
185 return commit_messages_.get();
187 const std::vector<sync_pb::CommitResponse*>& commit_responses() const {
188 return commit_responses_.get();
190 // Retrieve the last sent commit message.
191 const sync_pb::CommitMessage& last_sent_commit() const;
193 // Retrieve the last returned commit response.
194 const sync_pb::CommitResponse& last_commit_response() const;
196 // Retrieve the last request submitted to the server (regardless of type).
197 const sync_pb::ClientToServerMessage& last_request() const {
198 return last_request_;
201 void set_conflict_all_commits(bool value) {
202 conflict_all_commits_ = value;
204 void set_next_new_id(int value) {
205 next_new_id_ = value;
207 void set_conflict_n_commits(int value) {
208 conflict_n_commits_ = value;
211 void set_use_legacy_bookmarks_protocol(bool value) {
212 use_legacy_bookmarks_protocol_ = value;
215 void set_store_birthday(std::string new_birthday) {
216 // Multiple threads can set store_birthday_ in our tests, need to lock it to
217 // ensure atomic read/writes and avoid race conditions.
218 base::AutoLock lock(store_birthday_lock_);
219 store_birthday_ = new_birthday;
222 // Retrieve the number of GetUpdates requests that the mock server has
223 // seen since the last time this function was called. Can be used to
224 // verify that a GetUpdates actually did or did not happen after running
226 int GetAndClearNumGetUpdatesRequests() {
227 int result = num_get_updates_requests_;
228 num_get_updates_requests_ = 0;
232 // Expect that GetUpdates will request exactly the types indicated in
234 void ExpectGetUpdatesRequestTypes(ModelTypeSet expected_filter) {
235 expected_filter_ = expected_filter;
238 void SetServerReachable();
240 void SetServerNotReachable();
242 // Updates our internal state as if we had attempted a connection. Does not
243 // send notifications as a real connection attempt would. This is useful in
244 // cases where we're mocking out most of the code that performs network
246 void UpdateConnectionStatus();
248 void SetServerStatus(HttpResponse::ServerConnectionCode server_status);
250 // Return by copy to be thread-safe.
251 const std::string store_birthday() {
252 base::AutoLock lock(store_birthday_lock_);
253 return store_birthday_;
256 // Explicitly indicate that we will not be fetching some updates.
257 void ClearUpdatesQueue() {
258 update_queue_.clear();
261 // Locate the most recent update message for purpose of alteration.
262 sync_pb::SyncEntity* GetMutableLastUpdate();
265 sync_pb::SyncEntity* AddUpdateFull(syncable::Id id, syncable::Id parentid,
266 std::string name, int64 version,
269 sync_pb::SyncEntity* AddUpdateFull(std::string id,
270 std::string parentid, std::string name,
271 int64 version, int64 sync_ts,
273 sync_pb::SyncEntity* AddUpdateMeta(std::string id, std::string parentid,
274 std::string name, int64 version,
277 // Functions to handle the various types of server request.
278 void ProcessGetUpdates(sync_pb::ClientToServerMessage* csm,
279 sync_pb::ClientToServerResponse* response);
280 void ProcessCommit(sync_pb::ClientToServerMessage* csm,
281 sync_pb::ClientToServerResponse* response_buffer);
282 void ProcessClearData(sync_pb::ClientToServerMessage* csm,
283 sync_pb::ClientToServerResponse* response);
284 void AddDefaultBookmarkData(sync_pb::SyncEntity* entity, bool is_folder);
286 // Determine if one entry in a commit should be rejected with a conflict.
287 bool ShouldConflictThisCommit();
289 // Determine if the given item's commit request should be refused with
290 // a TRANSIENT_ERROR response.
291 bool ShouldTransientErrorThisId(syncable::Id id);
293 // Generate a numeric position_in_parent value. We use a global counter
294 // that only decreases; this simulates new objects always being added to the
295 // front of the ordering.
296 int64 GeneratePositionInParent() {
297 return next_position_in_parent_--;
300 // Get a mutable update response which will eventually be returned to the
302 sync_pb::GetUpdatesResponse* GetUpdateResponse();
305 // Determine whether an progress marker array (like that sent in
306 // GetUpdates.from_progress_marker) indicates that a particular ModelType
307 // should be included.
308 bool IsModelTypePresentInSpecifics(
309 const google::protobuf::RepeatedPtrField<
310 sync_pb::DataTypeProgressMarker>& filter,
313 sync_pb::DataTypeProgressMarker const* GetProgressMarkerForType(
314 const google::protobuf::RepeatedPtrField<
315 sync_pb::DataTypeProgressMarker>& filter,
318 // When false, we pretend to have network connectivity issues.
319 bool server_reachable_;
321 // All IDs that have been committed.
322 std::vector<syncable::Id> committed_ids_;
324 // List of IDs which should return a transient error.
325 std::vector<syncable::Id> transient_error_ids_;
327 // Control of when/if we return conflicts.
328 bool conflict_all_commits_;
329 int conflict_n_commits_;
331 // Commit messages we've sent, and responses we've returned.
332 ScopedVector<sync_pb::CommitMessage> commit_messages_;
333 ScopedVector<sync_pb::CommitResponse> commit_responses_;
335 // The next id the mock will return to a commit.
338 // The store birthday we send to the client.
339 std::string store_birthday_;
340 base::Lock store_birthday_lock_;
341 bool store_birthday_sent_;
343 std::string commit_time_rename_prepended_string_;
345 // On each PostBufferToPath() call, we decrement this counter. The call fails
346 // iff we hit zero at that call.
347 int countdown_to_postbuffer_fail_;
349 // Our directory. Used only to ensure that we are not holding the transaction
350 // lock when performing network I/O. Can be NULL if the test author is
351 // confident this can't happen.
352 syncable::Directory* directory_;
354 // The updates we'll return to the next request.
355 std::list<sync_pb::GetUpdatesResponse> update_queue_;
356 base::Closure mid_commit_callback_;
357 MidCommitObserver* mid_commit_observer_;
359 // The keystore key we return for a GetUpdates with need_encryption_key set.
360 std::string keystore_key_;
362 // The AUTHENTICATE response we'll return for auth requests.
363 sync_pb::AuthenticateResponse auth_response_;
364 // What we use to determine if we should return SUCCESS or BAD_AUTH_TOKEN.
365 std::string valid_auth_token_;
367 // Whether we are faking a server mandating clients to throttle requests.
368 // Protected by |response_code_override_lock_|.
371 // Whether we are failing all requests by returning
372 // ClientToServerResponse::AUTH_INVALID.
373 // Protected by |response_code_override_lock_|.
374 bool fail_with_auth_invalid_;
376 base::Lock response_code_override_lock_;
378 // True if we are only accepting GetUpdatesCallerInfo::PERIODIC requests.
379 bool fail_non_periodic_get_updates_;
381 scoped_ptr<sync_pb::ClientCommand> gu_client_command_;
382 scoped_ptr<sync_pb::ClientCommand> commit_client_command_;
384 // The next value to use for the position_in_parent property.
385 int64 next_position_in_parent_;
387 // The default is to use the newer sync_pb::BookmarkSpecifics-style protocol.
388 // If this option is set to true, then the MockConnectionManager will
389 // use the older sync_pb::SyncEntity_BookmarkData-style protocol.
390 bool use_legacy_bookmarks_protocol_;
392 ModelTypeSet expected_filter_;
394 int num_get_updates_requests_;
396 std::string next_token_;
398 sync_pb::ClientToServerMessage last_request_;
400 DISALLOW_COPY_AND_ASSIGN(MockConnectionManager);
403 } // namespace syncer
405 #endif // SYNC_TEST_ENGINE_MOCK_CONNECTION_MANAGER_H_