File: fake_server.h

package info (click to toggle)
chromium 139.0.7258.138-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 6,120,676 kB
  • sloc: cpp: 35,100,869; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (398 lines) | stat: -rw-r--r-- 17,455 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SYNC_TEST_FAKE_SERVER_H_
#define COMPONENTS_SYNC_TEST_FAKE_SERVER_H_

#include <stdint.h>

#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>

#include "base/location.h"
#include "base/observer_list.h"
#include "base/threading/thread_checker.h"
#include "base/values.h"
#include "components/sync/base/collaboration_id.h"
#include "components/sync/base/data_type.h"
#include "components/sync/engine/loopback_server/loopback_server.h"
#include "components/sync/engine/loopback_server/loopback_server_entity.h"
#include "components/sync/engine/loopback_server/persistent_bookmark_entity.h"
#include "components/sync/engine/loopback_server/persistent_tombstone_entity.h"
#include "components/sync/engine/loopback_server/persistent_unique_client_entity.h"
#include "components/sync/protocol/client_commands.pb.h"
#include "components/sync/protocol/deletion_origin.pb.h"
#include "components/sync/protocol/sync.pb.h"
#include "net/http/http_status_code.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace switches {

inline constexpr char kDisableFakeServerFailureOutput[] =
    "disable-fake-server-failure-output";

}  // namespace switches

namespace sync_pb {
class EntitySpecifics;
class DataTypeProgressMarker;
class SyncEntity;
enum SyncEnums_ErrorType : int;
}  // namespace sync_pb

namespace fake_server {

// This function only compares one part of the markers, the time-independent
// hashes of the data served in the update. Apart from this, the progress
// markers for fake wallet data also include information about fetch time. This
// is in-line with the server behavior and -- as it keeps changing -- allows
// integration tests to wait for a GetUpdates call to finish, even if they don't
// contain data updates.
bool AreFullUpdateTypeDataProgressMarkersEquivalent(
    const sync_pb::DataTypeProgressMarker& marker1,
    const sync_pb::DataTypeProgressMarker& marker2);

// A fake version of the Sync server used for testing. This class is not thread
// safe.
// `switches::kDisableFakeServerFailureOutput` can be passed to the command line
// to avoid debug logs upon test failure.
class FakeServer : public syncer::LoopbackServer::ObserverForTests {
 public:
  class Observer {
   public:
    virtual ~Observer() = default;

    // Called whenever a commit command is received by FakeServer. Note that
    // Commit command may fail and hence it's not guaranteed that OnCommit()
    // will be called. However, before any OnCommit() call there will be a
    // corresponding OnWillCommit() call.
    virtual void OnWillCommit() {}

    // Called after FakeServer has processed a successful commit. The types
    // updated as part of the commit are passed in `committed_data_types`.
    virtual void OnCommit(syncer::DataTypeSet committed_data_types) {}

    // Called whenever a get updates request is received by FakeServer.
    virtual void OnWillGetUpdates(
        const sync_pb::ClientToServerMessage& message) {}

    // Called after FakeServer has processed a successful get updates request.
    virtual void OnSuccessfulGetUpdates() {}
  };

  // Persists the server state to `loopback_server_dir` (useful for PRE_ tests).
  explicit FakeServer(const base::FilePath& loopback_server_dir);

  // Convenience version of the above which uses a new temporary directory.
  FakeServer();

  ~FakeServer() override;

  // Handles a /command POST (with the given `request`) to the server.
  // `response` must not be null.
  net::HttpStatusCode HandleCommand(const std::string& request,
                                    std::string* response);

  // Helpers for fetching the last Commit or GetUpdates messages, respectively.
  // Returns true if the specified message existed, and false if no message has
  // been received.
  bool GetLastCommitMessage(sync_pb::ClientToServerMessage* message);
  bool GetLastGetUpdatesMessage(sync_pb::ClientToServerMessage* message);

