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 "sync/engine/net/server_connection_manager.h"
19 #include "sync/internal_api/public/base/model_type.h"
20 #include "sync/internal_api/public/base/model_type_invalidation_map.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 explicit MockConnectionManager(syncable::Directory
*);
37 virtual ~MockConnectionManager();
39 // Overridden ServerConnectionManager functions.
40 virtual bool PostBufferToPath(
42 const std::string
& path
,
43 const std::string
& auth_token
,
44 ScopedServerStatusWatcher
* watcher
) OVERRIDE
;
46 // Control of commit response.
47 // NOTE: Commit callback is invoked only once then reset.
48 void SetMidCommitCallback(const base::Closure
& callback
);
49 void SetMidCommitObserver(MidCommitObserver
* observer
);
51 // Set this if you want commit to perform commit time rename. Will request
52 // that the client renames all commited entries, prepending this string.
53 void SetCommitTimeRename(std::string prepend
);
55 // Generic versions of AddUpdate functions. Tests using these function should
56 // compile for both the int64 and string id based versions of the server.
57 // The SyncEntity returned is only valid until the Sync is completed
58 // (e.g. with SyncShare.) It allows to add further entity properties before
59 // sync, using SetLastXXX() methods and/or GetMutableLastUpdate().
60 sync_pb::SyncEntity
* AddUpdateDirectory(
62 syncable::Id parent_id
,
66 std::string originator_cache_guid
,
67 std::string originator_client_item_id
);
68 sync_pb::SyncEntity
* AddUpdateBookmark(syncable::Id id
,
69 syncable::Id parent_id
,
73 std::string originator_cache_guid
,
74 std::string originator_client_item_id
);
75 // Versions of the AddUpdate functions that accept integer IDs.
76 sync_pb::SyncEntity
* AddUpdateDirectory(
82 std::string originator_cache_guid
,
83 std::string originator_client_item_id
);
84 sync_pb::SyncEntity
* AddUpdateBookmark(int id
,
89 std::string originator_cache_guid
,
90 std::string originator_client_item_id
);
91 // New protocol versions of the AddUpdate functions.
92 sync_pb::SyncEntity
* AddUpdateDirectory(
94 std::string parent_id
,
98 std::string originator_cache_guid
,
99 std::string originator_client_item_id
);
100 sync_pb::SyncEntity
* AddUpdateBookmark(std::string id
,
101 std::string parent_id
,
105 std::string originator_cache_guid
,
106 std::string originator_client_item_id
);
107 // Versions of the AddUpdate function that accept specifics.
108 sync_pb::SyncEntity
* AddUpdateSpecifics(
116 const sync_pb::EntitySpecifics
& specifics
);
117 sync_pb::SyncEntity
* AddUpdateSpecifics(
125 const sync_pb::EntitySpecifics
& specifics
,
126 std::string originator_cache_guid
,
127 std::string originator_client_item_id
);
128 sync_pb::SyncEntity
* SetNigori(
132 const sync_pb::EntitySpecifics
& specifics
);
133 // Unique client tag variant for adding items.
134 sync_pb::SyncEntity
* AddUpdatePref(std::string id
,
135 std::string parent_id
,
136 std::string client_tag
,
140 // Find the last commit sent by the client, and replay it for the next get
141 // updates command. This can be used to simulate the GetUpdates that happens
142 // immediately after a successful commit.
143 sync_pb::SyncEntity
* AddUpdateFromLastCommit();
145 // Add a deleted item. Deletion records typically contain no
146 // additional information beyond the deletion, and no specifics.
147 // The server may send the originator fields.
148 void AddUpdateTombstone(const syncable::Id
& id
);
150 void SetLastUpdateDeleted();
151 void SetLastUpdateServerTag(const std::string
& tag
);
152 void SetLastUpdateClientTag(const std::string
& tag
);
153 void SetLastUpdateOriginatorFields(const std::string
& client_id
,
154 const std::string
& entry_id
);
155 void SetLastUpdatePosition(int64 position_in_parent
);
156 void SetNewTimestamp(int ts
);
157 void SetChangesRemaining(int64 count
);
159 // Add a new batch of updates after the current one. Allows multiple
160 // GetUpdates responses to be buffered up, since the syncer may
161 // issue multiple requests during a sync cycle.
162 void NextUpdateBatch();
164 void FailNextPostBufferToPathCall() { countdown_to_postbuffer_fail_
= 1; }
165 void FailNthPostBufferToPathCall(int n
) { countdown_to_postbuffer_fail_
= n
; }
167 void SetKeystoreKey(const std::string
& key
);
169 void FailNonPeriodicGetUpdates() { fail_non_periodic_get_updates_
= true; }
171 // Simple inspectors.
172 bool client_stuck() const { return client_stuck_
; }
174 // warning: These take ownership of their input.
175 void SetGUClientCommand(sync_pb::ClientCommand
* command
);
176 void SetCommitClientCommand(sync_pb::ClientCommand
* command
);
178 void SetTransientErrorId(syncable::Id
);
180 const std::vector
<syncable::Id
>& committed_ids() const {
181 return committed_ids_
;
183 const std::vector
<sync_pb::CommitMessage
*>& commit_messages() const {
184 return commit_messages_
.get();
186 const std::vector
<sync_pb::CommitResponse
*>& commit_responses() const {
187 return commit_responses_
.get();
189 // Retrieve the last sent commit message.
190 const sync_pb::CommitMessage
& last_sent_commit() const;
192 // Retrieve the last returned commit response.
193 const sync_pb::CommitResponse
& last_commit_response() const;
195 // Retrieve the last request submitted to the server (regardless of type).
196 const sync_pb::ClientToServerMessage
& last_request() const {
197 return last_request_
;
200 void set_conflict_all_commits(bool value
) {
201 conflict_all_commits_
= value
;
203 void set_next_new_id(int value
) {
204 next_new_id_
= value
;
206 void set_conflict_n_commits(int value
) {
207 conflict_n_commits_
= value
;
210 void set_use_legacy_bookmarks_protocol(bool value
) {
211 use_legacy_bookmarks_protocol_
= value
;
214 void set_store_birthday(std::string new_birthday
) {
215 // Multiple threads can set store_birthday_ in our tests, need to lock it to
216 // ensure atomic read/writes and avoid race conditions.
217 base::AutoLock
lock(store_birthday_lock_
);
218 store_birthday_
= new_birthday
;
221 // Retrieve the number of GetUpdates requests that the mock server has
222 // seen since the last time this function was called. Can be used to
223 // verify that a GetUpdates actually did or did not happen after running
225 int GetAndClearNumGetUpdatesRequests() {
226 int result
= num_get_updates_requests_
;
227 num_get_updates_requests_
= 0;
231 // Expect that GetUpdates will request exactly the types indicated in
233 void ExpectGetUpdatesRequestTypes(ModelTypeSet expected_filter
) {
234 expected_filter_
= expected_filter
;
237 void ExpectGetUpdatesRequestStates(const ModelTypeInvalidationMap
& states
) {
238 expected_states_
= states
;
241 void SetServerReachable();
243 void SetServerNotReachable();
245 // Updates our internal state as if we had attempted a connection. Does not
246 // send notifications as a real connection attempt would. This is useful in
247 // cases where we're mocking out most of the code that performs network
249 void UpdateConnectionStatus();
251 void SetServerStatus(HttpResponse::ServerConnectionCode server_status
);
253 // Return by copy to be thread-safe.
254 const std::string
store_birthday() {
255 base::AutoLock
lock(store_birthday_lock_
);
256 return store_birthday_
;
259 // Explicitly indicate that we will not be fetching some updates.
260 void ClearUpdatesQueue() {
261 update_queue_
.clear();
264 // Locate the most recent update message for purpose of alteration.
265 sync_pb::SyncEntity
* GetMutableLastUpdate();
268 sync_pb::SyncEntity
* AddUpdateFull(syncable::Id id
, syncable::Id parentid
,
269 std::string name
, int64 version
,
272 sync_pb::SyncEntity
* AddUpdateFull(std::string id
,
273 std::string parentid
, std::string name
,
274 int64 version
, int64 sync_ts
,
276 sync_pb::SyncEntity
* AddUpdateMeta(std::string id
, std::string parentid
,
277 std::string name
, int64 version
,
280 // Functions to handle the various types of server request.
281 void ProcessGetUpdates(sync_pb::ClientToServerMessage
* csm
,
282 sync_pb::ClientToServerResponse
* response
);
283 void ProcessCommit(sync_pb::ClientToServerMessage
* csm
,
284 sync_pb::ClientToServerResponse
* response_buffer
);
285 void ProcessClearData(sync_pb::ClientToServerMessage
* csm
,
286 sync_pb::ClientToServerResponse
* response
);
287 void AddDefaultBookmarkData(sync_pb::SyncEntity
* entity
, bool is_folder
);
289 // Determine if one entry in a commit should be rejected with a conflict.
290 bool ShouldConflictThisCommit();
292 // Determine if the given item's commit request should be refused with
293 // a TRANSIENT_ERROR response.
294 bool ShouldTransientErrorThisId(syncable::Id id
);
296 // Generate a numeric position_in_parent value. We use a global counter
297 // that only decreases; this simulates new objects always being added to the
298 // front of the ordering.
299 int64
GeneratePositionInParent() {
300 return next_position_in_parent_
--;
303 // Get a mutable update response which will eventually be returned to the
305 sync_pb::GetUpdatesResponse
* GetUpdateResponse();
308 // Determine whether an progress marker array (like that sent in
309 // GetUpdates.from_progress_marker) indicates that a particular ModelType
310 // should be included.
311 bool IsModelTypePresentInSpecifics(
312 const google::protobuf::RepeatedPtrField
<
313 sync_pb::DataTypeProgressMarker
>& filter
,
316 sync_pb::DataTypeProgressMarker
const* GetProgressMarkerForType(
317 const google::protobuf::RepeatedPtrField
<
318 sync_pb::DataTypeProgressMarker
>& filter
,
321 // When false, we pretend to have network connectivity issues.
322 bool server_reachable_
;
324 // All IDs that have been committed.
325 std::vector
<syncable::Id
> committed_ids_
;
327 // List of IDs which should return a transient error.
328 std::vector
<syncable::Id
> transient_error_ids_
;
330 // Control of when/if we return conflicts.
331 bool conflict_all_commits_
;
332 int conflict_n_commits_
;
334 // Commit messages we've sent, and responses we've returned.
335 ScopedVector
<sync_pb::CommitMessage
> commit_messages_
;
336 ScopedVector
<sync_pb::CommitResponse
> commit_responses_
;
338 // The next id the mock will return to a commit.
341 // The store birthday we send to the client.
342 std::string store_birthday_
;
343 base::Lock store_birthday_lock_
;
344 bool store_birthday_sent_
;
346 std::string commit_time_rename_prepended_string_
;
348 // On each PostBufferToPath() call, we decrement this counter. The call fails
349 // iff we hit zero at that call.
350 int countdown_to_postbuffer_fail_
;
352 // Our directory. Used only to ensure that we are not holding the transaction
353 // lock when performing network I/O. Can be NULL if the test author is
354 // confident this can't happen.
355 syncable::Directory
* directory_
;
357 // The updates we'll return to the next request.
358 std::list
<sync_pb::GetUpdatesResponse
> update_queue_
;
359 base::Closure mid_commit_callback_
;
360 MidCommitObserver
* mid_commit_observer_
;
362 // The keystore key we return for a GetUpdates with need_encryption_key set.
363 std::string keystore_key_
;
365 // The AUTHENTICATE response we'll return for auth requests.
366 sync_pb::AuthenticateResponse auth_response_
;
367 // What we use to determine if we should return SUCCESS or BAD_AUTH_TOKEN.
368 std::string valid_auth_token_
;
370 // Whether we are faking a server mandating clients to throttle requests.
371 // Protected by |response_code_override_lock_|.
374 // Whether we are failing all requests by returning
375 // ClientToServerResponse::AUTH_INVALID.
376 // Protected by |response_code_override_lock_|.
377 bool fail_with_auth_invalid_
;
379 base::Lock response_code_override_lock_
;
381 // True if we are only accepting GetUpdatesCallerInfo::PERIODIC requests.
382 bool fail_non_periodic_get_updates_
;
384 scoped_ptr
<sync_pb::ClientCommand
> gu_client_command_
;
385 scoped_ptr
<sync_pb::ClientCommand
> commit_client_command_
;
387 // The next value to use for the position_in_parent property.
388 int64 next_position_in_parent_
;
390 // The default is to use the newer sync_pb::BookmarkSpecifics-style protocol.
391 // If this option is set to true, then the MockConnectionManager will
392 // use the older sync_pb::SyncEntity_BookmarkData-style protocol.
393 bool use_legacy_bookmarks_protocol_
;
395 ModelTypeSet expected_filter_
;
397 ModelTypeInvalidationMap expected_states_
;
399 int num_get_updates_requests_
;
401 std::string next_token_
;
403 sync_pb::ClientToServerMessage last_request_
;
405 DISALLOW_COPY_AND_ASSIGN(MockConnectionManager
);
408 } // namespace syncer
410 #endif // SYNC_TEST_ENGINE_MOCK_CONNECTION_MANAGER_H_