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