  // Creates a `base::Value::Dict` representation of all entities present in the
  // server. The dictionary keys are the strings generated by
  // DataTypeToDebugString and the values are Value::Lists containing
  // StringValue versions of entity names.
  base::Value::Dict GetEntitiesAsDictForTesting();

  // Returns all entities stored by the server of the given `data_type`.
  // This method returns SyncEntity protocol buffer objects (instead of
  // LoopbackServerEntity) so that callers can inspect datatype-specific data
  // (e.g., the URL of a session tab). Permanent entities are excluded.
  std::vector<sync_pb::SyncEntity> GetSyncEntitiesByDataType(
      syncer::DataType data_type);

  // Returns all permanent entities stored by the server of the given
  // `data_type`. This method returns SyncEntity protocol buffer objects
  // (instead of LoopbackServerEntity) so that callers can inspect
  // datatype-specific data (e.g., the URL of a session tab).
  std::vector<sync_pb::SyncEntity> GetPermanentSyncEntitiesByDataType(
      syncer::DataType data_type);

  // Returns all keystore keys from the server.
  const std::vector<std::vector<uint8_t>>& GetKeystoreKeys() const;

  // Triggers the keystore key rotation events on the server side: generating
  // new keystore key and touching the Nigori node.
  void TriggerKeystoreKeyRotation();

  // Adds `entity` to the server's collection of entities. This method makes no
  // guarantees that the added entity will result in successful server
  // operations.
  void InjectEntity(std::unique_ptr<syncer::LoopbackServerEntity> entity);

  // Sets the Wallet card and address data to be served in following GetUpdates
  // requests (any further GetUpdates response will be empty, indicating no
  // change, if the client already has received `wallet_entities`).
  //
  // The returned value represents the timestamp of the write, such that any
  // progress marker greater or equal to this timestamp must have processed the
  // changes. See GetProgressMarkerTimestamp() below.
  base::Time SetWalletData(
      const std::vector<sync_pb::SyncEntity>& wallet_entities);

  // Sets the Autofill offer data to be served in following GetUpdates
  // requests (any further GetUpdates response will be empty, indicating no
  // change, if the client already has received `offer_entities`).
  //
  // The returned value represents the timestamp of the write, such that any
  // progress marker greater or equal to this timestamp must have processed the
  // changes. See GetProgressMarkerTimestamp() below.
  base::Time SetOfferData(
      const std::vector<sync_pb::SyncEntity>& offer_entities);

  // Sets the Google Wallet valuable data to be served in following GetUpdates
  // requests (any further GetUpdates response will be empty, indicating no
  // change, if the client already has received `valuable_entities`).
  //
  // The returned value represents the timestamp of the write, such that any
  // progress marker greater or equal to this timestamp must have processed the
  // changes. See GetProgressMarkerTimestamp() below.
  base::Time SetValuableData(
      const std::vector<sync_pb::SyncEntity>& valuable_entities);

  // Allows the caller to know the timestamp corresponding to
  // `progress_marker` as annotated by the FakeServer during the GetUpdates
  // request that returned the progress marker.
  static base::Time GetProgressMarkerTimestamp(
      const sync_pb::DataTypeProgressMarker& progress_marker);

  // Modifies the entity on the server with the given `id`. The entity's
  // EntitySpecifics are replaced with `updated_specifics` and its version is
  // updated. If the given `id` does not exist or the DataType of
  // `updated_specifics` does not match the entity, false is returned.
  // Otherwise, true is returned to represent a successful modification.
  //
  // This method sometimes updates entity data beyond EntitySpecifics. For
  // example, in the case of a bookmark, changing the BookmarkSpecifics title
  // field will modify the top-level entity's name field.
  bool ModifyEntitySpecifics(const std::string& id,
                             const sync_pb::EntitySpecifics& updated_specifics);

  bool ModifyBookmarkEntity(const std::string& id,
                            const std::string& parent_id,
                            const sync_pb::EntitySpecifics& updated_specifics);

  // Clears server data simulating a "dashboard stop and clear" and sets a new
  // store birthday.
  void ClearServerData();

  // Deletes all `data_type` entities from the server without creating
  // tombstones.
  void DeleteAllEntitiesForDataType(syncer::DataType data_type);

