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 CHROME_BROWSER_SYNC_TEST_ENGINE_MOCK_CONNECTION_MANAGER_H_ | |
8 #define CHROME_BROWSER_SYNC_TEST_ENGINE_MOCK_CONNECTION_MANAGER_H_ | |
9 #pragma once | |
10 | |
11 #include <bitset> | |
12 #include <list> | |
13 #include <string> | |
14 #include <vector> | |
15 | |
16 #include "base/callback.h" | |
17 #include "base/compiler_specific.h" | |
18 #include "base/memory/scoped_vector.h" | |
19 #include "chrome/browser/sync/engine/net/server_connection_manager.h" | |
20 #include "chrome/browser/sync/syncable/model_type.h" | |
21 #include "chrome/browser/sync/syncable/model_type_payload_map.h" | |
22 #include "sync/protocol/sync.pb.h" | |
23 | |
24 class MockConnectionManager : public browser_sync::ServerConnectionManager { | |
25 public: | |
26 class MidCommitObserver { | |
27 public: | |
28 virtual void Observe() = 0; | |
29 | |
30 protected: | |
31 virtual ~MidCommitObserver() {} | |
32 }; | |
33 | |
34 explicit MockConnectionManager(syncable::Directory*); | |
35 virtual ~MockConnectionManager(); | |
36 | |
37 // Overridden ServerConnectionManager functions. | |
38 virtual bool PostBufferToPath( | |
39 PostBufferParams*, | |
40 const std::string& path, | |
41 const std::string& auth_token, | |
42 browser_sync::ScopedServerStatusWatcher* watcher) OVERRIDE; | |
43 | |
44 virtual bool IsServerReachable() OVERRIDE; | |
45 virtual bool IsUserAuthenticated() OVERRIDE; | |
46 | |
47 // Control of commit response. | |
48 void SetMidCommitCallback(const base::Closure& callback); | |
49 void SetMidCommitObserver(MidCommitObserver* observer); | |
50 | |
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); | |
54 | |
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(syncable::Id id, | |
61 syncable::Id parent_id, | |
62 std::string name, | |
63 int64 version, | |
64 int64 sync_ts); | |
65 sync_pb::SyncEntity* AddUpdateBookmark(syncable::Id id, | |
66 syncable::Id parent_id, | |
67 std::string name, | |
68 int64 version, | |
69 int64 sync_ts); | |
70 // Versions of the AddUpdate functions that accept integer IDs. | |
71 sync_pb::SyncEntity* AddUpdateDirectory(int id, | |
72 int parent_id, | |
73 std::string name, | |
74 int64 version, | |
75 int64 sync_ts); | |
76 sync_pb::SyncEntity* AddUpdateBookmark(int id, | |
77 int parent_id, | |
78 std::string name, | |
79 int64 version, | |
80 int64 sync_ts); | |
81 // New protocol versions of the AddUpdate functions. | |
82 sync_pb::SyncEntity* AddUpdateDirectory(std::string id, | |
83 std::string parent_id, | |
84 std::string name, | |
85 int64 version, | |
86 int64 sync_ts); | |
87 sync_pb::SyncEntity* AddUpdateBookmark(std::string id, | |
88 std::string parent_id, | |
89 std::string name, | |
90 int64 version, | |
91 int64 sync_ts); | |
92 // Versions of the AddUpdate function that accept specifics. | |
93 sync_pb::SyncEntity* AddUpdateSpecifics(int id, int parent_id, | |
94 std::string name,int64 version, int64 sync_ts, bool is_dir, | |
95 int64 position, const sync_pb::EntitySpecifics& specifics); | |
96 sync_pb::SyncEntity* SetNigori(int id, int64 version, int64 sync_ts, | |
97 const sync_pb::EntitySpecifics& specifics); | |
98 | |
99 // Find the last commit sent by the client, and replay it for the next get | |
100 // updates command. This can be used to simulate the GetUpdates that happens | |
101 // immediately after a successful commit. | |
102 sync_pb::SyncEntity* AddUpdateFromLastCommit(); | |
103 | |
104 // Add a deleted item. Deletion records typically contain no | |
105 // additional information beyond the deletion, and no specifics. | |
106 // The server may send the originator fields. | |
107 void AddUpdateTombstone(const syncable::Id& id); | |
108 | |
109 void SetLastUpdateDeleted(); | |
110 void SetLastUpdateServerTag(const std::string& tag); | |
111 void SetLastUpdateClientTag(const std::string& tag); | |
112 void SetLastUpdateOriginatorFields(const std::string& client_id, | |
113 const std::string& entry_id); | |
114 void SetLastUpdatePosition(int64 position_in_parent); | |
115 void SetNewTimestamp(int ts); | |
116 void SetChangesRemaining(int64 count); | |
117 | |
118 // Add a new batch of updates after the current one. Allows multiple | |
119 // GetUpdates responses to be buffered up, since the syncer may | |
120 // issue multiple requests during a sync cycle. | |
121 void NextUpdateBatch(); | |
122 | |
123 // For AUTHENTICATE responses. | |
124 void SetAuthenticationResponseInfo(const std::string& valid_auth_token, | |
125 const std::string& user_display_name, | |
126 const std::string& user_display_email, | |
127 const std::string& user_obfuscated_id); | |
128 | |
129 void FailNextPostBufferToPathCall() { fail_next_postbuffer_ = true; } | |
130 | |
131 void SetClearUserDataResponseStatus(sync_pb::SyncEnums::ErrorType errortype); | |
132 | |
133 // A visitor class to allow a test to change some monitoring state atomically | |
134 // with the action of overriding the response codes sent back to the Syncer | |
135 // (for example, so you can say "ThrottleNextRequest, and assert no more | |
136 // requests are made once throttling is in effect" in one step. | |
137 class ResponseCodeOverrideRequestor { | |
138 public: | |
139 // Called with response_code_override_lock_ acquired. | |
140 virtual void OnOverrideComplete() = 0; | |
141 | |
142 protected: | |
143 virtual ~ResponseCodeOverrideRequestor() {} | |
144 }; | |
145 void ThrottleNextRequest(ResponseCodeOverrideRequestor* visitor); | |
146 void FailWithAuthInvalid(ResponseCodeOverrideRequestor* visitor); | |
147 void StopFailingWithAuthInvalid(ResponseCodeOverrideRequestor* visitor); | |
148 void FailNonPeriodicGetUpdates() { fail_non_periodic_get_updates_ = true; } | |
149 | |
150 // Simple inspectors. | |
151 bool client_stuck() const { return client_stuck_; } | |
152 | |
153 sync_pb::ClientCommand* GetNextClientCommand(); | |
154 | |
155 const std::vector<syncable::Id>& committed_ids() const { | |
156 return committed_ids_; | |
157 } | |
158 const std::vector<sync_pb::CommitMessage*>& commit_messages() const { | |
159 return commit_messages_.get(); | |
160 } | |
161 const std::vector<sync_pb::CommitResponse*>& commit_responses() const { | |
162 return commit_responses_.get(); | |
163 } | |
164 // Retrieve the last sent commit message. | |
165 const sync_pb::CommitMessage& last_sent_commit() const; | |
166 | |
167 // Retrieve the last returned commit response. | |
168 const sync_pb::CommitResponse& last_commit_response() const; | |
169 | |
170 // Retrieve the last request submitted to the server (regardless of type). | |
171 const sync_pb::ClientToServerMessage& last_request() const { | |
172 return last_request_; | |
173 } | |
174 | |
175 void set_conflict_all_commits(bool value) { | |
176 conflict_all_commits_ = value; | |
177 } | |
178 void set_next_new_id(int value) { | |
179 next_new_id_ = value; | |
180 } | |
181 void set_conflict_n_commits(int value) { | |
182 conflict_n_commits_ = value; | |
183 } | |
184 | |
185 void set_use_legacy_bookmarks_protocol(bool value) { | |
186 use_legacy_bookmarks_protocol_ = value; | |
187 } | |
188 | |
189 void set_store_birthday(std::string new_birthday) { | |
190 // Multiple threads can set store_birthday_ in our tests, need to lock it to | |
191 // ensure atomic read/writes and avoid race conditions. | |
192 base::AutoLock lock(store_birthday_lock_); | |
193 store_birthday_ = new_birthday; | |
194 } | |
195 | |
196 // Retrieve the number of GetUpdates requests that the mock server has | |
197 // seen since the last time this function was called. Can be used to | |
198 // verify that a GetUpdates actually did or did not happen after running | |
199 // the syncer. | |
200 int GetAndClearNumGetUpdatesRequests() { | |
201 int result = num_get_updates_requests_; | |
202 num_get_updates_requests_ = 0; | |
203 return result; | |
204 } | |
205 | |
206 // Expect that GetUpdates will request exactly the types indicated in | |
207 // the bitset. | |
208 void ExpectGetUpdatesRequestTypes( | |
209 syncable::ModelTypeSet expected_filter) { | |
210 expected_filter_ = expected_filter; | |
211 } | |
212 | |
213 void ExpectGetUpdatesRequestPayloads( | |
214 const syncable::ModelTypePayloadMap& payloads) { | |
215 expected_payloads_ = payloads; | |
216 } | |
217 | |
218 void SetServerReachable(); | |
219 | |
220 void SetServerNotReachable(); | |
221 | |
222 // Return by copy to be thread-safe. | |
223 const std::string store_birthday() { | |
224 base::AutoLock lock(store_birthday_lock_); | |
225 return store_birthday_; | |
226 } | |
227 | |
228 // Locate the most recent update message for purpose of alteration. | |
229 sync_pb::SyncEntity* GetMutableLastUpdate(); | |
230 | |
231 private: | |
232 sync_pb::SyncEntity* AddUpdateFull(syncable::Id id, syncable::Id parentid, | |
233 std::string name, int64 version, | |
234 int64 sync_ts, | |
235 bool is_dir); | |
236 sync_pb::SyncEntity* AddUpdateFull(std::string id, | |
237 std::string parentid, std::string name, | |
238 int64 version, int64 sync_ts, | |
239 bool is_dir); | |
240 sync_pb::SyncEntity* AddUpdateMeta(std::string id, std::string parentid, | |
241 std::string name, int64 version, | |
242 int64 sync_ts); | |
243 | |
244 // Functions to handle the various types of server request. | |
245 void ProcessGetUpdates(sync_pb::ClientToServerMessage* csm, | |
246 sync_pb::ClientToServerResponse* response); | |
247 void ProcessAuthenticate(sync_pb::ClientToServerMessage* csm, | |
248 sync_pb::ClientToServerResponse* response, | |
249 const std::string& auth_token); | |
250 void ProcessCommit(sync_pb::ClientToServerMessage* csm, | |
251 sync_pb::ClientToServerResponse* response_buffer); | |
252 void ProcessClearData(sync_pb::ClientToServerMessage* csm, | |
253 sync_pb::ClientToServerResponse* response); | |
254 void AddDefaultBookmarkData(sync_pb::SyncEntity* entity, bool is_folder); | |
255 | |
256 // Determine if one entry in a commit should be rejected with a conflict. | |
257 bool ShouldConflictThisCommit(); | |
258 | |
259 // Generate a numeric position_in_parent value. We use a global counter | |
260 // that only decreases; this simulates new objects always being added to the | |
261 // front of the ordering. | |
262 int64 GeneratePositionInParent() { | |
263 return next_position_in_parent_--; | |
264 } | |
265 | |
266 // Get a mutable update response which will eventually be returned to the | |
267 // client. | |
268 sync_pb::GetUpdatesResponse* GetUpdateResponse(); | |
269 void ApplyToken(); | |
270 | |
271 // Determine whether an progress marker array (like that sent in | |
272 // GetUpdates.from_progress_marker) indicates that a particular ModelType | |
273 // should be included. | |
274 bool IsModelTypePresentInSpecifics( | |
275 const google::protobuf::RepeatedPtrField< | |
276 sync_pb::DataTypeProgressMarker>& filter, | |
277 syncable::ModelType value); | |
278 | |
279 sync_pb::DataTypeProgressMarker const* GetProgressMarkerForType( | |
280 const google::protobuf::RepeatedPtrField< | |
281 sync_pb::DataTypeProgressMarker>& filter, | |
282 syncable::ModelType value); | |
283 | |
284 // All IDs that have been committed. | |
285 std::vector<syncable::Id> committed_ids_; | |
286 | |
287 // Control of when/if we return conflicts. | |
288 bool conflict_all_commits_; | |
289 int conflict_n_commits_; | |
290 | |
291 // Commit messages we've sent, and responses we've returned. | |
292 ScopedVector<sync_pb::CommitMessage> commit_messages_; | |
293 ScopedVector<sync_pb::CommitResponse> commit_responses_; | |
294 | |
295 // The next id the mock will return to a commit. | |
296 int next_new_id_; | |
297 | |
298 // The store birthday we send to the client. | |
299 std::string store_birthday_; | |
300 base::Lock store_birthday_lock_; | |
301 bool store_birthday_sent_; | |
302 bool client_stuck_; | |
303 std::string commit_time_rename_prepended_string_; | |
304 | |
305 // Fail on the next call to PostBufferToPath(). | |
306 bool fail_next_postbuffer_; | |
307 | |
308 // Our directory. Used only to ensure that we are not holding the transaction | |
309 // lock when performing network I/O. Can be NULL if the test author is | |
310 // confident this can't happen. | |
311 syncable::Directory* directory_; | |
312 | |
313 // The updates we'll return to the next request. | |
314 std::list<sync_pb::GetUpdatesResponse> update_queue_; | |
315 base::Closure mid_commit_callback_; | |
316 MidCommitObserver* mid_commit_observer_; | |
317 | |
318 // The clear data response we'll return in the next response | |
319 sync_pb::SyncEnums::ErrorType clear_user_data_response_errortype_; | |
320 | |
321 // The AUTHENTICATE response we'll return for auth requests. | |
322 sync_pb::AuthenticateResponse auth_response_; | |
323 // What we use to determine if we should return SUCCESS or BAD_AUTH_TOKEN. | |
324 std::string valid_auth_token_; | |
325 | |
326 // Whether we are faking a server mandating clients to throttle requests. | |
327 // Protected by |response_code_override_lock_|. | |
328 bool throttling_; | |
329 | |
330 // Whether we are failing all requests by returning | |
331 // ClientToServerResponse::AUTH_INVALID. | |
332 // Protected by |response_code_override_lock_|. | |
333 bool fail_with_auth_invalid_; | |
334 | |
335 base::Lock response_code_override_lock_; | |
336 | |
337 // True if we are only accepting GetUpdatesCallerInfo::PERIODIC requests. | |
338 bool fail_non_periodic_get_updates_; | |
339 | |
340 scoped_ptr<sync_pb::ClientCommand> client_command_; | |
341 | |
342 // The next value to use for the position_in_parent property. | |
343 int64 next_position_in_parent_; | |
344 | |
345 // The default is to use the newer sync_pb::BookmarkSpecifics-style protocol. | |
346 // If this option is set to true, then the MockConnectionManager will | |
347 // use the older sync_pb::SyncEntity_BookmarkData-style protocol. | |
348 bool use_legacy_bookmarks_protocol_; | |
349 | |
350 syncable::ModelTypeSet expected_filter_; | |
351 | |
352 syncable::ModelTypePayloadMap expected_payloads_; | |
353 | |
354 int num_get_updates_requests_; | |
355 | |
356 std::string next_token_; | |
357 | |
358 sync_pb::ClientToServerMessage last_request_; | |
359 | |
360 DISALLOW_COPY_AND_ASSIGN(MockConnectionManager); | |
361 }; | |
362 | |
363 #endif // CHROME_BROWSER_SYNC_TEST_ENGINE_MOCK_CONNECTION_MANAGER_H_ | |
OLD | NEW |