OLD | NEW |
| (Empty) |
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. | |
4 // | |
5 // Mock ServerConnectionManager class for use in client unit tests. | |
6 | |
7 #ifndef SYNC_TEST_ENGINE_MOCK_CONNECTION_MANAGER_H_ | |
8 #define SYNC_TEST_ENGINE_MOCK_CONNECTION_MANAGER_H_ | |
9 | |
10 #include <stdint.h> | |
11 | |
12 #include <bitset> | |
13 #include <list> | |
14 #include <string> | |
15 #include <vector> | |
16 | |
17 #include "base/callback.h" | |
18 #include "base/compiler_specific.h" | |
19 #include "base/macros.h" | |
20 #include "base/memory/scoped_vector.h" | |
21 #include "base/synchronization/lock.h" | |
22 #include "sync/engine/net/server_connection_manager.h" | |
23 #include "sync/internal_api/public/base/model_type.h" | |
24 #include "sync/internal_api/public/base/unique_position.h" | |
25 #include "sync/protocol/sync.pb.h" | |
26 | |
27 namespace syncer { | |
28 | |
29 class MockConnectionManager : public ServerConnectionManager { | |
30 public: | |
31 class MidCommitObserver { | |
32 public: | |
33 virtual void Observe() = 0; | |
34 | |
35 protected: | |
36 virtual ~MidCommitObserver() {} | |
37 }; | |
38 | |
39 MockConnectionManager(syncable::Directory*, | |
40 CancelationSignal* signal); | |
41 ~MockConnectionManager() override; | |
42 | |
43 // Overridden ServerConnectionManager functions. | |
44 bool PostBufferToPath(PostBufferParams*, | |
45 const std::string& path, | |
46 const std::string& auth_token) override; | |
47 | |
48 // Control of commit response. | |
49 // NOTE: Commit callback is invoked only once then reset. | |
50 void SetMidCommitCallback(const base::Closure& callback); | |
51 void SetMidCommitObserver(MidCommitObserver* observer); | |
52 | |
53 // Set this if you want commit to perform commit time rename. Will request | |
54 // that the client renames all commited entries, prepending this string. | |
55 void SetCommitTimeRename(const std::string& prepend); | |
56 | |
57 // Generic versions of AddUpdate functions. Tests using these function should | |
58 // compile for both the int64_t and string id based versions of the server. | |
59 // The SyncEntity returned is only valid until the Sync is completed | |
60 // (e.g. with SyncShare.) It allows to add further entity properties before | |
61 // sync, using SetLastXXX() methods and/or GetMutableLastUpdate(). | |
62 sync_pb::SyncEntity* AddUpdateDirectory( | |
63 syncable::Id id, | |
64 syncable::Id parent_id, | |
65 const std::string& name, | |
66 int64_t version, | |
67 int64_t sync_ts, | |
68 const std::string& originator_cache_guid, | |
69 const std::string& originator_client_item_id); | |
70 sync_pb::SyncEntity* AddUpdateBookmark( | |
71 syncable::Id id, | |
72 syncable::Id parent_id, | |
73 const std::string& name, | |
74 int64_t version, | |
75 int64_t sync_ts, | |
76 const std::string& originator_cache_guid, | |
77 const std::string& originator_client_item_id); | |
78 // Versions of the AddUpdate functions that accept integer IDs. | |
79 sync_pb::SyncEntity* AddUpdateDirectory( | |
80 int id, | |
81 int parent_id, | |
82 const std::string& name, | |
83 int64_t version, | |
84 int64_t sync_ts, | |
85 const std::string& originator_cache_guid, | |
86 const std::string& originator_client_item_id); | |
87 sync_pb::SyncEntity* AddUpdateBookmark( | |
88 int id, | |
89 int parent_id, | |
90 const std::string& name, | |
91 int64_t version, | |
92 int64_t sync_ts, | |
93 const std::string& originator_cache_guid, | |
94 const std::string& originator_client_item_id); | |
95 // New protocol versions of the AddUpdate functions. | |
96 sync_pb::SyncEntity* AddUpdateDirectory( | |
97 const std::string& id, | |
98 const std::string& parent_id, | |
99 const std::string& name, | |
100 int64_t version, | |
101 int64_t sync_ts, | |
102 const std::string& originator_cache_guid, | |
103 const std::string& originator_client_item_id); | |
104 sync_pb::SyncEntity* AddUpdateBookmark( | |
105 const std::string& id, | |
106 const std::string& parent_id, | |
107 const std::string& name, | |
108 int64_t version, | |
109 int64_t sync_ts, | |
110 const std::string& originator_cache_guid, | |
111 const std::string& originator_client_item_id); | |
112 // Versions of the AddUpdate function that accept specifics. | |
113 sync_pb::SyncEntity* AddUpdateSpecifics( | |
114 int id, | |
115 int parent_id, | |
116 const std::string& name, | |
117 int64_t version, | |
118 int64_t sync_ts, | |
119 bool is_dir, | |
120 int64_t position, | |
121 const sync_pb::EntitySpecifics& specifics); | |
122 sync_pb::SyncEntity* AddUpdateSpecifics( | |
123 int id, | |
124 int parent_id, | |
125 const std::string& name, | |
126 int64_t version, | |
127 int64_t sync_ts, | |
128 bool is_dir, | |
129 int64_t position, | |
130 const sync_pb::EntitySpecifics& specifics, | |
131 const std::string& originator_cache_guid, | |
132 const std::string& originator_client_item_id); | |
133 sync_pb::SyncEntity* SetNigori(int id, | |
134 int64_t version, | |
135 int64_t sync_ts, | |
136 const sync_pb::EntitySpecifics& specifics); | |
137 // Unique client tag variant for adding items. | |
138 sync_pb::SyncEntity* AddUpdatePref(const std::string& id, | |
139 const std::string& parent_id, | |
140 const std::string& client_tag, | |
141 int64_t version, | |
142 int64_t sync_ts); | |
143 | |
144 // Find the last commit sent by the client, and replay it for the next get | |
145 // updates command. This can be used to simulate the GetUpdates that happens | |
146 // immediately after a successful commit. | |
147 sync_pb::SyncEntity* AddUpdateFromLastCommit(); | |
148 | |
149 // Add a deleted item. Deletion records typically contain no | |
150 // additional information beyond the deletion, and no specifics. | |
151 // The server may send the originator fields. | |
152 void AddUpdateTombstone(const syncable::Id& id, ModelType type); | |
153 | |
154 void SetLastUpdateDeleted(); | |
155 void SetLastUpdateServerTag(const std::string& tag); | |
156 void SetLastUpdateClientTag(const std::string& tag); | |
157 void SetLastUpdateOriginatorFields(const std::string& client_id, | |
158 const std::string& entry_id); | |
159 void SetLastUpdatePosition(int64_t position_in_parent); | |
160 void SetNewTimestamp(int ts); | |
161 void SetChangesRemaining(int64_t count); | |
162 | |
163 // Add a new batch of updates after the current one. Allows multiple | |
164 // GetUpdates responses to be buffered up, since the syncer may | |
165 // issue multiple requests during a sync cycle. | |
166 void NextUpdateBatch(); | |
167 | |
168 void FailNextPostBufferToPathCall() { countdown_to_postbuffer_fail_ = 1; } | |
169 void FailNthPostBufferToPathCall(int n) { countdown_to_postbuffer_fail_ = n; } | |
170 | |
171 void SetKeystoreKey(const std::string& key); | |
172 | |
173 void FailNonPeriodicGetUpdates() { fail_non_periodic_get_updates_ = true; } | |
174 | |
175 // Simple inspectors. | |
176 bool client_stuck() const { return client_stuck_; } | |
177 | |
178 // warning: These take ownership of their input. | |
179 void SetGUClientCommand(sync_pb::ClientCommand* command); | |
180 void SetCommitClientCommand(sync_pb::ClientCommand* command); | |
181 | |
182 void SetTransientErrorId(syncable::Id); | |
183 | |
184 const std::vector<syncable::Id>& committed_ids() const { | |
185 return committed_ids_; | |
186 } | |
187 const std::vector<sync_pb::CommitMessage*>& commit_messages() const { | |
188 return commit_messages_.get(); | |
189 } | |
190 const std::vector<sync_pb::CommitResponse*>& commit_responses() const { | |
191 return commit_responses_.get(); | |
192 } | |
193 // Retrieve the last sent commit message. | |
194 const sync_pb::CommitMessage& last_sent_commit() const; | |
195 | |
196 // Retrieve the last returned commit response. | |
197 const sync_pb::CommitResponse& last_commit_response() const; | |
198 | |
199 // Retrieve the last request submitted to the server (regardless of type). | |
200 const sync_pb::ClientToServerMessage& last_request() const; | |
201 | |
202 // Retrieve the cumulative collection of all requests sent by clients. | |
203 const std::vector<sync_pb::ClientToServerMessage>& requests() const; | |
204 | |
205 void set_conflict_all_commits(bool value) { | |
206 conflict_all_commits_ = value; | |
207 } | |
208 void set_next_new_id(int value) { | |
209 next_new_id_ = value; | |
210 } | |
211 void set_conflict_n_commits(int value) { | |
212 conflict_n_commits_ = value; | |
213 } | |
214 | |
215 void set_use_legacy_bookmarks_protocol(bool value) { | |
216 use_legacy_bookmarks_protocol_ = value; | |
217 } | |
218 | |
219 void set_store_birthday(const std::string& new_birthday) { | |
220 // Multiple threads can set store_birthday_ in our tests, need to lock it to | |
221 // ensure atomic read/writes and avoid race conditions. | |
222 base::AutoLock lock(store_birthday_lock_); | |
223 store_birthday_ = new_birthday; | |
224 } | |
225 | |
226 void set_partial_throttling(bool value) { partialThrottling_ = value; } | |
227 | |
228 // Retrieve the number of GetUpdates requests that the mock server has | |
229 // seen since the last time this function was called. Can be used to | |
230 // verify that a GetUpdates actually did or did not happen after running | |
231 // the syncer. | |
232 int GetAndClearNumGetUpdatesRequests() { | |
233 int result = num_get_updates_requests_; | |
234 num_get_updates_requests_ = 0; | |
235 return result; | |
236 } | |
237 | |
238 // Expect that GetUpdates will request exactly the types indicated in | |
239 // the bitset. | |
240 void ExpectGetUpdatesRequestTypes(ModelTypeSet expected_filter) { | |
241 expected_filter_ = expected_filter; | |
242 } | |
243 | |
244 // Set throttled date types. | |
245 void SetThrottledTypes(ModelTypeSet types) { throttled_type_ = types; } | |
246 | |
247 void SetServerReachable(); | |
248 | |
249 void SetServerNotReachable(); | |
250 | |
251 // Updates our internal state as if we had attempted a connection. Does not | |
252 // send notifications as a real connection attempt would. This is useful in | |
253 // cases where we're mocking out most of the code that performs network | |
254 // requests. | |
255 void UpdateConnectionStatus(); | |
256 | |
257 void SetServerStatus(HttpResponse::ServerConnectionCode server_status); | |
258 | |
259 // Return by copy to be thread-safe. | |
260 const std::string store_birthday() { | |
261 base::AutoLock lock(store_birthday_lock_); | |
262 return store_birthday_; | |
263 } | |
264 | |
265 // Explicitly indicate that we will not be fetching some updates. | |
266 void ClearUpdatesQueue() { | |
267 update_queue_.clear(); | |
268 } | |
269 | |
270 // Locate the most recent update message for purpose of alteration. | |
271 sync_pb::SyncEntity* GetMutableLastUpdate(); | |
272 | |
273 // Adds a new progress marker to the last update. | |
274 sync_pb::DataTypeProgressMarker* AddUpdateProgressMarker(); | |
275 | |
276 private: | |
277 sync_pb::SyncEntity* AddUpdateFull(syncable::Id id, | |
278 syncable::Id parentid, | |
279 const std::string& name, | |
280 int64_t version, | |
281 int64_t sync_ts, | |
282 bool is_dir); | |
283 sync_pb::SyncEntity* AddUpdateFull(const std::string& id, | |
284 const std::string& parentid, | |
285 const std::string& name, | |
286 int64_t version, | |
287 int64_t sync_ts, | |
288 bool is_dir); | |
289 sync_pb::SyncEntity* AddUpdateMeta(const std::string& id, | |
290 const std::string& parentid, | |
291 const std::string& name, | |
292 int64_t version, | |
293 int64_t sync_ts); | |
294 | |
295 // Functions to handle the various types of server request. | |
296 void ProcessGetUpdates(sync_pb::ClientToServerMessage* csm, | |
297 sync_pb::ClientToServerResponse* response); | |
298 void ProcessCommit(sync_pb::ClientToServerMessage* csm, | |
299 sync_pb::ClientToServerResponse* response_buffer); | |
300 void ProcessClearServerData(sync_pb::ClientToServerMessage* csm, | |
301 sync_pb::ClientToServerResponse* response); | |
302 void AddDefaultBookmarkData(sync_pb::SyncEntity* entity, bool is_folder); | |
303 | |
304 // Determine if one entry in a commit should be rejected with a conflict. | |
305 bool ShouldConflictThisCommit(); | |
306 | |
307 // Determine if the given item's commit request should be refused with | |
308 // a TRANSIENT_ERROR response. | |
309 bool ShouldTransientErrorThisId(syncable::Id id); | |
310 | |
311 // Generate a numeric position_in_parent value. We use a global counter | |
312 // that only decreases; this simulates new objects always being added to the | |
313 // front of the ordering. | |
314 int64_t GeneratePositionInParent() { return next_position_in_parent_--; } | |
315 | |
316 // Get a mutable update response which will eventually be returned to the | |
317 // client. | |
318 sync_pb::GetUpdatesResponse* GetUpdateResponse(); | |
319 void ApplyToken(); | |
320 | |
321 // Determine whether an progress marker array (like that sent in | |
322 // GetUpdates.from_progress_marker) indicates that a particular ModelType | |
323 // should be included. | |
324 bool IsModelTypePresentInSpecifics( | |
325 const google::protobuf::RepeatedPtrField< | |
326 sync_pb::DataTypeProgressMarker>& filter, | |
327 ModelType value); | |
328 | |
329 sync_pb::DataTypeProgressMarker const* GetProgressMarkerForType( | |
330 const google::protobuf::RepeatedPtrField< | |
331 sync_pb::DataTypeProgressMarker>& filter, | |
332 ModelType value); | |
333 | |
334 // When false, we pretend to have network connectivity issues. | |
335 bool server_reachable_; | |
336 | |
337 // All IDs that have been committed. | |
338 std::vector<syncable::Id> committed_ids_; | |
339 | |
340 // List of IDs which should return a transient error. | |
341 std::vector<syncable::Id> transient_error_ids_; | |
342 | |
343 // Control of when/if we return conflicts. | |
344 bool conflict_all_commits_; | |
345 int conflict_n_commits_; | |
346 | |
347 // Commit messages we've sent, and responses we've returned. | |
348 ScopedVector<sync_pb::CommitMessage> commit_messages_; | |
349 ScopedVector<sync_pb::CommitResponse> commit_responses_; | |
350 | |
351 // The next id the mock will return to a commit. | |
352 int next_new_id_; | |
353 | |
354 // The store birthday we send to the client. | |
355 std::string store_birthday_; | |
356 base::Lock store_birthday_lock_; | |
357 bool store_birthday_sent_; | |
358 bool client_stuck_; | |
359 std::string commit_time_rename_prepended_string_; | |
360 | |
361 // On each PostBufferToPath() call, we decrement this counter. The call fails | |
362 // iff we hit zero at that call. | |
363 int countdown_to_postbuffer_fail_; | |
364 | |
365 // Our directory. Used only to ensure that we are not holding the transaction | |
366 // lock when performing network I/O. Can be NULL if the test author is | |
367 // confident this can't happen. | |
368 syncable::Directory* directory_; | |
369 | |
370 // The updates we'll return to the next request. | |
371 std::list<sync_pb::GetUpdatesResponse> update_queue_; | |
372 base::Closure mid_commit_callback_; | |
373 MidCommitObserver* mid_commit_observer_; | |
374 | |
375 // The keystore key we return for a GetUpdates with need_encryption_key set. | |
376 std::string keystore_key_; | |
377 | |
378 // The AUTHENTICATE response we'll return for auth requests. | |
379 sync_pb::AuthenticateResponse auth_response_; | |
380 // What we use to determine if we should return SUCCESS or BAD_AUTH_TOKEN. | |
381 std::string valid_auth_token_; | |
382 | |
383 // Whether we are faking a server mandating clients to throttle requests. | |
384 // Protected by |response_code_override_lock_|. | |
385 bool throttling_; | |
386 | |
387 // Whether we are faking a server mandating clients to partial throttle | |
388 // requests. | |
389 // Protected by |response_code_override_lock_|. | |
390 bool partialThrottling_; | |
391 | |
392 base::Lock response_code_override_lock_; | |
393 | |
394 // True if we are only accepting GetUpdatesCallerInfo::PERIODIC requests. | |
395 bool fail_non_periodic_get_updates_; | |
396 | |
397 std::unique_ptr<sync_pb::ClientCommand> gu_client_command_; | |
398 std::unique_ptr<sync_pb::ClientCommand> commit_client_command_; | |
399 | |
400 // The next value to use for the position_in_parent property. | |
401 int64_t next_position_in_parent_; | |
402 | |
403 // The default is to use the newer sync_pb::BookmarkSpecifics-style protocol. | |
404 // If this option is set to true, then the MockConnectionManager will | |
405 // use the older sync_pb::SyncEntity_BookmarkData-style protocol. | |
406 bool use_legacy_bookmarks_protocol_; | |
407 | |
408 ModelTypeSet expected_filter_; | |
409 | |
410 ModelTypeSet throttled_type_; | |
411 | |
412 int num_get_updates_requests_; | |
413 | |
414 std::string next_token_; | |
415 | |
416 std::vector<sync_pb::ClientToServerMessage> requests_; | |
417 | |
418 DISALLOW_COPY_AND_ASSIGN(MockConnectionManager); | |
419 }; | |
420 | |
421 } // namespace syncer | |
422 | |
423 #endif // SYNC_TEST_ENGINE_MOCK_CONNECTION_MANAGER_H_ | |
OLD | NEW |