  // Causes future calls to HandleCommand() fail with the given response code.
  void SetHttpError(net::HttpStatusCode http_status_code);

  // Undoes previous calls to SetHttpError().
  void ClearHttpError();

  // Sets the provided `client_command` in all subsequent successful requests.
  void SetClientCommand(const sync_pb::ClientCommand& client_command);

  // Force the server to return `error_type` in the error_code field of
  // ClientToServerResponse on all subsequent commit requests. If any of errors
  // triggerings currently configured it must be called only with
  // sync_pb::SyncEnums::SUCCESS.
  void TriggerCommitError(const sync_pb::SyncEnums_ErrorType& error_type);

  // Force the server to return `error_type` in the error_code field of
  // ClientToServerResponse on all subsequent sync requests. If any of errors
  // triggerings currently configured it must be called only with
  // sync_pb::SyncEnums::SUCCESS.
  void TriggerError(const sync_pb::SyncEnums_ErrorType& error_type);

  // Force the server to return the given data as part of the error field of
  // ClientToServerResponse on all subsequent sync requests. Must not be called
  // if any of errors triggerings currently configured.
  void TriggerActionableProtocolError(
      const sync_pb::SyncEnums_ErrorType& error_type,
      const std::string& description,
      const std::string& url,
      const sync_pb::SyncEnums::Action& action);

  void ClearActionableProtocolError();

  // Instructs the server to send triggered errors on every other request
  // (starting with the first one after this call). This feature can be used to
  // test the resiliency of the client when communicating with a problematic
  // server or flaky network connection. This method should only be called
  // after a call to TriggerError or TriggerActionableProtocolError. Returns
  // true if triggered error alternating was successful.
  bool EnableAlternatingTriggeredErrors();

  // If called, all subsequent GetUpdatesResponses won't contain
  // encryption_keys.
  void DisallowSendingEncryptionKeys();

  // Mimics throttling of datatypes.
  void SetThrottledTypes(syncer::DataTypeSet types);

  // 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);

  // Enables strong consistency model (i.e. server detects conflicts).
  void EnableStrongConsistencyWithConflictDetectionModel();

  // Sets a maximum batch size for GetUpdates requests.
  void SetMaxGetUpdatesBatchSize(int batch_size);

  // Sets the bag of chips returned by the server.
  void SetBagOfChips(const sync_pb::ChipBag& bag_of_chips);

  void TriggerMigrationDoneError(syncer::DataTypeSet types);

  // Add the user to the collaboration for the shared data types. No-op if the
  // user is already in this collaboration.
  void AddCollaboration(syncer::CollaborationId collaboration_id);

  // Removes the user from the collaboration. Does not clean up related entities
  // from the server.
  void RemoveCollaboration(const syncer::CollaborationId& collaboration_id);

  // Implement LoopbackServer::ObserverForTests:
  void OnCommit(syncer::DataTypeSet committed_data_types) override;
  void OnCommittedDeletionOrigin(
      syncer::DataType type,
      const sync_pb::DeletionOrigin& deletion_origin) override;

  // Returns all DeletionOrigin protos committed to the server for `type`.
  const std::vector<sync_pb::DeletionOrigin>& GetCommittedDeletionOrigins(
      syncer::DataType type) const;

  std::string GetStoreBirthday() const;

  // Returns the current FakeServer as a WeakPtr.
  base::WeakPtr<FakeServer> AsWeakPtr();

  // Use this callback to generate response types for entities. They will still
  // be "committed" and stored as normal, this only affects the response type
  // the client sees. This allows tests to still inspect what the client has
  // done, although not as useful of a mechanism for multi client tests. Care
  // should be taken when failing responses, as the client will go into
  // exponential backoff, which can cause tests to be slow or time out.
  void OverrideResponseType(
      syncer::LoopbackServer::ResponseTypeProvider response_type_override);

  // Performs any pending disk write immediately. This is useful on platforms
  // where shutdown isn't graceful, and this object may not be destructed
  // properly (otherwise, the destructor takes care of this automatically).
  void FlushToDisk();

