Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / components / invalidation / registration_manager_unittest.cc
1 // Copyright 2014 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 #include "components/invalidation/registration_manager.h"
6
7 #include <algorithm>
8 #include <cmath>
9 #include <cstddef>
10 #include <deque>
11 #include <vector>
12
13 #include "base/basictypes.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/stl_util.h"
16 #include "components/invalidation/invalidation_util.h"
17 #include "google/cacheinvalidation/include/invalidation-client.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace syncer {
21 namespace {
22
23 // Fake registration manager that lets you override jitter.
24 class FakeRegistrationManager : public RegistrationManager {
25  public:
26   explicit FakeRegistrationManager(
27       invalidation::InvalidationClient* invalidation_client)
28       : RegistrationManager(invalidation_client),
29         jitter_(0.0) {}
30
31   ~FakeRegistrationManager() override {}
32
33   void SetJitter(double jitter) {
34     jitter_ = jitter;
35   }
36
37  protected:
38   double GetJitter() override { return jitter_; }
39
40  private:
41   double jitter_;
42
43   DISALLOW_COPY_AND_ASSIGN(FakeRegistrationManager);
44 };
45
46 // Fake invalidation client that just stores the currently-registered
47 // object IDs.
48 class FakeInvalidationClient : public invalidation::InvalidationClient {
49  public:
50   FakeInvalidationClient() {}
51
52   ~FakeInvalidationClient() override {}
53
54   void LoseRegistration(const invalidation::ObjectId& oid) {
55     EXPECT_TRUE(ContainsKey(registered_ids_, oid));
56     registered_ids_.erase(oid);
57   }
58
59   void LoseAllRegistrations() {
60     registered_ids_.clear();
61   }
62
63   // invalidation::InvalidationClient implementation.
64
65   void Start() override {}
66   void Stop() override {}
67   void Acknowledge(const invalidation::AckHandle& handle) override {}
68
69   void Register(const invalidation::ObjectId& oid) override {
70     EXPECT_FALSE(ContainsKey(registered_ids_, oid));
71     registered_ids_.insert(oid);
72   }
73
74   void Register(const std::vector<invalidation::ObjectId>& oids) override {
75     // Unused for now.
76   }
77
78   void Unregister(const invalidation::ObjectId& oid) override {
79     EXPECT_TRUE(ContainsKey(registered_ids_, oid));
80     registered_ids_.erase(oid);
81   }
82
83   void Unregister(const std::vector<invalidation::ObjectId>& oids) override {
84     // Unused for now.
85   }
86
87   const ObjectIdSet& GetRegisteredIdsForTest() const {
88     return registered_ids_;
89   }
90
91  private:
92   ObjectIdSet registered_ids_;
93
94   DISALLOW_COPY_AND_ASSIGN(FakeInvalidationClient);
95 };
96
97 size_t kObjectIdsCount = 5;
98
99 invalidation::ObjectId GetIdForIndex(size_t index) {
100   char name[2] = "a";
101   name[0] += static_cast<char>(index);
102   return invalidation::ObjectId(1 + index, name);
103 }
104
105 ObjectIdSet GetSequenceOfIdsStartingAt(size_t start, size_t count) {
106   ObjectIdSet ids;
107   for (size_t i = start; i < start + count; ++i)
108     ids.insert(GetIdForIndex(i));
109   return ids;
110 }
111
112 ObjectIdSet GetSequenceOfIds(size_t count) {
113   return GetSequenceOfIdsStartingAt(0, count);
114 }
115
116 void ExpectPendingRegistrations(
117     const ObjectIdSet& expected_pending_ids,
118     double expected_delay_seconds,
119     const RegistrationManager::PendingRegistrationMap& pending_registrations) {
120   ObjectIdSet pending_ids;
121   for (RegistrationManager::PendingRegistrationMap::const_iterator it =
122            pending_registrations.begin(); it != pending_registrations.end();
123        ++it) {
124     SCOPED_TRACE(ObjectIdToString(it->first));
125     pending_ids.insert(it->first);
126     base::TimeDelta offset =
127         it->second.last_registration_request -
128         it->second.registration_attempt;
129     base::TimeDelta expected_delay =
130         base::TimeDelta::FromSeconds(
131             static_cast<int64>(expected_delay_seconds)) + offset;
132     // TODO(akalin): Add base::PrintTo() for base::Time and
133     // base::TimeDeltas.
134     EXPECT_EQ(expected_delay, it->second.delay)
135         << expected_delay.InMicroseconds()
136         << ", " << it->second.delay.InMicroseconds();
137     if (it->second.delay <= base::TimeDelta()) {
138       EXPECT_EQ(base::TimeDelta(), it->second.actual_delay);
139     } else {
140       EXPECT_EQ(it->second.actual_delay, it->second.delay);
141     }
142   }
143   EXPECT_EQ(expected_pending_ids, pending_ids);
144 }
145
146 class RegistrationManagerTest : public testing::Test {
147  protected:
148   RegistrationManagerTest()
149       : fake_registration_manager_(&fake_invalidation_client_) {}
150
151   ~RegistrationManagerTest() override {}
152
153   void LoseRegistrations(const ObjectIdSet& oids) {
154     for (ObjectIdSet::const_iterator it = oids.begin(); it != oids.end();
155          ++it) {
156       fake_invalidation_client_.LoseRegistration(*it);
157       fake_registration_manager_.MarkRegistrationLost(*it);
158     }
159   }
160
161   void DisableIds(const ObjectIdSet& oids) {
162     for (ObjectIdSet::const_iterator it = oids.begin(); it != oids.end();
163          ++it) {
164       fake_invalidation_client_.LoseRegistration(*it);
165       fake_registration_manager_.DisableId(*it);
166     }
167   }
168
169   // Used by MarkRegistrationLostBackoff* tests.
170   void RunBackoffTest(double jitter) {
171     fake_registration_manager_.SetJitter(jitter);
172     ObjectIdSet ids = GetSequenceOfIds(kObjectIdsCount);
173     fake_registration_manager_.UpdateRegisteredIds(ids);
174
175     // Lose some ids.
176     ObjectIdSet lost_ids = GetSequenceOfIds(2);
177     LoseRegistrations(lost_ids);
178     ExpectPendingRegistrations(
179         lost_ids, 0.0,
180         fake_registration_manager_.GetPendingRegistrationsForTest());
181
182     // Trigger another failure to start delaying.
183     fake_registration_manager_.FirePendingRegistrationsForTest();
184     LoseRegistrations(lost_ids);
185
186     double scaled_jitter =
187         jitter * RegistrationManager::kRegistrationDelayMaxJitter;
188
189     double expected_delay =
190         RegistrationManager::kInitialRegistrationDelaySeconds *
191         (1.0 + scaled_jitter);
192     expected_delay = std::floor(expected_delay);
193     ExpectPendingRegistrations(
194         lost_ids, expected_delay,
195         fake_registration_manager_.GetPendingRegistrationsForTest());
196
197     // Trigger another failure.
198     fake_registration_manager_.FirePendingRegistrationsForTest();
199     LoseRegistrations(lost_ids);
200     expected_delay *=
201         RegistrationManager::kRegistrationDelayExponent + scaled_jitter;
202     expected_delay = std::floor(expected_delay);
203     ExpectPendingRegistrations(
204         lost_ids, expected_delay,
205         fake_registration_manager_.GetPendingRegistrationsForTest());
206
207     // Trigger enough failures to hit the ceiling.
208     while (expected_delay < RegistrationManager::kMaxRegistrationDelaySeconds) {
209       fake_registration_manager_.FirePendingRegistrationsForTest();
210       LoseRegistrations(lost_ids);
211       expected_delay *=
212           RegistrationManager::kRegistrationDelayExponent + scaled_jitter;
213       expected_delay = std::floor(expected_delay);
214     }
215     ExpectPendingRegistrations(
216         lost_ids,
217         RegistrationManager::kMaxRegistrationDelaySeconds,
218         fake_registration_manager_.GetPendingRegistrationsForTest());
219   }
220
221   FakeInvalidationClient fake_invalidation_client_;
222   FakeRegistrationManager fake_registration_manager_;
223
224  private:
225   // Needed by timers in RegistrationManager.
226   base::MessageLoop message_loop_;
227
228   DISALLOW_COPY_AND_ASSIGN(RegistrationManagerTest);
229 };
230
231 // Basic test of UpdateRegisteredIds to make sure we properly register
232 // new IDs and unregister any IDs no longer in the set.
233 TEST_F(RegistrationManagerTest, UpdateRegisteredIds) {
234   ObjectIdSet ids = GetSequenceOfIds(kObjectIdsCount - 1);
235
236   EXPECT_TRUE(fake_registration_manager_.GetRegisteredIdsForTest().empty());
237   EXPECT_TRUE(fake_invalidation_client_.GetRegisteredIdsForTest().empty());
238
239   ObjectIdSet expected_unregistered_ids;
240
241   ObjectIdSet unregistered_ids =
242       fake_registration_manager_.UpdateRegisteredIds(ids);
243   EXPECT_EQ(expected_unregistered_ids, unregistered_ids);
244   EXPECT_EQ(ids, fake_registration_manager_.GetRegisteredIdsForTest());
245   EXPECT_EQ(ids, fake_invalidation_client_.GetRegisteredIdsForTest());
246
247   ids.insert(GetIdForIndex(kObjectIdsCount - 1));
248   ids.erase(GetIdForIndex(kObjectIdsCount - 2));
249   unregistered_ids = fake_registration_manager_.UpdateRegisteredIds(ids);
250   expected_unregistered_ids.insert(GetIdForIndex(kObjectIdsCount - 2));
251   EXPECT_EQ(expected_unregistered_ids, unregistered_ids);
252   EXPECT_EQ(ids, fake_registration_manager_.GetRegisteredIdsForTest());
253   EXPECT_EQ(ids, fake_invalidation_client_.GetRegisteredIdsForTest());
254 }
255
256 int GetRoundedBackoff(double retry_interval, double jitter) {
257   const double kInitialRetryInterval = 3.0;
258   const double kMinRetryInterval = 2.0;
259   const double kMaxRetryInterval = 20.0;
260   const double kBackoffExponent = 2.0;
261   const double kMaxJitter = 0.5;
262
263   return static_cast<int>(
264       RegistrationManager::CalculateBackoff(retry_interval,
265                                             kInitialRetryInterval,
266                                             kMinRetryInterval,
267                                             kMaxRetryInterval,
268                                             kBackoffExponent,
269                                             jitter,
270                                             kMaxJitter));
271 }
272
273 TEST_F(RegistrationManagerTest, CalculateBackoff) {
274   // Test initial.
275   EXPECT_EQ(2, GetRoundedBackoff(0.0, -1.0));
276   EXPECT_EQ(3, GetRoundedBackoff(0.0,  0.0));
277   EXPECT_EQ(4, GetRoundedBackoff(0.0, +1.0));
278
279   // Test non-initial.
280   EXPECT_EQ(4, GetRoundedBackoff(3.0, -1.0));
281   EXPECT_EQ(6, GetRoundedBackoff(3.0,  0.0));
282   EXPECT_EQ(7, GetRoundedBackoff(3.0, +1.0));
283
284   EXPECT_EQ(7, GetRoundedBackoff(5.0, -1.0));
285   EXPECT_EQ(10, GetRoundedBackoff(5.0,  0.0));
286   EXPECT_EQ(12, GetRoundedBackoff(5.0, +1.0));
287
288   // Test ceiling.
289   EXPECT_EQ(19, GetRoundedBackoff(13.0, -1.0));
290   EXPECT_EQ(20, GetRoundedBackoff(13.0,  0.0));
291   EXPECT_EQ(20, GetRoundedBackoff(13.0, +1.0));
292 }
293
294 // Losing a registration should queue automatic re-registration.
295 TEST_F(RegistrationManagerTest, MarkRegistrationLost) {
296   ObjectIdSet ids = GetSequenceOfIds(kObjectIdsCount);
297
298   fake_registration_manager_.UpdateRegisteredIds(ids);
299   EXPECT_TRUE(
300       fake_registration_manager_.GetPendingRegistrationsForTest().empty());
301
302   // Lose some ids.
303   ObjectIdSet lost_ids = GetSequenceOfIds(3);
304   ObjectIdSet non_lost_ids = GetSequenceOfIdsStartingAt(3, kObjectIdsCount - 3);
305   LoseRegistrations(lost_ids);
306   ExpectPendingRegistrations(
307       lost_ids, 0.0,
308       fake_registration_manager_.GetPendingRegistrationsForTest());
309   EXPECT_EQ(non_lost_ids, fake_registration_manager_.GetRegisteredIdsForTest());
310   EXPECT_EQ(non_lost_ids, fake_invalidation_client_.GetRegisteredIdsForTest());
311
312   // Pretend we waited long enough to re-register.
313   fake_registration_manager_.FirePendingRegistrationsForTest();
314   EXPECT_EQ(ids, fake_registration_manager_.GetRegisteredIdsForTest());
315   EXPECT_EQ(ids, fake_invalidation_client_.GetRegisteredIdsForTest());
316 }
317
318 TEST_F(RegistrationManagerTest, MarkRegistrationLostBackoffLow) {
319   RunBackoffTest(-1.0);
320 }
321
322 TEST_F(RegistrationManagerTest, MarkRegistrationLostBackoffMid) {
323   RunBackoffTest(0.0);
324 }
325
326 TEST_F(RegistrationManagerTest, MarkRegistrationLostBackoffHigh) {
327   RunBackoffTest(+1.0);
328 }
329
330 // Exponential backoff on lost registrations should be reset to zero if
331 // UpdateRegisteredIds is called.
332 TEST_F(RegistrationManagerTest, MarkRegistrationLostBackoffReset) {
333   ObjectIdSet ids = GetSequenceOfIds(kObjectIdsCount);
334
335   fake_registration_manager_.UpdateRegisteredIds(ids);
336
337   // Lose some ids.
338   ObjectIdSet lost_ids = GetSequenceOfIds(2);
339   LoseRegistrations(lost_ids);
340   ExpectPendingRegistrations(
341       lost_ids, 0.0,
342       fake_registration_manager_.GetPendingRegistrationsForTest());
343
344   // Trigger another failure to start delaying.
345   fake_registration_manager_.FirePendingRegistrationsForTest();
346   LoseRegistrations(lost_ids);
347   double expected_delay =
348       RegistrationManager::kInitialRegistrationDelaySeconds;
349   ExpectPendingRegistrations(
350       lost_ids, expected_delay,
351       fake_registration_manager_.GetPendingRegistrationsForTest());
352
353   // Set ids again.
354   fake_registration_manager_.UpdateRegisteredIds(ids);
355   ExpectPendingRegistrations(
356       ObjectIdSet(),
357       0.0,
358       fake_registration_manager_.GetPendingRegistrationsForTest());
359 }
360
361 TEST_F(RegistrationManagerTest, MarkAllRegistrationsLost) {
362   ObjectIdSet ids = GetSequenceOfIds(kObjectIdsCount);
363
364   fake_registration_manager_.UpdateRegisteredIds(ids);
365
366   fake_invalidation_client_.LoseAllRegistrations();
367   fake_registration_manager_.MarkAllRegistrationsLost();
368
369   EXPECT_TRUE(fake_registration_manager_.GetRegisteredIdsForTest().empty());
370   EXPECT_TRUE(fake_invalidation_client_.GetRegisteredIdsForTest().empty());
371
372   ExpectPendingRegistrations(
373       ids, 0.0,
374       fake_registration_manager_.GetPendingRegistrationsForTest());
375
376   // Trigger another failure to start delaying.
377   fake_registration_manager_.FirePendingRegistrationsForTest();
378   fake_invalidation_client_.LoseAllRegistrations();
379   fake_registration_manager_.MarkAllRegistrationsLost();
380   double expected_delay =
381       RegistrationManager::kInitialRegistrationDelaySeconds;
382   ExpectPendingRegistrations(
383       ids, expected_delay,
384       fake_registration_manager_.GetPendingRegistrationsForTest());
385
386   // Pretend we waited long enough to re-register.
387   fake_registration_manager_.FirePendingRegistrationsForTest();
388   EXPECT_EQ(ids, fake_registration_manager_.GetRegisteredIdsForTest());
389   EXPECT_EQ(ids, fake_invalidation_client_.GetRegisteredIdsForTest());
390 }
391
392 // IDs that are disabled should not be re-registered by UpdateRegisteredIds or
393 // automatic re-registration if that registration is lost.
394 TEST_F(RegistrationManagerTest, DisableId) {
395   ObjectIdSet ids = GetSequenceOfIds(kObjectIdsCount);
396
397   fake_registration_manager_.UpdateRegisteredIds(ids);
398   EXPECT_TRUE(
399       fake_registration_manager_.GetPendingRegistrationsForTest().empty());
400
401   // Disable some ids.
402   ObjectIdSet disabled_ids = GetSequenceOfIds(3);
403   ObjectIdSet enabled_ids = GetSequenceOfIdsStartingAt(3, kObjectIdsCount - 3);
404   DisableIds(disabled_ids);
405   ExpectPendingRegistrations(
406       ObjectIdSet(),
407       0.0,
408       fake_registration_manager_.GetPendingRegistrationsForTest());
409   EXPECT_EQ(enabled_ids, fake_registration_manager_.GetRegisteredIdsForTest());
410   EXPECT_EQ(enabled_ids, fake_invalidation_client_.GetRegisteredIdsForTest());
411
412   fake_registration_manager_.UpdateRegisteredIds(ids);
413   EXPECT_EQ(enabled_ids, fake_registration_manager_.GetRegisteredIdsForTest());
414
415   fake_registration_manager_.MarkRegistrationLost(
416       *disabled_ids.begin());
417   ExpectPendingRegistrations(
418       ObjectIdSet(),
419       0.0,
420       fake_registration_manager_.GetPendingRegistrationsForTest());
421
422   fake_registration_manager_.MarkAllRegistrationsLost();
423   ExpectPendingRegistrations(
424       enabled_ids, 0.0,
425       fake_registration_manager_.GetPendingRegistrationsForTest());
426 }
427
428 }  // namespace
429 }  // namespace syncer