 private:
  // Analogous to HandleCommand() but deals with parsed protos.
  net::HttpStatusCode HandleParsedCommand(
      const sync_pb::ClientToServerMessage& message,
      sync_pb::ClientToServerResponse* response);

  // Returns whether a triggered error should be sent for the request.
  bool ShouldSendTriggeredError() const;
  bool HasTriggeredError() const;
  net::HttpStatusCode SendToLoopbackServer(
      const sync_pb::ClientToServerMessage& message,
      sync_pb::ClientToServerResponse* response);

  // Logs a string that is meant to be shown in case the running test fails,
  // as long as `switches::kDisableFakeServerFailureOutput` hasn't been passed
  // to the command line.
  void LogForTestFailure(const base::Location& location,
                         const std::string& title,
                         const std::string& body);

  // Notifies observers about an ongoing commit.
  void OnWillCommit();

  // List used to implement LogForTestFailure().
  std::vector<std::unique_ptr<testing::ScopedTrace>> gtest_scoped_traces_;

  // If set, the server will return HTTP errors.
  std::optional<net::HttpStatusCode> http_error_status_code_;

  // All committed deletion origins (optional part of committed tombstone).
  std::map<syncer::DataType, std::vector<sync_pb::DeletionOrigin>>
      committed_deletion_origins_;

  // Used as the error_code field of ClientToServerResponse on all commit
  // requests.
  sync_pb::SyncEnums_ErrorType commit_error_type_ = sync_pb::SyncEnums::SUCCESS;

  // Used as the error_code field of ClientToServerResponse on all responses.
  sync_pb::SyncEnums_ErrorType error_type_ = sync_pb::SyncEnums::SUCCESS;

  // Used as the error field of ClientToServerResponse when its pointer is not
  // null.
  std::unique_ptr<sync_pb::ClientToServerResponse_Error>
      triggered_actionable_error_;

  // These values are used in tandem to return a triggered error (either
  // `error_type_` or `triggered_actionable_error_`) on every other request.
  // `alternate_triggered_errors_` is set if this feature is enabled and
  // `request_counter_` is used to send triggered errors on odd-numbered
  // requests. Note that `request_counter_` can be reset and is not necessarily
  // indicative of the total number of requests handled during the object's
  // lifetime.
  bool alternate_triggered_errors_ = false;
  int request_counter_ = 0;

  // If set to true all `this` will clear `encryption_keys` in all
  // GetUpdateResponse's.
  bool disallow_sending_encryption_keys_ = false;

  // Client command to be included in every response.
  sync_pb::ClientCommand client_command_;

  // FakeServer's observers.
  base::ObserverList<Observer, true>::Unchecked observers_;

  // The last received client to server messages.
  sync_pb::ClientToServerMessage last_commit_message_;
  sync_pb::ClientToServerMessage last_getupdates_message_;

  // Used to verify that FakeServer is only used from one thread.
  base::ThreadChecker thread_checker_;

  std::unique_ptr<syncer::LoopbackServer> loopback_server_;

  // The LoopbackServer does not know how to handle Wallet data properly, so
  // the FakeServer handles those itself.
  std::vector<sync_pb::SyncEntity> wallet_entities_;

  // The LoopbackServer does not know how to handle offer data properly, so
  // the FakeServer handles those itself.
  std::vector<sync_pb::SyncEntity> offer_entities_;

  // The LoopbackServer does not know how to handle valuable data properly, so
  // the FakeServer handles those itself.
  std::vector<sync_pb::SyncEntity> valuable_entities_;

  // Collaborations the user is a member of, used for all shared types.
  std::set<syncer::CollaborationId> collaborations_;

  // Creates WeakPtr versions of the current FakeServer. This must be the last
  // data member!
  base::WeakPtrFactory<FakeServer> weak_ptr_factory_{this};
};

}  // namespace fake_server

#endif  // COMPONENTS_SYNC_TEST_FAKE_SERVER_H_